Salto per Leap Seconds!


28

Poiché oggi segna l'occasione del 26 ° secondo bisestile che si sia mai verificato, la tua sfida sarà quella di produrre la data e l'ora di ogni secondo bisestile in GMT o UTC che si è verificato finora, così come quello che si verifica oggi.

Ingresso

Non ci sono input.

Produzione

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

Regole

Dal momento che dubito che ci siano molti built-in che consentono secondi di salto, li permetterò.

Le scappatoie standard non sono ammesse.

Il codice più corto vince.

Il formato della data deve avere un mese a zero e un anno a 4 cifre, oltre all'ora militare e uno spazio che separa l'ora dalla data. Mettere UTCalla fine è facoltativo. La tua scelta di trattini o barre.

EDIT: Sì, come previsto, questa è diventata una sfida di codifica. Se solo la codifica potesse risolvere il problema del secondo salto, ... allora tutto il nostro codice sarebbe molto più pratico. Forse abbiamo bisogno di alcune idee per sfide più divertenti con usi pratici?


È necessario che l'output abbia quella distribuzione esatta o può avere qualsiasi distribuzione purché siano presenti le 26 date?
Ismael Miguel,

2
@IsmaelMiguel Devono essere in questo ordine.
mbomb007,

Fuori tema, ma guardando l'elenco, mi chiedo perché in questi giorni abbiamo bisogno di meno secondi bisestili rispetto al secolo precedente.
Mr Lister,

@MrLister Visualizza l'articolo di Wikipedia collegato. Penso che abbia a che fare con il cambiamento della velocità di rotazione della Terra.
mbomb007,

Risposte:


25

CJam, 72 70 69 64 byte

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

Provalo online nell'interprete CJam .

Idea

Iniziamo codificando ogni secondo di salto come 2 * (Y - 1972) + D , dove D è 1 se si verifica in dicembre e 0 altrimenti.

La matrice di tutti i secondi bisestili codificati è:

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

Chiamiamo questo array L .

Poiché l'array è in ordine crescente, è possibile memorizzare le differenze consecutive anziché i numeri effettivi:

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

Considerando questo array come le cifre di un numero di base 15, otteniamo il numero intero

19238985373462115979359619336

quali sono le cifre nella base 240 (dal cast ai personaggi)

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

Codice

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
Quella sensazione quando hai un built-in che risolve quasi completamente il problema e tuttavia la soluzione manuale in CJam è più breve.
Alex A.

9
@AlexA. Ci sono alcuni incorporati in Mathematica che posso reimplementare in meno byte in Mathematica .
Martin Ender,

@ MartinBüttner: brutale.
Alex A.

35

R, 78 75 byte

Incorporati, dici? Bene...

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

R ha una variabile automatica .leap.secondsche contiene la data e l'ora di ogni secondo di salto, dato nell'ora locale del sistema. A partire dalla versione 3.2.0 R, questo non include oggi, quindi l'ho aggiunto manualmente.

Ungolfed + spiegazione:

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

Puoi provarlo online !


se riesci ad assegnare "23:59:60" a una variabile, potresti salvare alcuni caratteri
Non che Charles

1
@NotthatCharles: ci avevo pensato, ma il metodo di R di combinare le stringhe non è abbastanza conciso da rendere la costruzione della data e dell'ora di oggi più brevi. Grazie per l'input però!
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- Questa domanda è taggata con complessità kolmogorov e quindi questa è una risposta perfettamente legale. Probabilmente non vincerà però ...
Digital Trauma,

10
@mlepage Questa è una delle "scappatoie standard".
Jacob Raihle,

4
@Voitcus salva nel file, si apre in un browser. È un workingcodice html
edc65

9
@ AntonyD'Andrea Sì, e allora? Laailail non è richiesta nelle code golfsfide.
edc65,

5
@anatolyg Non sei divertente per [kolmogorov-complessità]
vijrox,

11

C, 160 146 141 140 byte

Prima pubblicazione, non sono sicuro di quali siano le "scappatoie standard". Ho degli avvisi di stampa ovviamente.

160 byte:

L'idea originale è quella di codificare i secondi bisestili usando due bit all'anno: uno per giugno e uno per dicembre. La codifica viene consumata un bit alla volta dal ciclo while interno. Senza un numero intero a 128 bit, è necessario il ciclo while esterno. Il resto è tutto contabile e matematica. :-)

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:

Applicando i suggerimenti suggeriti si arriva a 146 byte. Quindi ho trovato un modo per semplificare la condizione while esterna (da Y <2000 a solo Z), portandola a 141 byte. Così vicino a un 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:

Ho notato che il trattino nella data potrebbe essere eliminato rendendo la giornata negativa. Non posso farlo anche con il mese a causa dello zero iniziale di giugno. Ma almeno si inserisce in un tweet ora!

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

Bella versione:

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

Versione bonus:

Ho eliminato il loop esterno spostando un intero di 64 bit in un altro, ma è di 150 byte, a causa del "long long unsigned" piuttosto lungo; se potessi usare qualcosa come "uint64" sarebbe 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
Benvenuti in PPCG. "Scappatoie standard" si riferisce a questo post , ma generalmente significa semplicemente "usa il buon senso e non imbrogliare". :)
Martin Ender,

1
Penso che l'uso di un forloop salverà alcuni byte. A proposito, int main()-> main(). Potresti trovare questo molto utile.
Spikatrix,

Inoltre: X>>=1è uguale a X/=2, 6*(2-Z)è uguale a 12-6*Z, ed 4362608640è un byte più corto di 0x104082000. Il intfronte main()non è necessario e, se si main()passa a, main(Z)è possibile rimuovere la dichiarazione Z=1.
ossifrage schifoso

Soluzione davvero if(X&1)printf(...);X&1?printf(...):1;
bella-

e anziché while(X){...}utilizzare le virgole in modo da poter rimuovere le parentesi graffe, while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;salvando altri 2 byte
euanjt,

9

Python 3, 91

Utilizza la codifica e la formattazione delle stringhe di Sp3000 , ma memorizza i valori in un oggetto Python 3 byte anziché in un numero magico.

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

La codifica richiede solo 86 dei 256 possibili valori di un byte, quindi viene utilizzato un intervallo di caratteri stampabili per renderlo più gradevole.


7

Brainfuck, 806

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

Puoi eseguirlo su questo interprete online.


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

Codifica di base e più codifica di base.


5

GNU sed + data: 112

Le comuni distribuzioni Linux hanno anche i secondi da saltare integrati. Usando GNU sed e date:

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

Salvaguardare alcuni personaggi tagliando il percorso:

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 messa a punto da Toby Speight: 84

Versione profondamente golfata proposta nei commenti:

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

Grazie per avermi insegnato dove trovare i dati dei secondi bisestili. Sfortunatamente, il mio date(GNU 8.23) mostra quelli come primo secondo del minuto successivo. Cosa stai usando per capire i 60 secondi?
Toby Speight,

Con i coreutils GNU, sono arrivato a 76, radendo i byte con la -rbandiera, sostituendo datecon il s///emodificatore e sostituendo %Y-%m-%dcon %Fin date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight,

Sapevo che mi mancava qualcosa. Sembra che non vi sia alcun modo per specificarlo manualmente, almeno non peggio della maggior parte delle altre soluzioni. Vediamo se qualcuno esce con una libreria di date per suonare i numeri supportando correttamente quei secondi.
Jens Erat,

Ci sono arrivato usando 1899-12-31 \1secla data e il codice hard 23:59:60come il tempo: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

La newline all'interno di `` è significativa e contata.

Per testare, esegui il frammento di seguito (essendo EcmaScript 6, solo 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";}

Sfortunatamente, non so se posso inserire \nnella funzione data. In tal caso, si tratta di 3 byte in meno a causa di ."".


Puoi (int)rimuovere entrambi e rimuovere alcuni spazi bianchi. La data genera un errore, se il fuso orario predefinito non è impostato, silenziarlo con un @. 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 codice macchina + DOS, 92 byte

Hexdump del codice:

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

Per eseguire, scrivere i 92 byte in un comfile ed eseguire Windows o DOSBox a 32 bit.

Il codice utilizza una bitmap con 87 bit, uno ogni sei mesi. I bit sono disposti in gruppi di 16, a partire da MSB.

Decodifica della 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

A causa della struttura del codice, alcuni bit vengono persi durante la decodifica, quindi ho dovuto ripeterli. Questa ripetizione non gonfia la bitmap perché dovevo comunque riempire da 87 bit a 96 bit.

Dopo aver stampato (o non stampato) il secondo bisestile, il codice aumenta la data di sei mesi, usando le manipolazioni sui codici ASCII del messaggio di output.

Codice sorgente (può essere assemblato con 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,'$'

Vorrei provare questo, ma non riesco a trovare un singolo editor ovunque che ti permetta di incollare hex e salvarlo in un file binario.
Mr Lister,

@MrLister qualsiasi normale editor esadecimale dovrebbe farlo per te.
TheDoctor

1

Pyth - 88 84 byte

Converte in char per comprimere i dati e salva i dati 06-30versus 12-31come numero binario.

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

(c'è uno spazio lì alla fine)

Provalo qui online .


1

Python 2, 123 121 116 114 111

Sono riuscito a farlo abbastanza corto, ma non sono sicuro di quanto possa essere più breve. Ho provato a usare exec, ma la formattazione può essere troppo costosa.

Ho usato una codifica base 16 della tabella dalla pagina Wikipedia collegata.

Modifica: l'uso della codifica esadecimale è più breve della base 36 (vedi la versione meno giocata).

Provalo qui

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

Meno 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

Ecco un altro approccio in C, usando le stringhe e la codifica della lunghezza della corsa. Non abbastanza conciso come la mia altra soluzione C, ma forse può essere migliorato?

155 byte:

Utilizzo di una stringa per contenere il mese / giorno.

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:

Eliminazione della stringa del mese / giorno.

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:

Eliminazione dell'inizializzazione dell'anno.

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:

Se ho ricodificato il buffer per fare in modo che il conteggio dei salti si applichi prima (non dopo) l'esecuzione, allora potrei riordinare le istruzioni nel ciclo while esterno, utilizzare l'operatore virgola ed eliminare le parentesi graffe, salvando 2 byte.

Posso salvare un altro byte rendendo il giorno negativo (come nella mia altra soluzione).

Bella:

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

Spiegazione:

Le esecuzioni sono codificate in byte. Ogni byte ha un bit per dire se è giugno o dicembre, 3 bit per un conteggio di lunghezza, 3 bit per un conteggio di salto e 1 bit alto non utilizzato.

Il conteggio dei salti è il numero di anni da saltare dopo una corsa; è compensato da -1 per consentire due secondi bisestili nel 1972. La durata è quanti anni di seguito; probabilmente potrebbe essere compensato di +1 ma non è attualmente.

Quindi un byte significa: "LENGTH anni di GIUGNO (o DICEMBRE) anni di secondi bisestili, quindi salta SKIP-1 anni" prima di passare al byte successivo.

I byte sono sfalsati di 33 per renderli leggibili ed evitare una codifica elaborata.

Ciò significa che, sebbene abbiamo abbastanza bit da saltare per coprire il periodo 1998-2005, siamo fuori dall'intervallo ASCII, quindi abbiamo una corsa extra zero. Inoltre, il 1979 appare da solo perché la lunghezza 1972-1979 è troppo lunga.

Ci sono abbastanza bit nei byte, quindi questi problemi potrebbero essere risolvibili alla fine.


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)

Spiegazione

Per ogni anno + 1 , codifica per anni dal 1905 come carattere ASCII, ad esempio:

1972 -> 1973 -> 68 -> D

6h$xgiri "D"indietro a 68. Dall'epoca qdella data 2000.01.01, sottraggiamo 95ed eseguiamo la conversione da interi a data "d"$"m"$-12*95-6h$x.

Il motivo per cui + 1 sopra è quello di sottrarre il numero di giorni dall'inizio del prossimo anno per ottenere il 31 dicembre o il 30 giugno dell'anno effettivo , ovvero 1 o 185 giorni. Pertanto, "DEFGHIJKSUV[^eh"rappresenta gli anni con un balzo in secondo luogo a dicembre e "DMNOQXYZ]lo"per quelli a giugno. L'accoppiamento-sottrazione viene effettuato tramite (a;b){x-y}'(c;d), dove ae bsono gli anni che verranno sottratti rispettivamente da ce il dnumero di giorni.

" "0:([]...)prepara i risultati per darci la formattazione corretta, con un piccolo avvertimento che verrà generata un'intestazione di colonna. 1_rilascia quell'intestazione e infine si applica ascper ottenere l'ordinamento corretto.

modifica : 'rifa base' per sottrarre 95 anni invece di 100 (salvando 1 carattere).

modifica 2 : riordino il posizionamento degli operandi all'interno della funzione di conversione da interi a oggi.


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"

Si può giocare con esso su repl.it .

Modifica: battuto a fondo! Le risposte alla compressione sono incredibilmente brevi.


Sorprendentemente, la mia risposta PHP è più corta, usando un algoritmo simile. Mi sono sempre aspettato che Python fosse più compatto. Forse potresti golf un po 'di più?
Voitcus,

Darò un'occhiata. Penso che il percorso migliore sia la compressione, e altri l'hanno già fatto
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";}

Questa è solo una piccola modifica dell'idea di @ 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))

Alcuni approfondimenti

Fondamentalmente, d(x)decomprime un vettore di 3 numeri interi da un singolo numero intero a 2 cifre. d(x)è costruito come funzione inversa (nel corso dei 26 secondi) c(v), che a sua volta è una funzione di compressione che trasforma un 3-uple come (1998,12,31) in un numero come 85. Per derivare l'elenco [20 , 21 ... 28,58] Ho progettato un altro algoritmo per verificare che la funzione di compressione sia biiettiva sul dominio. Cioè, ho fatto in modo che il seguente programma non producesse duplicati e ho usato il suo output come l'elenco del programma sopra.

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

La funzione di compressione è c(v)stata progettata per essere biiettiva utilizzando uno schema molto semplice. Prendiamo ad esempio (1998,12,31).

  • L'espressione (v [0]% 10) * 10 seleziona le unità dell'anno (ad es. 1 9 9 8 -> 8) e ne fa la decima cifra dell'output (ora x = 80).
  • Esistono solo due combinazioni di due giorni al giorno in cui accade la seconda cosa del salto, quindi ho deciso di utilizzare la componente giorno per distinguere tra il caso 06,30 e il caso 12,31. L'espressione v [2]% 30 è 0 se il giorno è 30 ed è 1 se il giorno è 31. Nel nostro esempio, aggiungiamo 1 a x (quindi ora x = 81).
  • Infine, ho osservato che questo puzzle richiede solo 5 decenni; quindi se associo il primo decennio (anni settanta) a 0 e l'ultimo decennio (anni 2010) a 4 posso fare cose interessanti. Più specificamente, se invece di mappare a 0,1,2,3,4 I mappa a 0,2,4,6,8 posso aggiungere questo valore alle unità di x, che a causa della regola precedente è 0 o 1. Quindi alla fine abbiamo che anche quest'ultimo passaggio non avvita la biiezione, e otteniamo che le unità di un caso 06,30 sono di 0,2,4,6,8 e che le unità di un Il caso 12,31 è uno di 1,3,5,7,9. Quindi la biiezione è ovvia. Nel nostro esempio, il 1998 è nella terza decade (anni 70-> 0, anni 80-> 1, anni 90-> 2), quindi aggiungiamo 2 * 2 = 4. Quindi otteniamo x = 85.

Ho scritto il programma per verificare che ciò sia vero, e poi ho definito d(x)l'inverso di c(v). Nel nostro esempio, c ((1998,12,31)) è 85 e d (85) stampa correttamente 1998-12-31 23:59:60.


1
Rimuovere q=x%10e sostituire qcon x%10ovunque. È più corto Fornisco anche una descrizione utile di alcuni golf aggiuntivi sul tuo programma qui . Consiglio di visualizzare la pagina Suggerimenti per giocare a golf in Python .
mbomb007,

Questo è code-golf , quindi dovresti provare ad accorciare la lunghezza del tuo codice in ogni modo possibile.
mbomb007,

-1

gzip, 114 byte

hexdump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Creare un file con i byte sopra descritti.

Estrai usando gunzip o un altro programma di decompressione per ottenere un nuovo file chiamato "l". Questo file contiene l'output desiderato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.