10進数の時刻変換


15

前書き

時間は混乱しています。60秒から1分、60分から1時間、24時間から1日(そして厄介なam / pmは言うまでもありません!)。

今日、そのような愚かさの余地はないので、私たちは唯一の賢明な代替案を採用することに決めました:小数日!つまり、各日は1単位とみなされ、それより短いものはその日の小数部として書き込まれます。たとえば、「12:00:00」は「0.5」と記述され、「01:23:45」は「0.058159」と記述されます。

新しいシステムに慣れるには時間がかかるため、双方向で変換できるプログラムを作成する必要があります。

チャレンジ

「hh:mm:ss」のISO-8601形式で現代の時刻を指定すると、選択した言語でプログラムを記述し、同等の10進小数単位を返します。同様に、小数を指定すると、プログラムは最初に指定された最新の形式で時刻を返す必要があります。

次の前提を立てることができます。

  • 現代の時間の入力と出力は、「00:00:00」から「24:00:00」の範囲で指定できます
  • 10進数の時間の入力と出力の範囲は「0」から「1」であり、最大5桁の小数点以下桁数(「0.12345」など)を受け入れ/出力できる必要があります。より高い精度が許容されます
  • プログラムは、入力に基づいて実行する変換方向を認識できる必要があります。
  • 時間関連の関数/ライブラリを使用できません

勝者は、基準を達成する最短のコードによって決定されます。それらは、少なくとも10進数の7日単位で、または十分な提出があった場合に/選択されます。

例として使用するJavaScriptコードの(意図的に)不十分な記述を以下に示します。

function decimalDay(hms) {
    var x, h, m, s;
    if (typeof hms === 'string' && hms.indexOf(':') > -1) {
        x = hms.split(':');
        return (x[0] * 3600 + x[1] * 60 + x[2] * 1) / 86400;
    }
    h = Math.floor(hms * 24) % 24;
    m = Math.floor(hms * 1440) % 60;
    s = Math.floor(hms * 86400) % 60;
    return (h > 9 ? '' : '0') + h + ':' + (m > 9 ? '' : '0') + m + ':' + (s > 9 ? '' : '0') + s;
}
decimalDay('02:57:46'); // 0.12344907407407407
decimalDay('23:42:12'); // 0.9876388888888888
decimalDay(0.5); // 12:00:00
decimalDay(0.05816); // 01:23:45

うーん... 60はほぼ 64 です。1 分に64秒、1時間に64分(1日に16時間または32時間)があった場合、どのような時間になるのでしょうか。

1
うるう秒を処理する必要がありますか?23:59:60は86401秒目の終わりから1秒ですか?
スパー

1
@Sparrうるう秒について心配する必要はありません。これは未来であり、地球の自転の相対速度にも結び付けながら、絶対値と見なされるのは1秒の間ばかげていると判断した;)
Mwr247

1
@MichaelTプログラマーの夢の世界= P
Mwr247

1
@ Mwr247うん。DNS TTL nnは、2 ^ n秒のフィールドがあります(持っていましたか?)。したがって、値「6」のTTLは約1分でした。「12」の値のTTLは約1時間でした。「15」は約8時間などでした。1バイトでタイムアウトを定義し、短時間または長時間の十分な制御を可能にしました。

回答:


6

CJam、58 56 42バイト

これは長すぎて、多くのゴルフができると確信しています。しかし、ここから先に進みます。

86400q':/:d_,({60bd\/}{~*i60b{s2Ue[}%':*}?

こちらからオンラインでお試しください


ほら、同様のアイデアがあります
aditsu

@aditsu Oh !. 私のものを更新する前にあなたのものを見なかったし、それから通勤に急いでいた。
オプティマイザー

あなたは何を知っている..私のコードを自由に使用してください:86400q':/:d_,({60bd\/}{~*mo60bAfmd2/':*}?、私は私の答えを削除しています。のmoは、0.058159が01:23:45に変換されるようにするためです
15

3

Python 2、159 150 141 + 2 = 143バイト

簡単な解決策は、おそらくはるかに短くすることができます。それで動作します。

入力を「s」で囲む必要があることを説明するために2バイトを追加しました。また、Sp3000はeval()がオクタルを解釈する問題を指摘し、フォーマットを短縮し、map()を使用して1つの印刷を削除する方法を示しました。

n=input();i=float;d=864e2
if':'in n:a,b,c=map(i,n.split(':'));o=a/24+b/1440+c/d
else:n=i(n);o=(':%02d'*3%(n*24,n*1440%60,n*d%60))[1:]
print o

こちらでideoneをご覧ください。


2

Javascript(ES6)、116 110バイト

f=x=>x[0]?([h,m,s]=x.split(':'),+s+m*60+h*3600)/86400:[24,60,60].map(y=>('0'+~~(x*=y)%60).slice(-2)).join(':')


// for snippet demo:
i=prompt();
i=i==+i?+i:i; // convert decimal string to number type
alert(f(i))

コメント:

f=x=>
    x[0] ? // if x is a string (has a defined property at '0')
        ([h, m, s] = x.split(':'), // split into hours, minutes, seconds
        +s + m*60 + h*3600) // calculate number of seconds
        / 86400 // divide by seconds in a day
    : // else
        [24, 60, 60]. // array of hours, minutes, seconds
        map(y=> // map each with function
            ('0' + // prepend with string zero
                ~~(x *= y) // multiply x by y and floor it
                % 60 // get remainder
            ).slice(-2) // get last 2 digits
        ).join(':') // join resulting array with colons

24:00:00を生成します1が、逆は真ではありません
-rink.attendant.6

@ rink.attendant.6修正
-nderscore

2

Python 3:143バイト

i,k,l,m=input(),60,86400,float
if'.'in i:i=m(i)*l;m=(3*':%02d'%(i/k/k,i/k%k,i%k))[1:]
else:a,b,c=map(m,i.split(':'));m=(a*k*k+b*k+c)/l
print(m)

Python 2ソリューションと同じバイトカウントですが、数学に対して異なるアプローチを採用したようです。


2

ジュリア、152 143 142バイト

よく、ゴルフのために、彼らの言うように、アプローチを「ジュリアン」よりも少なくするように更新しました。より良い(簡潔ではないが)アプローチについては、改訂履歴を参照してください。

x->(t=[3600,60,1];d=86400;typeof(x)<:String?dot(int(split(x,":")),t)/d:(x*=d;o="";for i=t q,x=x÷i,x%i;o*=lpad(int(q),2,0)*":"end;o[1:end-1]))

これにより、文字列または64ビット浮動小数点数を受け入れ、それぞれ64ビット浮動小数点数または文字列を返す名前のない関数が作成されます。それを呼び出すには、名前を付けます、例えばf=x->...ます。

Ungolfed +説明:

function f(x)
    # Construct a vector of the number of seconds in an hour,
    # minute, and second
    t = [3600, 60, 1]

    # Store the number of seconds in 24 hours
    d = 86400

    # Does the type of x inherit from the type String?
    if typeof(x) <: String
        # Compute the total number of observed seconds as the
        # dot product of the time split into a vector with the
        # number of seconds in an hour, minute, and second
        s = dot(int(split(x, ":")), t)

        # Get the proportion of the day by dividing this by
        # the number of seconds in 24 hours
        s / d
    else
        # Convert x to the number of observed seconds
        x *= d

        # Initialize an output string
        o = ""

        # Loop over the number of seconds in each time unit
        for i in t
            # Set q to be the quotient and x to be the remainder
            # from x divided by i
            q, x = divrem(x, i)

            # Append q to o, padded with zeroes as necessary
            o *= lpad(int(q), 2, 0) * ":"
        end

        # o has a trailing :, so return everything up to that
        o[1:end-1]
    end
end

例:

julia> f("23:42:12")
0.9876388888888888

julia> f(0.9876388888888888)
"23:42:12"

julia> f(f("23:42:12"))
"23:42:12"

2

C、137バイト

完全なCプログラム。stdinで入力を受け取り、stdoutで出力します。

main(c){float a,b;scanf("%f:%f:%d",&a,&b,&c)<3?c=a*86400,printf("%02d:%02d:%02d",c/3600,c/60%60,c%60):printf("%f",a/24+b/1440+c/86400.);}

非ゴルフとコメント:

int main() {
    // b is float to save a . on 1440
    float a,b;
    // c is int to implicitly cast floats
    int c;

    // If the input is hh:mm:ss it gets splitted into a, b, c
    // Three arguments are filled, so ret = 3
    // If the input is a float, it gets stored in a
    // scanf stops at the first semicolon and only fills a, so ret = 1
    int ret = scanf("%f:%f:%d", &a, &b, &c);

    if(ret < 3) {
        // Got a float, convert to time
        // c = number of seconds from 00:00:00
        c = a * 86400;
        printf("%02d:%02d:%02d", c/3600, c/60 % 60, c%60);
    }
    else {
        // a = hh, b = mm, c = ss
        // In one day there are:
        // 24 hours
        // 1440 minutes
        // 86400 seconds
        printf("%f", a/24 + b/1440 + c/86400.);
    }
}

scanfと%fの非常に明確な使用
一部のユーザー

ど!「賢い」という意味でした。
一部のユーザー

2

J、85バイト

結果:

T '12:00:00 '
0.5

T 0.5
12 0 0

T '12:34:56 '
0.524259

T 0.524259
12 34 56

T=:3 :'a=.86400 if.1=#y do.>.(24 60 60#:y*a)else.a%~+/3600 60 1*".y#~#:192 24 3 end.'

合計85


サイトへようこそ!コードがコードとして表示されるように、投稿を編集しました。オンラインリンクに関しては、私が知っている最高のものはTIOです。リンクを提供しますが、私はJに詳しくないので、それを呼び出す正しい方法がわかりません。また、最初と最後の行を含めると、これは91バイトと思われます。これは正しいです?
DJMcMayhem

ご協力いただきありがとうございます!プログラム[a = ... to end。]は77です。タイトルは10です。ターミネータは1なので、88になります。私はそれに取り組みます:o)
リチャードドノヴァン

85バイトのワンライナーになりました!
リチャードドノヴァン

1

Javascriptを、194の 192 190 188バイト

function(z){if(isNaN(z)){x=z.split(':');return x[0]/24+x[1]/1440+x[2]/86400}h=(z*24)|0;h%=24;m=(z*1440)|0;m%=60;s=(z*86400)|0;s%=60;return""+(h>9?'':0)+h+':'+(m>9?'':0)+m+':'+(s>9?'':0)+s}

1

JavaScriptのES6、98の 130バイト

s=>s==+s?'246060'.replace(/../g,l=>':'+('0'+~~(s*=+l)%60).slice(-2)).slice(1):s.split`:`.reduce((a,b)=>+b+(+a)*60)*1/864e2;f(0.5);

残念ながら、この課題では時間関連の関数(「Date」や「​​toTimeString」など)は許可されていません。それ以外の場合は、より簡潔な方法です=)
Mwr247

@ Mwr247オハイオ州はそれを見なかった、私はそれを修正します
Downgoat

1

C、156 152バイト

Cにとっては簡単になると思いましたが、それでもかなり大きなものになりました。:(

n,m=60;d(char*s){strchr(s,58)?printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);}

テストプログラム:

#include <stdio.h>
#include <stdlib.h>

int n,m=60;
d(char*s)
{
    strchr(s,':') ? 
        printf("%f",(float)(atoi(s)*m*m+atoi(s+3)*m+atoi(s+6))/m/m/24):
        printf("%02d:%02d:%02d",(n=atof(s)*m*m*24)/m/m,n/m%m,n%m);
}

int main()
{
    d("01:23:45");
    printf("\n");
    d("02:57:46");
    printf("\n");
    d("23:42:12");
    printf("\n");
    d("12:00:00");
    printf("\n");
    d("0.5");
    printf("\n");
    d("0.05816");
    printf("\n");
    d("0");
    printf("\n");
    d("1");
    printf("\n");
    return 0;
}

出力:

0.058160
0.123449
0.987639
0.500000
12:00:00
01:23:45
00:00:00
24:00:00

1

PHP、70 69バイト

<?=strpos($t=$argv[1],58)?strtotime($t)/86400:date("H:i:s",$t*86400);

コマンドライン引数から入力を受け取り、STDOUTに出力します:

入力にコロンが含まれる場合は、Unix時間に変換して(1日あたりの秒数)で除算し、
それ以外の場合は(1日あたりの秒数)で数値を乗算し、unix時間をにフォーマットしhh:mm:ssます。


1

Perlの、109 108 101 + 6(-plaF:フラグ)= 107バイト

$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60

を使用して:

perl -plaF: -e '$_=$#F?($F[0]*60+$F[1]+$F[2]/60)/1440:sprintf"%02d:%02d:%02d",$h=$_*24,$m=($h-int$h)*60,($m-int$m)*60' <<< 01:23:45

Ideoneでお試しください。


0

Excel、178バイト

=IF(LEFT(A1,2)="0.",TEXT(FLOOR(A1*24,1),"00")&":"&TEXT(MOD(FLOOR(A1*1440,1),60),"00")&":"&TEXT(MOD(FLOOR(A1*86400,1),60),"00"),((LEFT(A1,2)*60+MID(A1,4,2))*60+RIGHT(A1,2))/86400)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.