うるう秒の飛躍!


28

今日は26回目のうるう秒の機会を示すため、あなたの課題は、今日発生するものだけでなく、これまでに発生したGMTまたはUTCのすべてのうるう秒の日付と時刻を出力することです。

入力

入力はありません。

出力

1972-06-30 23:59:60
1972-12-31 23:59:60
1973-12-31 23:59:60
1974-12-31 23:59:60
1975-12-31 23:59:60
1976-12-31 23:59:60
1977-12-31 23:59:60
1978-12-31 23:59:60
1979-12-31 23:59:60
1981-06-30 23:59:60
1982-06-30 23:59:60
1983-06-30 23:59:60
1985-06-30 23:59:60
1987-12-31 23:59:60
1989-12-31 23:59:60
1990-12-31 23:59:60
1992-06-30 23:59:60
1993-06-30 23:59:60
1994-06-30 23:59:60
1995-12-31 23:59:60
1997-06-30 23:59:60
1998-12-31 23:59:60
2005-12-31 23:59:60
2008-12-31 23:59:60
2012-06-30 23:59:60
2015-06-30 23:59:60

ルール

うるう秒を許可する多くの組み込み関数があるとは思わないので、許可します。

標準の抜け穴は許可されていません。

最短のコードが優先されます。

日付形式には、ゼロが埋め込まれた月と4桁の年、および軍事時間と日付と時間を区切るスペースが必要です。UTC最後に置くことはオプションです。ダッシュまたはスラッシュの選択。

編集:うん、予想通り、これはエンコーディングの課題になりました。エンコードのみでうるう秒の問題を解決できた場合、...すべてのコードはより実用的です。実用的な用途でもっと楽しいチャレンジをするために、いくつかのアイデアが必要でしょうか?


出力はその正確な分布を持っている必要がありますか、それとも26個の日付がある限り任意の分布を持つことができますか?
イスマエルミゲル

2
@IsmaelMiguel彼らはこの順序である必要があります。
mbomb007

トピックから外れていますが、リストを見ると、なぜ昨世紀よりもうるう秒が少ないのか疑問に思っています。
ミスターリスター

@MrListerリンクされたウィキペディアの記事をご覧ください。地球の回転速度の変化と関係があると思います。
mbomb007

回答:


25

CJam、72 70 69 64バイト

26,"~g¼K&Béx¸¦­Ø"240bFbf{<1b2md\1972+'-@6X$4*-'-Z3$" 23:59:60"N}

CJamインタープリターでオンラインで試してください。

アイディア

我々は、各うるう秒を符号化することによって開始+ D - 2 *(1972 Y) Dはである1それは12月に発生した場合と0そうでありません。

エンコードされたすべてのうるう秒の配列は次のとおりです。

[0 1 3 5 7 9 11 13 15 18 20 22 26 31 35 37 40 42 44 47 50 53 67 73 80 86]

この配列をLと呼びましょう。

配列は昇順であるため、実際の数値の代わりに連続した差を保存できます。

[1 2 2 2 2 2 2 2 3 2 2 4 5 4 2 3 2 2 3 3 3 14 6 7 6]

この配列を基数15の数字として扱い、整数を取得します

19238985373462115979359619336

基数240(文字にキャスト)のどの数字が

~g¼K&Béx¸¦­Ø

コード

26,             e# Push I := [0 ... 25].
"~g¼K&Béx¸¦­Ø"   e# Push the string from above.
240bFb          e# Convert from base 250 to base 15 to push L.
f{              e# For each J in I:
                e#   Push L.
  <             e#   Replace L with L[:J].
  1b            e#   Push the sum S of the integers in L[:J].
  2md           e#   Push (S / 2) and (S % 2).
  \1972+        e#   Add 1972 to (S / 2).
  '-@           e#   Push '-' and rotate (S % 2) on top.
  6X$4*-        e#   Compute (6 - 4 * (S % 2)).
  '-Z           e#   Push '-' and 3.
  3$            e#   Push a copy of (S % 2).
  " 23:59:60"   e#   Push that string.
  N             e#   Push a linefeed.
}

28
ビルトインしたときの感覚は、ほぼ完全に問題を解決しますが、CJamの手動ソリューションは短くなります。
アレックスA.

9
@AlexA。Mathematicaにはいくつかのビルトインがあり、それらをMathematicaでより少ないバイト再実装できます。
マーティンエンダー

@MartinBüttner:残忍です。
アレックスA.

35

R、78 75バイト

ビルトインですか?まあ...

message(paste(as.Date(.leap.seconds)-1,"23:59:60\n"),"2015-06-30 23:59:60")

Rには、.leap.secondsシステムのローカル時間で指定された各うるう秒挿入の日付と時刻を含む自動変数があります。Rバージョン3.2.0の時点では、これには今日は含まれていないため、手動で追加しました。

Ungolfed +説明:

# Convert the datetime values to UTC dates. These will be a day past the
# expected output, so we can subtract 1 to get what we want.
dates <- as.Date(.leap.second) - 1

# Paste the UTC time and a newline onto the end of each date
datetimes <- paste(dates, "23:59:60\n")

# Print each time, including today, on its own line
message(datetimes, "2015-06-30 23:59:60")

オンラインで試すことができます


変数に「23:59:60」を割り当てることができる場合、いくつかの文字を保存することができます
チャールズではないチャールズ

1
@NotthatCharles:私はそれについて考えていましたが、文字列を結合するRの方法は、今日の日付と時刻の構築を短くするほど簡潔ではありません。入力をありがとう!
アレックスA.

24

HTML、594バイト

1972-06-30 23:59:60<br>1972-12-31 23:59:60<br>1973-12-31 23:59:60<br>1974-12-31 23:59:60<br>1975-12-31 23:59:60<br>1976-12-31 23:59:60<br>1977-12-31 23:59:60<br>1978-12-31 23:59:60<br>1979-12-31 23:59:60<br>1981-06-30 23:59:60<br>1982-06-30 23:59:60<br>1983-06-30 23:59:60<br>1985-06-30 23:59:60<br>1987-12-31 23:59:60<br>1989-12-31 23:59:60<br>1990-12-31 23:59:60<br>1992-06-30 23:59:60<br>1993-06-30 23:59:60<br>1994-06-30 23:59:60<br>1995-12-31 23:59:60<br>1997-06-30 23:59:60<br>1998-12-31 23:59:60<br>2005-12-31 23:59:60<br>2008-12-31 23:59:60<br>2012-06-30 23:59:60<br>2015-06-30 23:59:60

¯\ _(ツ)_ /¯


6
@ Vioz-この質問にはkolmogorov-complexityというタグが付けられているため、これは完全に合法的な答えです。しかし勝つ可能性は低いです...
デジタル外傷

10
@mlepageこれは「標準的な抜け穴」の1つです。
ジェイコブライレ

4
@Voitcusはファイルに保存し、ブラウザで開きます。それはだworkinghtmlコード
edc65

9
@ AntonyD'Andreaうん、それで何?チャレンジでは有効性は要求されませんcode golf
edc65

5
@anatolyg [kolmogorov-complexity]が面白くない
-vijrox

11

C、160の 146 141 140バイト

初めて投稿するとき、「標準的な抜け穴」が何であるかわからない。もちろんprintf警告があります。

160バイト:

元のアイデアは、1年に2ビットを使用してうるう秒をエンコードすることです。1つは6月、もう1つは12月です。エンコードは、内側のwhileループによって一度に1ビット消費されます。128ビット整数がない場合、外側のwhileループが必要です。残りはすべて簿記と数学です。:-)

int main(){long long X=0x2495288454AAAB,Y=1972,Z=1;while(Y<2000){while(X){if(X&1)printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z);Y+=Z^=1;X>>=1;}X=0x104082000;}}

141バイト:

推奨されるヒントを適用すると、146バイトになります。次に、外側のwhile条件(Y <2000からZのみ)を単純化して141バイトに減らす方法を見つけました。ツイートにとても近い!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,12-6*Z,31-Z):1,Y+=Z^=1,X/=2;X=4362608640;}}

140バイト:

日をマイナスにすることで、日付のダッシュを削除できることに気付きました。6月に先行ゼロがあるため、月でもこれを実行できません。しかし、少なくとも今はツイートに収まります!

main(Z){long long X=0x2495288454AAAB,Y=1972;while(Z){while(X)X&1?printf("%d-%02d%d 23:59:60\n",Y,12-6*Z,Z-31):1,Y+=Z^=1,X/=2;X=4362608640;}}

プリティバージョン:

main(Z) {
    long long X = 0x2495288454AAAB, Y = 1972;
    while (Z) {
        while (X)
            X&1 ? printf("%d-%02d%d 23:59:60\n", Y, 12-6*Z, Z-31) : 1,
            Y += Z ^= 1,
            X /= 2;
        X = 4362608640;
    }
}

ボーナスバージョン:

64ビット整数を別の整数にビットシフトすることで外側のループを削除しましたが、かなり長い「unsigned long long」のために150バイトです。「uint64」のようなものを使用できれば、138バイトになります。

main(Z) {
    unsigned long long Y = 1972, X = 0x2495288454AAAB, W = 8520720;
    while (X)
        X&1 ? printf("%d-%02d-%d 23:59:60\n", Y, 12-6*Z, 31-Z) : 1,
        Y += Z^= 1,
        X = X/2 | (W>>=1)<<63;
}

4
PPCGへようこそ。「標準的な抜け穴」はこの投稿を指しますが、一般的には「常識を使用し、ごまかすな」という意味です。:)
マーティンエンダー

1
forループを使用すると、いくつかのバイトを節約できると思います。ところで、int main()-> main()これは非常に役立つかもしれません。
Spikatrix

また:X>>=1と同じであるX/=26*(2-Z)と同じであり12-6*Z、そして4362608640より1バイト短いです0x104082000。のintmain()は不要です。変更main()するmain(Z)場合は、宣言を削除できますZ=1
squeamish ossifrage

本当に素敵な溶液-あなたが変更することができますabout-考える別の事if(X&1)printf(...);X&1?printf(...):1;1つのバイトを保存する
euanjt

そして、いうよりwhile(X){...}利用コンマあなたはbraces-を削除することができますのでwhile(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;、他の2つのバイトを保存する
euanjt

9

Python 3、91

Sp3000によるエンコードと文字列の書式設定を使用しますが、マジックナンバーではなくPython 3バイトオブジェクトに値を保存します。

for n in b'()+-/1357:<>BGKMPRTWZ]kqx~':print('%d-%02d-3%d 23:59:60'%(1952+n/2,n%2*6+6,n%2))

エンコードに必要なのは1バイトの256個の値のうち86個だけなので、印刷可能な文字の範囲を使用して見栄えを良くしています。


7

Brainfuck、806

++++++++[>++++++>+++++++>+++++++>++++++>++++++>++++++>+++++++>++++++>++++++>++++++>++++>++++++>++++++>+++++++>+++++++>+++++++>+++++++>+++++++>++++++>+<<<<<<<<<<<<<<<<<<<<-]>+>+>->++>--->>-->--->+++>>>++>+++>++>--->+>++>-->>++[<]>[.>]<[<]>>>>>>+>---->>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>+>-------->>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>>++>>+>---->>>+[<]>[.>]<[<]>>>>++[<]>[.>]<[<]>>>+>---------[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>>>>++>>->++++>>>-[<]>[.>]<[<]>>>>+>>+>---->>>+[<]>[.>]<[<]>+>--------->--------->---[<]>[.>]<[<]>>>>+++[<]>[.>]<[<]>>>+>------>>->++++>>>-[<]>[.>]<[<]>>>>+++[<]>[.>]

このオンラインインタープリターで実行できます。


6

Python 2、111 104バイト

n=0x6697f252225354422533333330;y=1972
while n:print'%d-%02d-3%d 23:59:60'%(y,n%2*6+6,n%2);y+=n/2%8;n/=16

ベースエンコーディングとより多くのベースエンコーディング。


5

GNU sed + date:112

一般的なLinuxディストリビューションにもうるう秒が組み込まれています。GNU sedと日付の使用:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /usr/share/zoneinfo/leap-seconds.list|date -f- +"%Y-%m-%d 23:59:60"

GNU sed + date:90

パスをカットして数人のキャラクターを救う:

sed -n 's/^\([0-9]\+\).*/1899-12-31 \1sec/p' /u*/s*/z*/leap*|date -f- +'%Y-%m-%d 23:59:60'

Toby Speightによって調整されたGNU sed + date:84

コメントで提案された深くゴルフされたバージョン:

sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*

うるう秒データの場所を教えてくれてありがとう。残念ながら、私のdate(GNU 8.23)はそれらを次の1分の1秒として表示します。60秒を理解するために何を使用していますか?
トビースパイト

GNU coreutilsを使用すると、76バイトになり、-rフラグでバイトを削りdates///e修飾子で置き換え%Y-%m-%d%Fin で置き換えdateます:TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight

私は何かを逃したことを知っていました。これを手動で指定する方法は、少なくとも他のほとんどのソリューションよりも悪くないようです。誰かがそれらの秒を適切にサポートする数値をいじるために何らかの日付ライブラリを思いつくかどうか見てみましょう。
イェンスエラ

私は1899-12-31 \1sec日付に使用し23:59:60、時間としてハードコーディングすることでそこに着きました:sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*
Toby Speight

3

JavaScript(ES6)125

``内の改行は重要でカウントされます。

テストするには、以下のスニペットを実行します(EcmaScript 6、Firefoxのみ)

alert([..."09:;=DEFIX[01234567?ABGJQS"].map((c,i)=>c.charCodeAt()+1924+(i>10?'-12-31':'-06-30')+' 23:59:60').sort().join`
`)


2

PHP、198バイト

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5] as$d){$h=(int)$d-ceil($d);echo date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,(int)$d+1972))."\n";}

残念ながら、\n日付関数に挿入できるかどうかはわかりません。その場合、これはのために3バイト少なくなります.""


両方(int)を削除して、空白を削除できます。デフォルトのタイムゾーンが設定されていない場合、日付はエラーをスローします@。187バイト:foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){$h=$d-ceil($d);echo@date("Y-m-d 23:59:60",mktime(0,0,0,-6*$h,31+$h,$d+1972))."\n";}
Octfx

2

8086マシンコード+ DOS、92バイト

コードのHexdump:

BE 3A 01 B1 57 D1 E0 75 03 AD EB F9 72 09 50 BA
47 01 B4 09 CD 21 58 BB 50 01 81 77 FC 01 04 80
37 01 80 3F 31 74 10 83 EB 05 4B FE 07 80 3F 3A
75 05 C6 07 30 EB F3 E2 CC C3 AA 2A 77 B5 6A DD
DF B6 BE FF 7D BF 31 39 37 32 2D 30 36 2D 33 30
20 32 33 3A 35 39 3A 36 30 0D 0A 24

実行するには、92バイトを com -file 32ビットWindowsまたはDOSBoxで実行します。

コードは、半年に1回、87ビットのビットマップを使用します。ビットは、MSBから始まる16のグループに配置されます。

ビットマップのデコード:

                 ; when the program starts, ax=0 (tested on DOSBox)
myloop:
    shl ax, 1    ; shift the MSB left into the carry flag
    jnz mywork   ; if some bits are left in the register, work normally
    lodsw        ; if all bits were shifted out, load the next 16 bits
    jmp myloop   ; and check the MSB again

コードの構造により、デコード中に一部のビットが失われるため、それらを繰り返す必要がありました。とにかく87ビットから96ビットを埋めなければならなかったので、この繰り返しはビットマップを膨張させません。

うるう秒を印刷する(または印刷しない)後、コードは出力メッセージのASCIIコードの操作を使用して、半年だけ日付を増やします。

ソースコード(でアセンブル可能 tasm):

    mov si, offset mydata
    mov cl, 57h ; number of iterations

myloop:
    shl ax, 1   ; shift the MSB left into the carry flag
    jnz mywork  ; if some bits are left in the register, work normally
    lodsw       ; if all bits were shifted out, load the next 16 bits
    jmp myloop  ; and check the MSB again
mywork:
    jc myinc_date ; shifted bit 1? - skip printing the message

    push ax
    mov dx, offset mymsg
    mov ah, 9
    int 21h     ; print the message
    pop ax

myinc_date:
    mov bx, offset mymsg + 9 ; pointer to the middle of the message
    xor word ptr [bx - 4], 401h ; change month 06<->12
    xor byte ptr [bx], 1 ; change day 30<->31
    cmp byte ptr [bx], '1'
    je myloop_end ; if 31 December, no need to increase the year
    sub bx, 5 ; pointer beyond the last digit of the year

myinc_year:
    dec bx
    inc byte ptr [bx] ; increase the digit
    cmp byte ptr [bx], '0' + 10
    jne myloop_end ; if the digit was less than 9, done
    mov byte ptr [bx], '0' ; set the digit to 0
    jmp myinc_year ; continue increasing other digits

myloop_end:
    loop myloop
    ret ; terminate the program

; In the following bitmap, the spaces before some LSBs
; show that the least significant 1-bit and all
; following 0-bits are lost during decoding.
mydata:
    dw 02aaah ; 00101010101010     10
    dw 0b577h ; 101101010111011    1
    dw 0dd6ah ; 11011101011010     10
    dw 0b6dfh ; 101101101101111    1
    dw 0ffbeh ; 11111111101111     10
    dw 0bf7dh ; 101111110111110    1

mymsg:
    db '1972-06-30 23:59:60',13,10,'$'

これをテストしたいと思いますが、16進数を貼り付けてバイナリファイルに保存できるエディターはどこにもありません。
ミスターリスター

@MrListerは、通常の16進エディタでそれを行う必要があります。
TheDoctor


1

Python 2、123 121 116 114 111

私はそれをかなり短くすることができましたが、どれくらい短くできるのか分かりません。を使用してみましたexecが、フォーマットのコストが高すぎます。

リンクされたウィキペディアのページからテーブルのベース16エンコードを使用しました。

編集:16進エンコーディングの使用は、ベース36よりも短くなっています(ゴルフの少ないバージョンを参照してください)。

ここで試してみてください

n=0x410208002495288454aaab
for i in range(88):
    if n%2:print"%d-%02d-3%d 23:59:60"%(1972+i/2,i%2*6+6,i%2)
    n/=2

少ないゴルフ:

s=bin(int('WELD24ZDGIMBWWLFM',36))[2:]
for i in range(44):
    t,s=int(s[0]),s[1:]
    if t:print"%d-06-30 23:59:60"%(i+1972)
    t,s=int(s[0]),s[1:]
    if t:print"%d-12-31 23:59:60"%(i+1972)

1

C、155 149 147バイト

文字列とランレングスエンコーディングを使用するCの別のアプローチを次に示します。私の他のCソリューションほど簡潔ではありませんが、改善できるかもしれません。

155バイト:

文字列を使用して月/日を保持します。

main(Y){Y=1972;char*M="06-3012-31",*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%.5s 23:59:60\n",Y++,M+b%2*5);Y+=(b>>4&7)-1;}}

149バイト:

月/日の文字列を削除します。

main(Y){Y=1972;char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

147バイト:

年の初期化を削除します。

main(Y){char*B="#@DGCDF7D3daTdS#!",b,c;while(b=*B++-33){c=b>>1&7;while(c--)printf("%d-%02d-%d 23:59:60\n",1971+Y++,6+b%2*6,30+b%2);Y+=(b>>4&7)-1;}}

144バイト:

実行前(後ではなく)スキップカウントを適用するようにバッファーを再エンコードした場合、外側のwhileループ内のステートメントを並べ替え、コンマ演算子を使用し、中かっこを削除して2バイトを節約できます。

(他のソリューションのように)日を負にすることで、もう1バイト節約できます。

かなり:

main(Y) {
    char *B = "#@DGCDF7D3daTdS#!", // buffer of bytes encoding runs
         b, // current byte
         c; // current count
    while (b = *B++-33) { // get byte
        c = b>>1&7; // get count
        while (c--) printf("%d-%02d-%d 23:59:60\n", 1971+Y++, 6+b%2*6, 30+b%2); // run
        Y += (b>>4&7)-1; // skip years
    }
}

説明:

実行はバイト単位でエンコードされます。各バイトには、6月か12月かを示す1ビット、長さカウント用の3ビット、スキップカウント用の3ビット、および未使用の上位ビット1つがあります。

スキップカウントは、実行後にスキップする年数です。1972年に2うるう秒を考慮して-1がオフセットされています。おそらく+1でオフセットされる可能性がありますが、現在はそうではありません。

したがって、バイトとは、次のバイトに移動する前に、「6月(または12)年のうるう秒を実行してからSKIP-1年をスキップする」という意味です。

バイトは、読みやすく、派手なエンコードを避けるために33オフセットされています。

これは、1998〜2005をカバーするのに十分なスキップビットがあるにもかかわらず、ASCIIの範囲外であるため、余分なゼロ長の実行があることを意味します。また、長さ1972-1979は長すぎるため、1979年は単独で表示されます。

バイトには十分なビットがあるため、これらの問題は最終的に修正可能です。


1

q / kdb +、95 94 93バイト

asc 1_" "0:([]raze("DEFGHIJKSUV[^eh";"DMNOQXYZ]lo"){("d"$"m"$-12*95-6h$x)-y}'1 185;`23:59:60)

説明

各年+ 1について、1905年以降の年をASCII文字としてエンコードします。例:

1972 -> 1973 -> 68 -> D

6h$x"D"戻り68ます。以来qの日付エポックがあり2000.01.01、我々は減算95と整数から日付への変換を行います"d"$"m"$-12*95-6h$x

上記の+ 1の理由は、実際の年の 12月31日または6月30日、つまり1または185日を取得するために、来年の初めから日数を引くためです。したがって、12月はうるう秒で、6 月はうるう秒で表されます。ペアリング-減算は、を介して行われます。ここでおよびは、それぞれ日と日数で減算される年です。"DEFGHIJKSUV[^eh""DMNOQXYZ]lo"(a;b){x-y}'(c;d)abcd

" "0:([]...)結果を準備して、正しい書式設定を提供しますが、列ヘッダーが生成されることに注意してください。1_そのヘッダーを削除し、最終的に適用ascして順序を正しくします。

編集: 're-base'を100の代わりに95年を差し引く(1文字節約)。

編集2:整数から日付への変換関数内のオペランドの位置を並べ替えます。


1

Python、204 201

e,g,h=0,1972,0
for i in range(1,27):e,g,h={2:1,9:2,10:1,12:2,15:1,16:2,17:1,20:2,21:1,22:7,23:3,24:4,25:3}.get(i,e),g+e,(h,1-h)[i in[2,10,14,17,20,21,22,25]];print`g`+("-06-30","-12-31")[h]+" 23:59:60"

repl.itで再生できます。

編集:徹底的にbeatられた!圧縮の答えは驚くほど短いです。


驚くべきことに、私のPHP anwserは同様のアルゴリズムを使用して短くなっています。Pythonはもっとコンパクトになるといつも思っていました。たぶんもう少しゴルフできるでしょうか?
ヴォイトカス

見てみましょう。私はかかわらず、最適なルートが圧縮であると思うし、他の人がすでにいることを行っている
はsudoのrm -rfはスラッシュ

0

PHP、164バイト

foreach([.5,1,2,3,4,5,6,7,8,9.5,10.5,11.5,13.5,16,18,19,20.5,21.5,22.5,24,25.5,27,34,37,40.5,43.5]as$d){echo(ceil($d)+1971).($d%2?'-12-31':'-06-30')." 23:59:60\n";}

これは、@ Voitcusのアイデアを少し修正したものです。


0

Python、221 217

def d(x):
 q=x%10
 if x%2==0:
  p,r=q/2,"06-30"
 else:
  p,r=(q-1)/2,"12-31"
 return"%d%d-%s 23:59:60"%(p+197,x/10,r)
for x in [20,21,31,41,51,61,71,81,91,12,22,32,52,73,93,5,24,34,44,55,74,85,57,87,28,58]:print(d(x))

いくつかの洞察

基本的に、d(x)単一の2桁の整数から3つの整数のベクトルを解凍します。d(x)はの逆関数(26うるう秒の日付時刻)として構築されc(v)、これは(1998,12,31)のような3倍を85のような数に変換する圧縮関数です。リストを導出するには[20 、21 ... 28,58]圧縮関数がドメイン全体で全単射であることを検証する別のアルゴリズムを設計しました。つまり、次のプログラムが重複しないようにし、その出力を上記のプログラムのリストとして使用しました。

dates = [(1972,06,30),
    (1972,12,31),
    (1973,12,31),
    (1974,12,31),
    (1975,12,31),
    (1976,12,31),
    (1977,12,31),
    (1978,12,31),
    (1979,12,31),
    (1981,06,30),
    (1982,06,30),
    (1983,06,30),
    (1985,06,30),
    (1987,12,31),
    (1989,12,31),
    (1990,12,31),
    (1992,06,30),
    (1993,06,30),
    (1994,06,30),
    (1995,12,31),
    (1997,06,30),
    (1998,12,31),
    (2005,12,31),
    (2008,12,31),
    (2012,06,30),
    (2015,06,30)]

def c(v):
    x = (v[0] % 10) * 10
    x += v[2] % 30
    x += 2 * (int(v[0] / 10) - 197)
    return x

for v in dates:
    print(c(v))

圧縮関数c(v)は、非常に単純なスキームを使用して全単射になるように設計されました。例として取り上げましょう(1998,12,31)。

  • 式(v [0]%10)* 10は、年の単位を選択します(例:1 9 9 8 > 8)を選択し、出力の10桁になります(現在はx = 80)。
  • うるう秒が発生するのは月と日の組み合わせが2つしかないため、06,30の場合と12,31の場合を区別するために日コンポーネントを使用することにしました。式v [2]%30は、日が30の場合は0、日が31の場合は1です。この例では、xに1を追加します(したがって、x = 81になります)。
  • 最後に、このパズルにはわずか50年しかかからないことに気付きました。したがって、最初の10年間(70年代)を0に、最後の10年間(2010年代)を4にマッピングすると、クールなことができます。より具体的には、0,1,2,3,4にマッピングする代わりに、0,2,4,6,8にマッピングする場合、xの単位にこの値を追加できます。これは、前のルールにより0または1.最後に、この最後のステップでも全単射を台無しにせず、06,30のケースの単位は0,2,4,6,8の1つであり、aの単位は12,31の場合は、1,3,5,7,9のいずれかです。したがって、全単射は明らかです。この例では、1998年は30年(70s-> 0、80s-> 1、90s-> 2)であるため、2 * 2 = 4を追加します。したがって、x = 85になります。

これが正しいことを確認するためにプログラムを作成d(x)し、の逆として定義しましたc(v)。この例では、c((1998,12,31))は85で、d(85)は正しく印刷され1998-12-31 23:59:60ます。


1
どこでも取り外しq=x%10て交換qx%10ます。短いです。ここであなたのプログラムに追加のゴルフのいくつかの役に立つ説明をします。Pythonページでゴルフヒントを表示することをお勧めします。
mbomb007

これはコードゴルフですなので、可能な限りコードの長さを短くするようにしてください。
mbomb007

-1

gzip、114バイト

Hexdump:

2

上記のバイトでファイルを作成します。

gunzipまたは別の解凍プログラムを使用して抽出し、「l」という名前の新しいファイルを取得します。このファイルには、目的の出力が含まれています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.