Lompatan demi Lompatan Detik!


28

Karena hari ini menandai kesempatan lompatan ke-26 yang pernah terjadi, tantangan Anda adalah mengeluarkan tanggal dan waktu setiap detik kabisat dalam GMT atau UTC yang telah terjadi sejauh ini, serta yang terjadi hari ini.

Memasukkan

Tidak ada input.

Keluaran

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

Aturan

Karena saya ragu ada banyak built-in yang memungkinkan lompatan-detik, saya akan mengizinkannya.

Celah standar tidak diijinkan.

Kode terpendek menang.

Format tanggal harus memiliki bulan nol-empuk dan tahun 4-digit, serta waktu militer dan ruang yang memisahkan waktu dari tanggal. Menempatkan UTCpada bagian akhir adalah opsional. Pilihan tanda hubung atau garis miring.

EDIT: Ya seperti yang diperkirakan, ini menjadi tantangan penyandian. Jika hanya penyandian yang dapat memperbaiki masalah lompatan kedua, ... maka semua kode kita akan jauh lebih praktis. Mungkin kita membutuhkan beberapa ide untuk tantangan yang lebih menyenangkan dengan penggunaan praktis?


Apakah output harus memiliki distribusi yang tepat, atau dapat memiliki distribusi selama 26 tanggal ada?
Ismael Miguel

2
@ IsmaelMiguel Mereka harus dalam urutan ini.
mbomb007

Di luar topik, tetapi melihat daftar, saya bertanya-tanya mengapa kita membutuhkan lebih sedikit detik kabisat daripada yang kita lakukan di abad sebelumnya.
Tuan Lister

@ Mr.Lister Lihat artikel Wikipedia yang ditautkan Saya pikir itu ada hubungannya dengan kecepatan rotasi Bumi yang berubah.
mbomb007

Jawaban:


25

CJam, 72 70 69 64 byte

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

Cobalah online di juru bahasa CJam .

Ide

Kita mulai dengan pengkodean setiap lompatan kedua sebagai 2 * (Y - 1972) + D , di mana D adalah 1 jika terjadi pada bulan Desember dan 0 sebaliknya.

Array dari semua detik kodekan adalah:

[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]

Mari kita sebut array ini L .

Karena array dalam urutan menaik, kita dapat menyimpan perbedaan berurutan daripada angka yang sebenarnya:

[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]

Memperlakukan array ini sebagai digit nomor 15 basis, kita mendapatkan integer

19238985373462115979359619336

yang angka dalam basis 240 (dilemparkan ke karakter) adalah

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

Kode

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
Perasaan ketika Anda memiliki built in yang hampir seluruhnya menyelesaikan masalah dan solusi manual di CJam lebih pendek.
Alex A.

9
@AlexA. Ada beberapa built-in di Mathematica yang dapat saya implementasikan dalam lebih sedikit byte di Mathematica .
Martin Ender

@ MartinBüttner: Brutal.
Alex A.

35

R, 78 75 byte

Built-in, katamu? Baik...

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

R memiliki variabel otomatis .leap.secondsyang berisi tanggal dan waktu setiap penyisipan lompatan kedua, yang diberikan dalam waktu lokal sistem. Pada R versi 3.2.0, ini tidak termasuk hari ini, jadi saya telah menambahkannya secara manual.

Penjelasan + tidak dikumpulkan:

# 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")

Anda dapat mencobanya secara online !


jika Anda dapat menetapkan "23:59:60" ke variabel, Anda dapat menyimpan beberapa karakter
Bukan berarti Charles

1
@NotthatCharles: Saya sudah memikirkan hal itu, tetapi metode R dalam menggabungkan string tidak cukup ringkas untuk membuat tanggal dan waktu pembuatan hari ini lebih pendek. Terima kasih atas masukannya!
Alex A.

24

HTML, 594 byte

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- Pertanyaan ini ditandai dengan kompleksitas-kolmogorov dan jadi ini adalah jawaban yang sangat legal. Tapi sepertinya tidak akan menang ...
Trauma Digital

10
@mlepage Itu salah satu "celah standar".
Jacob Raihle

4
@Voitcus simpan dalam file, buka di browser. Ini adalah workingkode html
edc65

9
@ AntonyD'Andrea Ya, jadi apa? Vailiditas tidak diminta dalam code golftantangan.
edc65

5
@anatolyg KAMU tidak menyenangkan untuk [kolmogorov-kompleksitas]
vijrox

11

C, 160 146 141 140 byte

Pertama kali memposting, tidak yakin apa "celah standar" itu. Saya punya peringatan printf tentu saja.

160 byte:

Gagasan asli adalah untuk menyandikan detik kabisat menggunakan dua bit per tahun: satu untuk Juni dan satu untuk Desember. Pengkodean dikonsumsi satu per satu oleh loop sementara dalam. Tanpa integer 128-bit, loop sementara luar diperlukan. Sisanya adalah pembukuan dan matematika. :-)

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 byte:

Menerapkan tip yang disarankan akan turun hingga 146 byte. Kemudian saya menemukan cara untuk menyederhanakan kondisi outer sementara (dari Y <2000 menjadi hanya Z), membawanya ke 141 byte. Begitu dekat dengan tweet!

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 byte:

Saya perhatikan tanda hubung pada tanggal tersebut dapat dihilangkan dengan membuat hari menjadi negatif. Tidak dapat melakukannya dengan bulan juga karena memimpin nol pada bulan Juni. Tapi setidaknya itu pas di tweet sekarang!

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;}}

Versi cantik:

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;
    }
}

Versi bonus:

Saya menghilangkan loop luar dengan menggeser bit satu integer 64-bit ke yang lain, tapi itu 150 byte, karena agak lama "unsigned long long"; jika saya bisa menggunakan sesuatu seperti "uint64" itu akan menjadi 138 byte.

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
Selamat datang di PPCG. "Celah standar" merujuk ke pos ini , tetapi umumnya ini berarti "menggunakan akal sehat dan jangan curang". :)
Martin Ender

1
Saya pikir menggunakan forloop akan menghemat beberapa byte. BTW, int main()-> main(). Anda mungkin menemukan ini sangat membantu.
Spikatrix

Juga: X>>=1sama dengan X/=2, 6*(2-Z)sama dengan 12-6*Z, dan 4362608640satu byte lebih pendek dari 0x104082000. The intdi depan main()tidak diperlukan, dan jika Anda mengubah main()ke main(Z)maka Anda dapat menghapus deklarasi Z=1.
squeamish ossifrage

Solusi yang sangat bagus - hal lain untuk dipikirkan - Anda dapat mengubah if(X&1)printf(...);dengan X&1?printf(...):1;yang menghemat 1 byte
euanjt

dan alih-alih while(X){...}menggunakan koma sehingga Anda dapat menghapus kawat gigi- while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;menghemat 2 byte lainnya
euanjt

9

Python 3, 91

Menggunakan penyandian dan pemformatan string oleh Sp3000 , tetapi menyimpan nilai-nilai dalam objek Python 3 byte daripada angka ajaib.

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

Pengkodean hanya membutuhkan 86 dari 256 nilai yang mungkin dari byte, sehingga berbagai karakter yang dapat dicetak digunakan untuk membuatnya terlihat lebih bagus.


7

Brainfuck, 806

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

Anda dapat menjalankannya pada juru bahasa online ini.


6

Python 2, 111 104 byte

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

Encoding basis dan lebih banyak encoding basis.


5

GNU sed + date: 112

Distribusi Linux pada umumnya memiliki lompatan detik bawaan. Menggunakan sed dan tanggal GNU:

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

Menyimpan beberapa karakter dengan memotong jalan:

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

GNU sed + date disetel oleh Toby Speight: 84

Versi golf yang diusulkan dalam komentar:

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

Terima kasih telah mengajari saya di mana menemukan data detik kabisat. Sayangnya, date(GNU 8.23) saya menampilkannya sebagai detik pertama pada menit berikutnya. Apa yang Anda gunakan yang memahami 60 menit?
Toby Speight

Dengan GNU coreutils, saya mendapatkannya hingga 76, mencukur byte dengan -rbendera, menggantikan datedengan s///epengubah, dan mengganti %Y-%m-%ddengan %Fdi date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight

Saya tahu saya melewatkan sesuatu. Tampaknya tidak ada cara untuk menentukan ini secara manual, setidaknya tidak lebih buruk daripada kebanyakan solusi lain. Mari kita lihat apakah ada yang datang dengan beberapa perpustakaan tanggal untuk mengutak-atik angka dengan benar mendukung detik itu.
Jens Erat

Saya sampai di sana dengan menggunakan 1899-12-31 \1sectanggal, dan hardcoding 23:59:60sebagai waktu: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

Baris baru di dalam `` signifikan dan dihitung.

Untuk menguji, jalankan cuplikan di bawah ini (menjadi EcmaScript 6, khusus 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 byte

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";}

Sayangnya, saya tidak tahu apakah saya bisa memasukkan \nfungsi tanggal. Jika demikian, ini kurang dari 3 byte karena ."".


Anda dapat menghapus keduanya (int)dan menghapus spasi putih. Tanggal melempar kesalahan, jika zona waktu default tidak disetel, diamkan dengan @. 187 byte: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 kode mesin + DOS, 92 byte

Hexdump kode:

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

Untuk menjalankan, tulis 92 byte ke com-file dan jalankan di bawah 32-bit Windows atau DOSBox.

Kode ini menggunakan bitmap dengan 87 bit, satu per setengah tahun. Bit disusun dalam kelompok 16, mulai dari MSB.

Decoding bitmap:

                 ; 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

Karena struktur kode, beberapa bit hilang selama decoding, jadi saya harus mengulanginya. Pengulangan ini tidak mengasapi bitmap karena saya harus memasukkan 87 bit menjadi 96 bit.

Setelah mencetak (atau tidak mencetak) lompatan kedua, kode meningkatkan tanggal setengah tahun, menggunakan manipulasi pada kode ASCII dari pesan keluaran.

Kode sumber (dapat dirakit dengan 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,'$'

Saya ingin menguji ini, tetapi sepertinya saya tidak dapat menemukan editor tunggal di mana saja yang memungkinkan Anda untuk menempelkan hex dan menyimpannya ke file biner.
Tn. Lister

@ Mr.Lister editor hex normal mana pun harus melakukannya untuk Anda.
TheDoctor

1

Pyth - 88 84 byte

Konversi ke char untuk mengompresi data dan menyimpan data 06-30versus 12-31sebagai angka biner.

jbm++-2047ed?"-06-30"hd"-12-31"" 23:59:60"C,j33678243 2CM"KKJIHGFEDBA@><:9765421*'# 

(ada ruang di sana di akhir)

Coba di sini online .


1

Python 2, 123 121 116 114 111

Saya sudah berhasil membuatnya cukup pendek, tapi saya tidak yakin seberapa pendek itu bisa didapat. Saya mencoba menggunakan exec, tetapi pemformatan menjadi terlalu mahal.

Saya menggunakan basis 16 pengkodean tabel dari halaman Wikipedia yang ditautkan.

Sunting: Menggunakan hex encoding lebih pendek dari base 36 (lihat versi yang kurang golf).

Coba di sini

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

Kurang bermain golf:

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 byte

Berikut pendekatan lain dalam C, menggunakan string dan menjalankan encoding panjang. Tidak sesingkat solusi C saya yang lain, tapi mungkin itu bisa diperbaiki?

155 byte:

Menggunakan string untuk menahan bulan / hari.

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 byte:

Menghilangkan string bulan / hari.

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 byte:

Menghilangkan inisialisasi tahun.

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 byte:

Jika saya me-encode ulang buffer untuk membuat jumlah lompatan berlaku sebelum (bukan setelah) jalankan, maka saya bisa menyusun ulang pernyataan di loop sementara luar, menggunakan operator koma, dan menghilangkan kawat gigi, menghemat 2 byte.

Saya dapat menyimpan byte lain dengan membuat hari menjadi negatif (seperti pada solusi saya yang lain).

Cantik:

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
    }
}

Penjelasan:

Proses dikodekan dalam byte. Setiap byte memiliki satu bit untuk mengatakan apakah itu Juni atau Desember, 3 bit untuk jumlah panjang, 3 bit untuk jumlah lewati, dan 1 bit tinggi yang tidak digunakan.

Hitungan loncatan adalah jumlah tahun untuk dilewati setelah berlari; itu diimbangi dengan -1 untuk memungkinkan dua detik kabisat pada tahun 1972. Panjangnya adalah berapa tahun dalam menjalankan; mungkin dapat diimbangi dengan +1 tetapi saat ini tidak.

Jadi satu byte berarti: "Lakukan PANJANG tahun JUNI (atau DESEMBER) tahun kabisat detik, kemudian lewati SKIP-1 tahun" sebelum pindah ke byte berikutnya.

Bytes diimbangi oleh 33 untuk membuatnya dapat dibaca dan menghindari pengkodean mewah.

Ini berarti meskipun kami memiliki cukup lewati bit untuk mencakup 1998-2005, kami berada di luar kisaran ASCII, jadi kami memiliki jangka panjang nol ekstra. Juga, 1979 muncul dengan sendirinya karena panjangnya 1972-1979 terlalu panjang.

Ada cukup banyak bit dalam byte, sehingga masalah-masalah itu akhirnya bisa diperbaiki.


1

q / kdb +, 95 94 93 byte

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

Penjelasan

Untuk setiap tahun +1 , penyandian selama bertahun-tahun sejak 1905 sebagai karakter ASCII, misalnya:

1972 -> 1973 -> 68 -> D

6h$xbergantian "D"kembali ke 68. Karena qzaman tanggal adalah 2000.01.01, kami mengurangi 95dan melakukan konversi bilangan bulat ke tanggal "d"$"m"$-12*95-6h$x.

Alasan kami memberi +1 di atas adalah untuk mengurangi jumlah hari dari awal tahun depan untuk mendapatkan tahun sebenarnya 31 Desember atau 30 Juni, yaitu 1 atau 185 hari. Oleh karena itu, "DEFGHIJKSUV[^eh"mewakili tahun-tahun dengan lompatan kedua pada bulan Desember, dan "DMNOQXYZ]lo"bagi mereka pada bulan Juni. Pengurangan-pasangan dilakukan melalui (a;b){x-y}'(c;d), di mana adan badalah tahun-tahun yang akan dikurangkan oleh cdan djumlah hari masing-masing.

" "0:([]...)menyiapkan hasilnya untuk memberi kita format yang benar, dengan peringatan kecil bahwa header kolom akan dihasilkan. 1_menjatuhkan tajuk itu dan akhirnya berlaku ascuntuk mendapatkan pemesanan yang benar.

sunting : 're-base' untuk mengurangi 95 tahun alih-alih 100 (menyimpan 1 karakter).

edit 2 : memesan ulang posisi operan di dalam fungsi konversi integer-to-date.


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"

Anda dapat bermain dengan pada repl.it .

Sunting: Dipukul habis! Jawaban kompresi sangat pendek.


Anehnya, PHP anwser saya lebih pendek, menggunakan algoritma yang sama. Saya selalu berharap Python lebih kompak. Mungkin Anda bisa sedikit lebih golf?
Voitcus

Aku akan melihatnya. Saya pikir rute terbaik adalah kompresi, dan yang lain sudah melakukan itu
sudo rm -rf slash

0

PHP, 164 byte

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";}

Ini hanya beberapa modifikasi pada ide @ 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))

Beberapa Wawasan

Pada dasarnya, d(x)dekompresi vektor 3 bilangan bulat dari bilangan bulat 2 digit. d(x)dikonstruksikan sebagai fungsi terbalik (lebih dari 26 detik detik kabisat) dari c(v), yang pada gilirannya adalah fungsi kompresi yang mengubah 3-uple seperti (1998,12,31) menjadi angka seperti 85. Untuk memperoleh daftar [20 , 21 ... 28,58] Saya merancang algoritma lain untuk memverifikasi bahwa fungsi kompresi bijective atas domain. Yaitu, saya memastikan bahwa program berikut ini tidak menghasilkan duplikat, dan saya menggunakan hasilnya sebagai daftar program di atas.

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))

Fungsi kompresi c(v)dirancang menjadi bijective dengan menggunakan skema yang sangat sederhana. Mari kita ambil sebagai contoh (1998,12,31).

  • Ekspresi (v [0]% 10) * 10 memilih satuan tahun (mis. 1 9 9 8 -> 8) dan menjadikannya digit kesepuluh dari output (sekarang x = 80).
  • Hanya ada dua hari kombinasi di mana lompatan hal kedua terjadi, jadi saya memutuskan untuk menggunakan komponen hari untuk membedakan antara kasus 06,30 dan kasus 12,31. Ekspresi v [2]% 30 adalah 0 jika hari adalah 30, dan 1 jika hari adalah 31. Dalam contoh kita, kita menambahkan 1 ke x (karenanya, sekarang x = 81).
  • Akhirnya, saya mengamati bahwa teka-teki ini hanya melibatkan 5 dekade; maka jika saya memetakan dekade pertama (tahun tujuh puluhan) ke 0 dan dekade terakhir (tahun 2010) ke 4 saya dapat melakukan hal-hal keren. Lebih khusus lagi, jika alih-alih memetakan ke 0,1,2,3,4 I memetakan menjadi 0,2,4,6,8 saya dapat menambahkan nilai ini ke unit x, yang karena aturan sebelumnya adalah 0 atau 1. Jadi pada akhirnya kami memiliki itu juga langkah terakhir ini tidak merusak penambangan, dan kami mendapatkan bahwa unit kasus 06,30 adalah salah satu dari 0,2,4,6,8 dan bahwa unit dari 12,31 kasus adalah satu dari 1,3,5,7,9. Karenanya, bijihnya jelas. Dalam contoh kita, 1998 adalah dalam dekade ketiga (70s-> 0, 80s-> 1, 90s-> 2) jadi kita tambahkan 2 * 2 = 4. Jadi kita mendapatkan x = 85.

Saya menulis program untuk memverifikasi bahwa ini benar, dan kemudian saya mendefinisikan d(x)sebagai kebalikan dari c(v). Dalam contoh kita, c ((1998,12,31)) adalah 85 dan d (85) dicetak dengan benar 1998-12-31 23:59:60.


1
Hapus q=x%10dan ganti qdengan x%10mana saja. Lebih pendek. Saya juga memberikan deskripsi bermanfaat tentang beberapa golf tambahan di program Anda di sini . Saya sarankan melihat Tips untuk Golf di halaman Python .
mbomb007

Ini adalah kode-golf , jadi Anda harus mencoba mempersingkat panjang kode Anda dengan cara apa pun yang mungkin.
mbomb007

-1

gzip, 114 byte

Hexdump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Buat file dengan byte yang dijelaskan di atas.

Ekstrak menggunakan gunzip atau program dekompresi lain untuk mendapatkan file baru bernama "l". File ini berisi output yang diinginkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.