Sıçrama Saniye için Bir Adım!


28

Bugün, şimdiye kadar gerçekleşen 26. atılım saniyesinin vesilesiyle işaret ettiğinden, meydan okumanız, bugüne kadar gerçekleşen GMT ya da UTC'de her atılım saniyesinin tarihini ve saatini ve şimdiye kadar olanları ortaya çıkarmak olacaktır.

Giriş

Giriş yok.

Çıktı

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

kurallar

Sıçrayan saniyelere izin veren birçok yapı olduğundan şüphelendiğimden, onlara izin vereceğim.

Standart boşluklara izin verilmez.

En kısa kod kazanır.

Tarih biçiminde sıfır dolgulu bir ay ve 4 basamaklı bir yıl, ayrıca askeri zaman ve zamanı tarihten ayıran bir boşluk bulunmalıdır. UTCSonuna koymak isteğe bağlıdır. Seçiminiz çizgi veya eğik çizgi.

EDIT: Tahmin edildiği gibi Evet, bu bir kodlama mücadelesi haline geldi. Eğer sadece kodlama artık ikinci sorunu çözebilseydi, tüm kodumuz çok daha pratik olurdu. Belki pratik kullanımlarla daha eğlenceli zorluklar için fikirlere ihtiyacımız var?


Çıktının tam olarak dağıtılması gerekiyor mu, yoksa 26 tarih olduğu sürece herhangi bir dağıtımı olabilir mi?
Ismael Miguel

2
@IsmaelMiguel Bu sıraya girmeleri gerekiyor.
mbomb007

Konu dışı, ancak listeye bakarken, bu günlerde neden bir önceki yüzyılda olduğundan daha az artık saniyeye ihtiyacımız olduğunu merak ediyorum.
Bay Lister,

@MrLister Bağlantılı Wikipedia makalesini görüntüleyin. Dünya'nın değişen dönme hızıyla ilgili olduğunu düşünüyorum.
mbomb007

Yanıtlar:


25

CJam, 72 70 69 64 bayt

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

CJam tercümanında çevrimiçi olarak deneyin .

Fikir

Biz, her artık ikinci kodlayan başlamak + D - 2 * (1972 Y) , D ise 1 Aralık ve oluşursa 0 , aksi.

Tüm kodlanmış sıçrama saniye dizisi:

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

Bu diziye L diyelim .

Dizi artan sırada olduğundan, gerçek sayılar yerine ardışık farkları saklayabiliriz:

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

Bu diziyi bir 15 sayısının basamağı olarak ele alarak, tamsayıyı elde ederiz

19238985373462115979359619336

240 tabanındaki hangi rakamlar (karakterlere yazılır)

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

kod

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
Neredeyse tamamen sorunu çözecek bir yapıya sahip olduğunuz hissi ve henüz CJam'daki manuel çözüm daha kısa.
Alex A.

9
@AlexA. Daha az bayt reimplement olabilir Mathematica bazı yerleşik ins vardır Mathematica .
Martin Ender

@ MartinBüttner: Acımasız.
Alex A.

35

R, 78 75 bayt

Yerleşik mi dedin? İyi...

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

R, .leap.secondssistemin yerel saatinde verilen her bir sıçrama saniyesinin tarihini ve saatini içeren bir otomatik değişkene sahiptir. R 3.2.0 sürümünden itibaren, bu bugün içermiyor, bu yüzden bunu el ile ekledim.

Ungolfed + açıklama:

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

Şunları yapabilirsiniz çevrimiçi denemek !


eğer bir değişkene "23:59:60" atayabilirseniz, bazı karakterleri kaydedebilirsiniz
Charles

1
@NotthatCharles: Bunu düşünmüştüm, ancak R'nin dizeleri birleştirme yöntemi bugünün tarihini ve saatini kısaltmak için yeterli değil. Yine de girdi için teşekkürler!
Alex A.

24

HTML, 594 bayt

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- Bu soru kolmogorov karmaşıklığı olarak etiketlendi ve bu yüzden bu tamamen yasal bir cevap. Yine de kazanması muhtemel değil ...
Digital Trauma,

10
@mlepage "Standart boşluklardan" biri.
Jacob Raihle

4
@Voitcus dosyaya kaydet, bir tarayıcıda aç. Bu bir workingHTML kodu
edc65

9
@ AntonyD'Andrea Evet, ne olmuş? Zorluklarda Vailidity talep edilmiyor code golf.
edc65

5
@anatolyg SİZİN [kolmogorov-karmaşıklık] için eğlenceli değil
vijrox

11

C, 160 146 141 140 bayt

İlk kez gönderme, "standart boşluklar" ın ne olduğundan emin değil. Tabii ki baskı uyarılarım var.

160 bayt:

Orijinal fikir, yılda iki bit kullanarak artık saniyeleri kodlamaktır: biri haziran için diğeri aralık ayı için. Kodlama, bir süre iç bitim sırasında bir bit tüketilir. 128-bit bir tamsayı olmadan, dış ise döngü gereklidir. Gerisi tüm defter tutma ve matematiktir. :-)

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

Önerilen ipuçlarını uygulamak onu 146 bayta indirir. Sonra dış durumu basitleştirmenin bir yolunu buldum (Y <2000'den sadece Z'ye), onu 141 bayta indirdi. Bir tweet'e çok yakın!

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

Günün olumsuzluğunu belirleyerek tarihin kısa sürede ortadan kalkabileceğini fark ettim. Ayın başında da Haziran ayındaki sıfır sırasından dolayı yapamam. Ama en azından şimdi bir tweet'e uyuyor!

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

Güzel sürüm:

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

Bonus versiyonu:

Dıştaki döngüyü 64 bitlik bir tamsayı bir başkasına bit kaydırarak elimine ettim, ancak oldukça uzun "işaretsiz uzun uzun" nedeniyle 150 bayt; "uint64" gibi bir şey kullanabilirsem 138 byte olur.

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'ye Hoşgeldiniz. "Standart boşluklar" bu yazıya atıfta bulunur , ancak genellikle sadece "sağduyu kullanma ve hile yapma" anlamına gelir. :)
Martin Ender

1
Bir fordöngü kullanarak bazı baytları kurtaracağını düşünüyorum . BTW, int main()-> main(). Sen bulabilir bu çok yararlı.
Spikatrix

Ayrıca: X>>=1aynıdır X/=2, 6*(2-Z)aynı 12-6*Zve 4362608640daha bir byte kısadır 0x104082000. intArasında ön main()gereksiz olduğunu ve değiştirirseniz main()için main(Z)o zaman beyanı kaldırabilirsiniz Z=1.
squeamish ossifrage

Gerçekten güzel bir çözüm - düşünmek için başka bir şey - if(X&1)printf(...);ile X&1?printf(...):1;1 byte kaydeder değiştirebilirsiniz
euanjt

ve while(X){...}virgül kullanmak yerine , parantezleri kaldırabilirsinizwhile(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;
euanjt

9

Python 3, 91

Sp3000 tarafından kodlama ve dize biçimlendirmesini kullanır , ancak değerleri sihirli bir sayı yerine bir Python 3 bytes nesnesinde saklar .

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

Kodlama yalnızca baytın 256 olası değerinin 86'sına ihtiyaç duyar, bu nedenle daha güzel görünmesi için bir dizi yazdırılabilir karakter kullanılır.


7

Brainfuck, 806

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

Sen olabilir bu online tercüman çalıştırın.


6

Python 2, 111 104 bayt

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

Baz kodlama ve daha fazla baz kodlama.


5

GNU sed + tarihi: 112

Yaygın Linux dağıtımları da artık saniyelerde yerleşiktir. GNU sed ve date kullanımı:

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 + tarihi: 90

Yolu keserek birkaç karakteri güvenli hale getirme:

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

Toby Speight tarafından ayarlanan GNU sed + tarihi: 84

Yorumlarda önerilen derinden golf versiyonu:

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

Artık saniye verilerini nerede bulacağımı öğrettiğin için teşekkürler. Ne yazık ki, benim date(GNU 8.23), bir sonraki dakikanın ilk saniyesi olarak bunları gösteriyor. 60 saniyelik anıyı anlayan ne kullanıyorsunuz?
Toby Speight

GNU coreutils, ben 76 için aşağı var, traş ile bayt -ryerine, bayrak dateile giriş s///edeğiştirici ve değiştirilmesi %Y-%m-%dile %Fde dateTZ = UTC:sed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight

Bir şeyi özlediğimi biliyordum. Bunu elle belirtmenin hiçbir yolu yok, en azından diğer çözümlerin çoğundan daha kötü değil gibi görünüyor. Birisi bu saniye destekleyici sayıları keman için bazı tarih kütüphanesi ile gelip gelmediğini görelim.
Jens Erat

Oraya 1899-12-31 \1sectarih kullanarak ve 23:59:60o zamanki kodlamayı kullanarak geldim :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

`` İçindeki yeni satır önemli ve sayılır.

Test etmek için aşağıdaki pasajı çalıştırın (yalnızca EcmaScript 6, Firefox olmak)

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 bayt

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

Ne yazık ki \ntarih fonksiyonuna ekleyebilir miyim bilmiyorum . Eğer öyleyse, bu nedeniyle 3 bayt daha azdır ."".


İkisini de (int)soyabilir ve biraz boşluk kaldırabilirsiniz. Varsayılan saat dilimi ayarlanmadıysa, tarih bir hata verir @. 187 bayt: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 makine kodu + DOS, 92 bayt

Kodun 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

Çalıştırmak için 92 baytı bir comdosyaya yazın ve 32-bit Windows veya DOSBox altında çalıştırın.

Kod, yılda bir yarım olmak üzere 87 bitlik bir bitmap kullanır. Bitler, MSB'den başlayarak 16 kişilik gruplar halinde düzenlenir.

Bitmap'in kodunu çözme:

                 ; 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

Kodun yapısı nedeniyle, kod çözme sırasında bazı bitler kayboluyor, bu yüzden tekrarlamak zorunda kaldım. Bu tekrarlama bitmap'i şişirmiyor çünkü zaten 87 bite 96 bite oturmak zorunda kaldım.

Artık saniyenin yazdırılmasından (veya yazdırılmamasından) sonra kod, çıkış mesajının ASCII kodlarındaki manipülasyonları kullanarak tarihi yarım yıl artırır.

Kaynak kodu (ile birleştirilebilir 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,'$'

Bunu test etmek istiyorum, ancak altıgen yapıştırmanızı ve bir ikili dosyaya kaydetmenizi sağlayan tek bir editör bulamıyorum.
Bay Lister,

@ MrLister herhangi bir normal hex editörü sizin için yapmalı.
Doktor

1

Pyth - 88 84 bayt

Verileri sıkıştırmak için char değerine dönüştürür ve verilere 06-30karşı 12-31ikili sayı olarak kaydeder .

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

(sonunda bir boşluk var)

Burada çevrimiçi deneyin .


1

Python 2, 123 121 116 114 111

Oldukça kısa tutmayı başardım, ama ne kadar kısaltacağından emin değilim. Kullanmayı denedim exec, ama biçimlendirme çok pahalı olacak.

Bağlantılı Wikipedia sayfasından tablonun 16 tabanlı kodlamasını kullandım.

Düzenleme: Onaltılık kodlamanın kullanılması, taban 36'dan daha kısadır (daha az golf versiyonuna bakınız).

Burada dene

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

Daha az golf oynadı:

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 bayt

İşte dize ve çalışma uzunluğu kodlaması kullanarak, C bir başka yaklaşım. Diğer C çözümüm kadar özensiz değil, ama belki geliştirilebilir?

155 bayt:

Ay / günü tutmak için bir dize kullanma.

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

Ay / gün dizesini ortadan kaldırmak.

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

Yıl başlangıcını ortadan kaldırmak.

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

Atlama sayısının çalışmadan önce (sonra değil) uygulanmasını sağlamak için arabelleği yeniden kodladıysam, o zaman ifadeleri dış sırasındaki döngüde yeniden sıralayabilir, virgül operatörünü kullanabilir ve parantezleri elimine edebilir, 2 bayt tasarruf edebilirim.

Günü negatif yaparak başka bir baytı kurtarabilirim (diğer çözümümde olduğu gibi).

Güzel:

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

Açıklama:

Çalışmalar bayt olarak kodlanmıştır. Her baytın haziran veya aralık olup olmadığını, uzunluk sayımı için 3 bit, atlama sayımı için 3 bit ve 1 kullanılmamış yüksek bit olduğunu söyleyecek bir biti vardır.

Atlama sayısı, bir işlemden sonra atlanacak yıl sayısıdır; 1972'de iki saniye boyunca izin vermek için -1 ile dengelenir. Bir koşunun uzunluğu kaç yıldır; muhtemelen +1 ile dengelenebilir, ancak şu anda değil.

Yani bir bayt şu anlama gelir: "Bir sonraki bayta geçmeden önce," HAZİRANIZ SÜRE (veya ARALIK) yıllar arası atlamak saniye, sonra SKIP-1 yıl atla "

Baytlar okunabilir hale getirmek ve süslü kodlamalardan kaçınmak için 33 ile kaydırılır.

Bu, 1998-2005 yıllarını kapsayacak kadar fazla atlama bitine sahip olmamıza rağmen, ASCII aralığının dışında olduğumuz için ekstra sıfır uzunluğumuz var. Ayrıca, 1979 kendi başına görünür, çünkü 1972-1979 uzunluğu çok uzun.

Baytlarda yeterli bit var, bu yüzden sonuçta bu sorunlar çözülebilir.


1

q / kdb +, 95 94 93 bayt

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

açıklama

Her yıl + 1 için , 1905'ten beri geçen yılları ASCII karakteri olarak kodlayın, örneğin:

1972 -> 1973 -> 68 -> D

6h$x"D"geri döner 68. Bu qtarihten bu yana , tam sayıların güncel dönüşümünü 2000.01.01çıkarır 95ve gerçekleştiririz "d"$"m"$-12*95-6h$x.

Yukarıdaki + 1'in sebebi , gelecek yılın başından itibaren gerçek sayısı 31 Aralık veya 30 Haziran, yani 1 veya 185 gün almak için gün sayısını çıkarmaktır . Bu nedenle, "DEFGHIJKSUV[^eh"Aralık ayında ikinci bir yıl ve "DMNOQXYZ]lo"Haziran ayında olanlar için bir yıl temsil eder . Eşleştirme-çıkarma yoluyla yapılır (a;b){x-y}'(c;d), nerede ave btarafından düşülür yıldır cve dsırasıyla gün sayısına.

" "0:([]...)sonuçları bize doğru biçimlendirme vermeye hazırlar, bir sütun başlığının üretileceği küçük bir uyarı ile. 1_bu başlığı düşürür ve son ascolarak siparişi doğru bir şekilde almak için uygulanır .

düzenleme : 're-base' 100 yerine 95 yıl çıkarmak için (1 karakter kaydetme).

düzenleme 2 : İşlenenlerin tamsayılar dönüştürme işlevi içindeki konumlarını yeniden sıralama.


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 ile onunla oynayabilirsin .

Düzenleme: İyice dövülmüş! Sıkıştırma cevapları inanılmaz derecede kısa.


Şaşırtıcı bir şekilde, PHP cevaplarım benzer bir algoritma kullanarak daha kısa. Her zaman Python'un daha kompakt olmasını beklerdim. Belki biraz daha golf oynayabilirsin?
Voitcus

Bir bakacağım. En iyi yol olsa da sıkıştırma olduğunu düşünüyorum, ve diğerleri zaten bunu yaptı
sudo rm -rf slash

0

PHP, 164 bayt

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

Bu @ Voitcus'un fikrinde yapılan birkaç değişiklik


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

Bazı görüşler

Temel olarak, d(x)tek bir 2 basamaklı tam sayıdan 3 tam sayı vektörünü sıkıştırır. d(x)ters fonksiyon işlevi (26 sıçrama saniyenin üzerinde). c(v), bunun ardından (1998, 12, 31) gibi bir 3-up'ı 85 gibi bir sayıya dönüştüren bir sıkıştırma işlevidir. Listeyi türetmek için [20 , 21 ... 28,58] Sıkıştırma işlevinin etki alanı üzerinde önemsiz olduğunu doğrulamak için başka bir algoritma tasarladım. Yani, aşağıdaki programın kopya üretmediğinden emin oldum ve çıktısını yukarıdaki programların listesi olarak kullandım.

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

Sıkıştırma işlevi c(v), çok basit bir şema kullanarak, önyükleyici olacak şekilde tasarlanmıştır. Örnek olarak ele alalım (1998,12,31).

  • (V [0]% 10) * 10 ifadesi yılın birimlerini seçer (örneğin, 1 9 9 8 -> 8) ve bunu çıktının onda hanesini (şimdi x = 80) yapar.
  • Artık ikinci şeyin gerçekleştiği sadece iki aylık bir kombinasyon var, bu yüzden 06,30 ve 12,31 vakalarını ayırt etmek için day bileşenini kullanmaya karar verdim. V [2]% 30 ifadesi, gün 30 ise 0, gün 31 ise 1'dir. Örneğimizde, x'e 1 ekleriz (dolayısıyla, şimdi x = 81).
  • Sonunda, bu bulmacanın sadece 5 yıl içerdiğini gözlemledim; dolayısıyla ilk on yılı (yetmişli yıl) 0 ve son on yılı (2010'lar) 4 ile eşleştirirsem harika şeyler yapabilirim. Daha spesifik olarak, eğer 0,1,2,3,4 ile eşlemek yerine 0,2,4,6,8 ile eşleştirirsem, bu değeri önceki cihaza bağlı olarak 0 veya daha fazla olan x birimlerine ekleyebilirim. 1. Sonuç olarak, bu son adımın önyargıyı mahvetmediğini ve 06.30 davasının birimlerinin 0,2,4,6,8'den biri olduğunu ve 12,31 dava 1,3,5,7,9'dur. Dolayısıyla önyargı açıktır. Örneğimize göre, 1998 üçüncü on yılda (70s-> 0, 80s-> 1, 90s-> 2) yani 2 * 2 = 4 ekleriz. Böylece x = 85 olur.

Bunun doğru olduğunu doğrulamak için programı yazdım ve sonra d(x)bunun tersini tanımladım c(v). Örneğimizde, c ((1998, 12, 31)) 85'tir ve d (85) doğru şekilde basar 1998-12-31 23:59:60.


1
Kaldır q=x%10ve değiştirme qile x%10her yerde. Daha kısa. Ayrıca, buradaki programınız hakkında ek bir golf oynamaya ilişkin yararlı bir açıklama yapıyorum . Python'da Golf için İpuçları sayfasını görüntülemenizi öneririm .
mbomb007

Bu kod-golf , bu nedenle kodunuzun uzunluğunu herhangi bir şekilde kısaltmanız gerekir.
mbomb007

-1

gzip, 114 bayt

HexDump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Yukarıda açıklanan baytlarla bir dosya oluşturun.

"L" adında yeni bir dosya almak için gunzip veya başka bir dekompresyon programı kullanarak açın. Bu dosya istenen çıktıyı içeriyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.