Skok na sekundy przestępne!

28

Ponieważ dzisiaj przypada 26. sekunda przestępna , Twoim wyzwaniem będzie podanie daty i godziny każdej drugiej sekundy przestępnej w GMT lub UTC, która miała miejsce do tej pory, a także tej, która ma miejsce dzisiaj.

Wkład

Brak danych wejściowych.

Wydajność

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

Zasady

Ponieważ wątpię, aby było wiele wbudowanych, które pozwalają na sekundę przestępną, pozwolę im.

Standardowe luki są niedozwolone.

Najkrótszy kod wygrywa.

Format daty musi mieć zerowany miesiąc i 4-cyfrowy rok, a także czas wojskowy i spację oddzielającą czas od daty. Umieszczenie UTCna końcu jest opcjonalne. Twój wybór myślników lub ukośników.

EDYCJA: Tak, jak przewidywano, stało się to wyzwaniem kodowania. Gdyby tylko kodowanie mogło naprawić drugi problem, ... cały nasz kod byłby o wiele bardziej praktyczny. Może potrzebujemy pomysłów na więcej zabawy z praktycznymi zastosowaniami?

mbomb007
źródło
Czy wynik musi mieć ten dokładny rozkład, czy może mieć dowolny rozkład, o ile istnieje 26 dat?
Ismael Miguel
2
@IsmaelMiguel Muszą być w tej kolejności.
mbomb007
Poza tematem, ale patrząc na listę, zastanawiam się, dlaczego potrzebujemy obecnie mniej sekund przestępnych niż w poprzednim stuleciu.
Pan Lister,
@MrLister Zobacz powiązany artykuł w Wikipedii. Myślę, że ma to związek ze zmieniającą się prędkością obrotową Ziemi.
mbomb007

Odpowiedzi:

25

CJam, 72 70 69 64 bajtów

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

Wypróbuj online w interpretatorze CJam .

Pomysł

Zaczynamy od zakodowania każdej sekundy przestępnej jako 2 * (Y - 1972) + D , gdzie D wynosi 1, jeśli występuje w grudniu, a 0 w przeciwnym razie.

Tablica wszystkich zakodowanych sekund przestępnych to:

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

Nazwijmy to tablica L .

Ponieważ tablica jest w porządku rosnącym, możemy przechowywać kolejne różnice zamiast rzeczywistych liczb:

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

Traktując tę ​​tablicę jako cyfry liczby podstawowej 15, otrzymujemy liczbę całkowitą

19238985373462115979359619336

które cyfry w bazie 240 (przesyłane do postaci) są

~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.
}
Dennis
źródło
28
To uczucie, gdy masz wbudowaną funkcję, która prawie całkowicie rozwiązuje problem, a mimo to ręczne rozwiązanie w CJam jest krótsze.
Alex A.
9
@AlexA. Jest kilka wbudowanych w Mathematica, które mogę zaimplementować w mniejszej liczbie bajtów w Mathematica .
Martin Ender
@ MartinBüttner: Brutal.
Alex A.,
35

R 78 78 bajtów

Wbudowane, mówisz? Dobrze...

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

R ma zmienną automatyczną, .leap.secondsktóra zawiera datę i godzinę drugiego wstawienia przestępnego, podaną w czasie lokalnym systemu. Począwszy od wersji R 3.2.0, nie obejmuje to dzisiaj, więc dodałem to ręcznie.

Niegolfowane + wyjaśnienie:

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

Możesz spróbować online !

Alex A.
źródło
jeśli możesz przypisać „23:59:60” do zmiennej, możesz zapisać niektóre znaki
Nie, że Charles
1
@NotthatCharles: Myślałem o tym, ale metoda łączenia ciągów R nie jest wystarczająco zwięzła, aby skrócić dzisiejszą datę i godzinę. W każdym razie dziękuję za wkład!
Alex A.
24

HTML, 594 bajty

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

¯ \ _ (ツ) _ / ¯

vijrox
źródło
6
@ Vioz- To pytanie jest oznaczone złożonością kolmogorowa, więc jest to odpowiedź całkowicie zgodna z prawem. Prawdopodobnie nie wygra ...
Digital Trauma
10
@mlepage To jedna ze „standardowych luk”.
Jacob Raihle
4
@Voitcus zapisz w pliku, otwórz w przeglądarce. Jest to workingkod HTML
edc65
9
@ AntonyD'Andrea Tak, więc co z tego? Wyzwania nie są wymagane code golf.
edc65
5
@anatolyg YOU'RE not fun for [kolmogorov-complexity]
vijrox
11

C, 160 146 141 140 bajtów

Po raz pierwszy nie jestem pewien, jakie są „standardowe luki”. Oczywiście mam ostrzeżenia printf.

160 bajtów:

Pierwotnym pomysłem jest kodowanie sekund przestępnych za pomocą dwóch bitów rocznie: jeden dla czerwca i jeden dla grudnia. Kodowanie jest zużywane pojedynczo przez wewnętrzną pętlę while. Bez 128-bitowej liczby całkowitej niezbędna jest zewnętrzna pętla while. Reszta to księgowość i matematyka. :-)

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 bajtów:

Zastosowanie sugerowanych wskazówek sprowadza go do 146 bajtów. Potem znalazłem sposób, aby uprościć warunek zewnętrzny while (od Y <2000 do tylko Z), obniżając go do 141 bajtów. Tak blisko tweeta!

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 bajtów:

Zauważyłem, że kreska w dacie może zostać wyeliminowana poprzez uczynienie dnia ujemnym. Nie można tego zrobić także z miesiącem, ponieważ w czerwcu prowadzi zero. Ale teraz przynajmniej mieści się w tweecie!

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

Ładna wersja:

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

Wersja bonusowa:

Wyeliminowałem zewnętrzną pętlę poprzez przesunięcie bitów jednej 64-bitowej liczby całkowitej na drugą, ale ma ona 150 bajtów, z powodu dość długiego „niepodpisanego długiego długiego”; gdybym mógł użyć czegoś takiego jak „uint64”, byłoby to 138 bajtów.

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;
}
mlepage
źródło
4
Witamy w PPCG. „Standardowe luki” odnoszą się do tego postu , ale ogólnie oznacza to po prostu „kieruj się zdrowym rozsądkiem i nie oszukuj”. :)
Martin Ender
1
Myślę, że użycie forpętli pozwoli zaoszczędzić trochę bajtów. BTW, int main()-> main(). Może ci się to bardzo przydać .
Spikatrix
Ponadto: X>>=1jest taki sam jak X/=2, 6*(2-Z)jest taki sam jak 12-6*Zi 4362608640jest o jeden bajt krótszy niż 0x104082000. intW przód main()jest niepotrzebne, a jeśli zmieni main()się main(Z)potem można usunąć deklarację Z=1.
piskliwy ossifrage
Naprawdę fajne rozwiązanie - kolejna rzecz do przemyślenia - możesz zmienić, if(X&1)printf(...);dzięki X&1?printf(...):1;czemu oszczędzasz 1 bajt
euanjt
i zamiast while(X){...}używać przecinków, aby usunąć nawiasy klamrowe - while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;oszczędzając kolejne 2 bajty
euanjt
9

Python 3, 91

Używa kodowania i formatowania ciągów przez Sp3000 , ale przechowuje wartości w obiekcie bajtów Python 3 zamiast magicznej liczby.

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

Kodowanie wymaga tylko 86 z 256 możliwych wartości bajtów, więc zakres znaków do wydrukowania jest używany, aby wyglądać ładniej.

xnor
źródło
7

Brainfuck, 806

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

Możesz uruchomić go na tym tłumaczu online.

Peter Olson
źródło
6

Python 2, 111 104 bajtów

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

Kodowanie podstawowe i więcej kodowania podstawowego.

Sp3000
źródło
5

GNU sed + data: 112

Typowe dystrybucje Linuksa mają także wbudowane sekundy przestępne. Korzystanie z GNU sed i data:

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

Zabezpiecz kilka postaci, odcinając ścieżkę:

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

GNU sed + data dostrojona przez Toby Speight: 84

Wersja głęboko golfowa zaproponowana w komentarzach:

sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*
Jens Erat
źródło
Dzięki za nauczenie mnie, gdzie znaleźć dane sekund przestępnych. Niestety mój date(GNU 8.23) wyświetla je jako pierwszą sekundę następnej minuty. Czego używasz, który rozumie 60-sekundową minutę?
Toby Speight,
Z coreutils GNU mam go do 76 golenia bajtów z -rflagą, zastępując datew z s///emodyfikatorem, a zastąpienie %Y-%m-%dw %Fw date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight
Wiedziałem, że coś przeoczyłem. Wydaje się, że nie ma sposobu na ręczne określenie tego, przynajmniej nie gorsze niż w przypadku większości innych rozwiązań. Zobaczmy, czy ktoś wymyśli jakąś bibliotekę dat, która poprawi liczby poprawnie obsługując te sekundy.
Jens Erat
Dotarłem tam, używając 1899-12-31 \1secdaty i na stałe wpisując 23:59:60czas: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

Nowa linia wewnątrz `` jest znacząca i liczona.

Aby przetestować, uruchom poniższy fragment kodu (tylko EcmaScript 6, tylko Firefox)

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

edc65
źródło
2

PHP, 198 bajtów

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

Niestety nie wiem, czy mogę wstawić \nfunkcję daty. Jeśli tak, to o 3 bajty mniej z powodu ."".

Voitcus
źródło
Możesz usunąć oba (int)i usunąć trochę białych znaków. Data generuje błąd, jeśli domyślna strefa czasowa nie jest ustawiona, ucisz ją za pomocą @. 187 bajtów: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

Kod maszynowy 8086 + DOS, 92 bajty

Hexdump kodu:

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

Aby uruchomić, zapisz 92 bajty w com-pliku i uruchom pod 32-bitowym systemem Windows lub DOSBox.

Kod wykorzystuje bitmapę z 87 bitami, jeden na pół roku. Bity są ułożone w grupy po 16, zaczynając od MSB.

Dekodowanie mapy bitowej:

                 ; 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

Ze względu na strukturę kodu niektóre bity są tracone podczas dekodowania, więc musiałem je powtórzyć. To powtarzanie nie powoduje rozdęcia mapy bitowej, ponieważ musiałem uzupełnić 87 bitów do 96 bitów.

Po wydrukowaniu (lub nie wydrukowaniu) sekundy przestępnej kod zwiększa datę o pół roku przy użyciu manipulacji kodami ASCII komunikatu wyjściowego.

Kod źródłowy (może być złożony 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,'$'
anatolig
źródło
Chciałbym to przetestować, ale wydaje mi się, że nie mogę znaleźć nigdzie edytora, który pozwala wkleić hex i zapisać go w pliku binarnym.
Pan Lister
@MrLister każdy normalny edytor szesnastkowy powinien to zrobić za Ciebie.
TheDoctor,
1

Pyth - 88 84 bajtów

Konwertuje na char, aby skompresować dane i zapisuje dane 06-30kontra 12-31jako liczbę binarną.

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

(na końcu jest miejsce)

Wypróbuj tutaj online .

Maltysen
źródło
1

Python 2, 123 121 116 114 111

Udało mi się to zrobić dość krótko, ale nie jestem pewien, jak długo może być krótszy. Próbowałem użyć exec, ale formatowanie staje się zbyt kosztowne.

Użyłem podstawowego kodowania tabeli 16 z powiązanej strony Wikipedii.

Edycja: użycie kodowania szesnastkowego jest krótsze niż baza 36 (patrz wersja mniej golfowa).

Wypróbuj tutaj

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

Mniej golfa:

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)
mbomb007
źródło
1

C, 155 149 147 bajtów

Oto inne podejście w C, wykorzystujące ciągi znaków i kodowanie długości przebiegu. Nie tak zwięzłe jak moje inne rozwiązanie C, ale może można to poprawić?

155 bajtów:

Używanie ciągu do przechowywania miesiąca / dnia.

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 bajtów:

Eliminowanie ciągu miesiąca / dnia.

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 bajtów:

Eliminacja inicjalizacji roku.

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

Gdybym ponownie kodował bufor, aby licznik pominięć obowiązywał przed uruchomieniem (a nie po nim), mógłbym zmienić kolejność instrukcji w zewnętrznej pętli while, użyć operatora przecinka i wyeliminować nawiasy klamrowe, oszczędzając 2 bajty.

Mogę zapisać kolejny bajt, ustawiając dzień na ujemny (jak w moim innym rozwiązaniu).

Ładny:

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

Wyjaśnienie:

Przebiegi są kodowane w bajtach. Każdy bajt ma jeden bit do powiedzenia, czy jest to czerwiec, czy grudzień, 3 bity dla liczby długości, 3 bity dla liczby pominięć i 1 nieużywany bit wysoki.

Liczba pominięć to liczba lat, które należy pominąć po biegu; jest przesunięty o -1, aby pozwolić na dwie sekundy przestępne w 1972 roku. Długość to ile lat z rzędu; prawdopodobnie można go zrównoważyć +1, ale obecnie nie jest.

Tak więc bajt oznacza: „Wykonaj LENGTH lat CZERWCA (lub GRUDZIEŃ) lat przestępnych sekund, a następnie pomiń SKIP-1 rok” przed przejściem do następnego bajtu.

Bajty są przesunięte o 33, aby były czytelne i unikały wymyślnego kodowania.

Oznacza to, że chociaż mamy wystarczającą liczbę bitów pomijania, aby pokryć lata 1998-2005, jesteśmy poza zakresem ASCII, więc mamy dodatkowy przebieg o zerowej długości. Również rok 1979 pojawia się sam, ponieważ długość 1972–1979 jest o jeden za długa.

W bajtach jest wystarczająco dużo bitów, więc te problemy mogą być ostatecznie naprawione.

mlepage
źródło
1

q / kdb +, 95 94 93 bajtów

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

Wyjaśnienie

Dla każdego roku + 1 koduj dla lat od 1905 roku jako znak ASCII, np .:

1972 -> 1973 -> 68 -> D

6h$xobroty "D"z powrotem do 68. Ponieważ qepoka daty jest 2000.01.01, odejmujemy 95i wykonujemy konwersję liczb całkowitych na datę "d"$"m"$-12*95-6h$x.

Powodem, dla którego +1 powyżej, jest odjęcie liczby dni od początku przyszłego roku, aby uzyskać faktyczny rok 31 grudnia lub 30 czerwca, a mianowicie 1 lub 185 dni. Dlatego "DEFGHIJKSUV[^eh"reprezentuje lata z drugim skokiem w grudniu, a "DMNOQXYZ]lo"dla tych w czerwcu. Parowanie-odejmowanie odbywa się za pośrednictwem (a;b){x-y}'(c;d), gdzie ai bsą lata, które będą odejmowane przez ci dliczby dni, odpowiednio.

" "0:([]...)przygotowuje wyniki, aby zapewnić nam prawidłowe formatowanie, z małym zastrzeżeniem, że zostanie wygenerowany nagłówek kolumny. 1_upuszcza ten nagłówek i na koniec stosuje ascsię, aby poprawnie zamówić.

edycja : „przywróć bazę” do odejmowania 95 lat zamiast 100 (zapisując 1 znak).

edycja 2 : zmiana kolejności pozycjonowania operandów w funkcji konwersji liczb całkowitych na datę.

hjk
źródło
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"

Można grać z nim na repl.it .

Edycja: Całkowicie pobity! Odpowiedzi na kompresję są niezwykle krótkie.

sudo rm -rf slash
źródło
Zaskakujące jest to, że moja odpowiedź PHP jest krótsza i wykorzystuje podobny algorytm. Zawsze spodziewałem się, że Python będzie bardziej kompaktowy. Może mógłbyś jeszcze trochę zagrać w golfa?
Voitcus,
Spojrzę na to. Myślę, że najlepszą drogą jest kompresja, a inni już to zrobili
sudo rm -rf slash
0

PHP, 164 bajty

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

To tylko kilka modyfikacji pomysłu @ Voitcus

pranzer
źródło
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))

Niektóre spostrzeżenia

Zasadniczo d(x)dekompresuje wektor 3 liczb całkowitych z jednej 2-cyfrowej liczby całkowitej. d(x)jest skonstruowany jako funkcja odwrotna (w danych 26 sekund przestępnych) c(v), która z kolei jest funkcją kompresji, która zamienia 3-uple, takie jak (1998,12,31), na liczbę 85. Aby uzyskać listę [20 , 21 ... 28,58] Zaprojektowałem inny algorytm, aby sprawdzić, czy funkcja kompresji jest bijectywna w domenie. To znaczy upewniłem się, że poniższy program nie tworzy duplikatów, i użyłem jego danych wyjściowych jako listy powyższego programu.

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

Funkcja kompresji c(v)została zaprojektowana tak, aby była bijectywna przy użyciu bardzo prostego schematu. Weźmy jako przykład (1998,12,31).

  • Wyrażenie (v [0]% 10) * 10 wybiera jednostki roku (np. 1 9 9 8 -> 8) i czyni go dziesiątą cyfrą wyniku (teraz x = 80).
  • Są tylko kombinacje dwóch miesięcy, w których dzieje się druga rzecz, więc postanowiłem użyć komponentu dnia, aby rozróżnić przypadek 06,30 i przypadek 12,31. Wyrażenie v [2]% 30 wynosi 0, jeśli dzień wynosi 30, a 1, jeśli dzień ma 31. W naszym przykładzie dodajemy 1 do x (stąd teraz x = 81).
  • Wreszcie zauważyłem, że ta łamigłówka obejmuje tylko 5 dekad; dlatego jeśli mapuję pierwszą dekadę (lata siedemdziesiąte) na 0, a ostatnią dekadę (lata 2010) na 4, mogę zrobić fajne rzeczy. Mówiąc dokładniej, jeśli zamiast mapowania na 0,1,2,3,4 I mapuję na 0,2,4,6,8, mogę dodać tę wartość do jednostek x, co z powodu poprzedniej reguły wynosi 0 lub 1. Więc w końcu mamy również to, że ten ostatni krok nie psuje bijectionu i otrzymujemy, że jednostki 06,30 są jednymi z 0,2,4,6,8 i że jednostki 12,31 przypadków jest jednym z 1,3,5,7,9. Stąd wstrząs jest oczywisty. W naszym przykładzie 1998 przypada na trzecią dekadę (lata 70-te> 0, lata 80-> 1, lata 90-> 2), więc dodajemy 2 * 2 = 4. Otrzymujemy x = 85.

Napisałem program, aby sprawdzić, czy to prawda, a następnie zdefiniowałem d(x)jako odwrotność c(v). W naszym przykładzie c ((1998,12,31)) wynosi 85, a d (85) poprawnie drukuje 1998-12-31 23:59:60.

damix911
źródło
1
Wyjąć q=x%10i wymienić qz x%10wszędzie. Jest krótszy Daję również pomocny opis niektórych dodatkowych golfa w twoim programie tutaj . Polecam przejrzeć stronę Wskazówki dotyczące gry w golfa w języku Python .
mbomb007
To jest golf golfowy , więc powinieneś spróbować skrócić długość kodu w jakikolwiek możliwy sposób.
mbomb007,
-1

gzip, 114 bajtów

Hexdump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Utwórz plik z bajtami opisanymi powyżej.

Wyodrębnij za pomocą gunzip lub innego programu dekompresyjnego, aby uzyskać nowy plik o nazwie „l”. Ten plik zawiera żądane dane wyjściowe.

Stef Heyenrath
źródło