まだですか?


22

私はタイムトラベラーであり、時間の経過に夢中です。時計の針が12を過ぎたとき、カレンダーの次のページに移動したとき、または「Happy New Year!」と大声で叫んだときが特に気に入っています。

プログレスバーの形で、そのような最後の瞬間から次の瞬間までの距離を示すプログラムを書いてください。たとえば、時間が09:12であると伝えると、次のように出力されます。

09:00 ####---------------- 10:00

月が1982年5月であると言うと、次のように印刷されます。

1982-01 #######------------- 1983-01

私はタイムトラベラーだと言いましたか?0 ADの最初のミリ秒から9999 ADの最後のミリ秒まで移動するため、プログラムはその範囲の日付と時刻を処理する必要があります。

入力

  • 入力は次のいずれかの形式になります。

    • YYYY-MM-DDThh:mm:ss.sss
    • YYYY-MM-DDThh:mm:ss
    • YYYY-MM-DDThh:mm
    • YYYY-MM-DDThh
    • YYYY-MM-DD
    • YYYY-MM

    これらは、処理が必要な唯一の形式です。各部分には正確に表示される桁数があります。つまり、小数秒には末尾のゼロが含まれる場合があります(例:.120never .12)。T時間から日付を区切るリテラル文字「T」です。時間は24時間制です。

  • 月と日は1から始まります(これについては後で詳しく説明します)。

  • 無効で範囲外の入力を処理する必要はありません。

  • プログラマーの裁量により、入力には単一の末尾改行が含まれる場合があります。

プログレスバーの数学

プログラムは、指定された入力の最下位および2番目に重要な単位に関係しています。たとえば、入力が日レベルの精度(例:)である2016-12-14場合、進行状況バーは、入力された月の残りの日に対する経過した日数の割合を示します。

プログレスバーは、20単位(文字)を有するであろうと表される割合が最も近い増分に丸められます1 / 20。例えば、所与2016-12-14T12:28、プログレスバーが表示されるラウンド(28 / 60 ×20)9 = 20の単位を"充填します"。

1から始まる月と日

(たとえば)12月1日は012016-12-01ありますが、切り捨てられた単位はその日の0時の0分の0ミリ秒を意味するため、計算の目的では月の0日になります。換言すれば、2016-12-01ある0 / 31 Decemberまでの道のと2016-12-02ある1 / 31、及びオンになります。

同様に、2016-01その計算にそれは、1月の0日目の0ミリ秒0 / 12その手段、2016-12である11 / 12

はい、それは月と日が進行状況バーを完全に埋めることがないことを意味します。

異なる月の期間とうるう年

異なる月には異なる日数があり、出力にはこれを反映する必要があります(うるう年を含む)。2017年2月6日の進行状況バーは、2016年2月6日(または両方の年の1月6日)の進行状況バーとは異なります。

その他

  • タイムトラベラーは、予言的なグレゴリオ暦を使用します。TL; DR:1752年の日がなくなったような特別なケースはありません。入力には、西暦0年の日付が含まれます
  • 時間旅行者は夏時間を無視します。
  • プログラムはうるう秒を考慮する必要はありませんが、そうすることはできます。

出力

プログラム(または関数)は、水平方向の20文字のプログレスバーを印刷(または文字列として返す)する必要があります。このバーは、経過した時間を「塗りつぶし」、残りの時間を「開く」必要があります。左から右に「埋める」必要があります。

進行状況バーの左側には、カウントされる期間の開始を示すラベルがあり、右側には次の期間の開始を示すラベルが入力と同じ形式である必要があります(ただし、精度は2単位のみ表示されます)。この例の2016-12-14有効な出力は次のとおりです。

12-01 #########----------- 01-01

可能な各期間の有効なラベル形式は次のとおりです。

  • 月: YYYY-MM
  • 日々: MM-DD
  • 営業時間: DDThh
  • 議事録: hh:mm
  • 秒: mm:ss
  • ミリ秒: ss.sss

ラベルに追加のユニットを含めることはできず、省略することもできません。

出力ノート

  • 進行状況バーの「塗りつぶされた」単位は、#文字で表されます。「オープン」ユニットはで表され-ます。
  • 進行状況バーと各ラベルの間には、正確に1つのスペースが必要です。
  • 先頭または末尾のスペースおよび/または単一の末尾の改行が許可されます。

勝ち

これはです。バイト単位の最短コードが優先されます。標準ルールが適用されます。標準的な抜け穴は禁止されています。

Input                      Output
-----------------------    -------------------------------------
2016-12-12T12:17           12:00 ######-------------- 13:00
2016-12-12                 12-01 #######------------- 01-01
0000-01-01T00:00:00.000    00.000 -------------------- 01.000
0000-01-01T00:00           00:00 -------------------- 01:00
1899-12-31T23              31T00 ###################- 01T00
1899-12-31                 12-01 ###################- 01-01
1899-12                    1899-01 ##################-- 1900-01
1982-05-15T17:15           17:00 #####--------------- 18:00
1982-05-15T17              15T00 ##############------ 16T00
1982-05                    1982-01 #######------------- 1983-01
9999-12-31T23:59:59.999    59.000 #################### 00.000
9999-12                    9999-01 ##################-- 10000-01
2000-01-06                 01-01 ###----------------- 02-01
2000-02-06                 02-01 ###----------------- 03-01
2001-02-06                 02-01 ####---------------- 03-01
1742-09-10                 09-01 ######-------------- 10-01

4
うるう秒を心配する必要がありますか?
ライリー

@Riley良い質問です。いいえ
ヨルダン

2
標準化されたフォームはないので、夏時間は無視されると思いますか?
CAD97

3
@ CAD97良い質問です。あなたは正しいです。DSTはタイムトラベラーにとっては本当に複雑なことなので、無視します。
ヨルダン

「1899-12-31T23」の例は、「1982-05-15T17」の場合と同様に、提供された入力形式のリストに従って無効です。テストデータを確認してください。
ツェッペリン

回答:


4

JavaScript、282バイト

(x,v=x.split(/\D/g),l=v.length-2,[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),t=(v[l+1]-b)/d*20+.5|0,n=v[l],o=((n|0)+1)%a,r=l?('0'+o).slice(-2):o)=>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

すべてのテストに合格

(
x,
v=x.split(/\D/g),
l=v.length-2,
[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),
t=(v[l+1]-b)/d*20+.5|0,
n=v[l],
o=((n|0)+1)%a,
r=l?('0'+o).slice(-2):o
) =>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

テスト関数は、成功の場合は何も出力せず、失敗の場合は値を出力します。

function test(value,expected){
    if (f(value)!=expected)
    {
        console.log(value);
        console.log(f(value));
        console.log(expected);
     }
}

テストケース:

test('2016-12-12T12:17','12:00 ######-------------- 13:00')                 ;
test('2016-12-12','12-01 #######------------- 01-01')                       ;
test('0000-01-01T00:00:00.000','00.000 -------------------- 01.000')        ;
test('0000-01-01T00:00','00:00 -------------------- 01:00')                 ;
test('1899-12-31T23','31T00 ###################- 01T00')                    ;
test('1899-12-31','12-01 ###################- 01-01')                       ;
test('1899-12','1899-01 ##################-- 1900-01')                      ;
test('1982-05-15T17:15','17:00 #####--------------- 18:00')                 ;
test('1982-05-15T17','15T00 ##############------ 16T00')                    ;
test('1982-05','1982-01 #######------------- 1983-01')                      ;
test('9999-12-31T23:59:59.999','59.000 #################### 00.000')        ;
test('9999-12','9999-01 ##################-- 10000-01')                     ;
test('2000-01-06','01-01 ###----------------- 02-01')                       ;
test('2000-02-06','02-01 ###----------------- 03-01')                       ;
test('2001-02-06','02-01 ####---------------- 03-01')                       ;
test('1742-09-10','09-01 ######-------------- 10-01')                       ;

2
私はこのバージョンを上回るために新しい言語を学ばなければなりませんでした...それは非常に簡潔です!
rexroni 16

3

Pyth、213バイト

pythでの最初のコード!見よ:

+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

私のpythコードは、以前のpythonの回答に密接に基づいています。コメントなしのバージョンは次のとおりです。

"K is the input, as a list of numbers"
Kr:w"[-T:.]"d7
"Y=year"
=YhK
"k=month"
=k@K1
"H = a list of denominators"
=H[0 ^9T 12 ?q2k+28+q0%Y4-q0%Y400q0%Y100 +30%+k/k8 2 24 60 60 999)
"J is the second-to-last number of the input"
J@K_2
"b is the +1 starting point for months and days"
=b<lK4
"G is the number of hashtags in the statusbar"
=Gs+*20c-eKb@HlK.5
"N is the formatted string"
=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lK3 *2lK
+%hNJ+@N1+%eNb+d+*\#G+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

複数の値のテストは、コードループを作成し、最後に改行を追加することで簡単に実行できます。

Wp+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1+%eNb"\n"

それから私は走ったかcat testinput | pyth code.pyth > outputdiff output testoutput またはそれをオンラインで試す


2

Python 2、371バイト

この挑戦は驚くほど難しいものでした!出力文字列の書式設定ができるまで、300才未満になると思われました。

クールな部分は、私の答えが日付パッケージを使用しないことです。

import re
s=raw_input()
S=[int(i)for i in re.sub('[-T:.]',' ',s).split()]
l=len(S)
y,m=S[:2]
d=[0,20<<9,12,28+(y%4==0!=y%100)+(y%400==0)if m==2else 30+(m+m/8)%2,24,60,60,999]
a,n=S[-2:]
b=1-(1if l>3else 0)
h=int(20.*(n-b)/d[l]+.5)
x,y,z='- %.4d - %.2d - %.2d T %.2d : %.2d : %.2d . %.3d'.split()[l*2-3:l*2]
print x%a+y+z%b+' '+'#'*h+'-'*(20-h)+' '+x%((a+1)%d[l-1])+y+z%b
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.