Leap for Leap Seconds!

28

Comme aujourd'hui marque l'occasion de la 26e seconde intercalaire à se produire, votre défi sera d'afficher la date et l'heure de chaque seconde intercalaire en GMT ou UTC qui s'est produite jusqu'à présent, ainsi que celle qui se produira aujourd'hui.

Contribution

Il n'y a aucune entrée.

Sortie

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

Règles

Étant donné que je doute qu'il existe de nombreux éléments intégrés qui permettent des secondes intercalaires, je les autorise.

Les failles standard ne sont pas autorisées.

Le code le plus court gagne.

Le format de la date doit avoir un mois à zéro et une année à 4 chiffres, ainsi que l'heure militaire et un espace séparant l'heure de la date. La mise UTCà la fin est facultative. Votre choix de tirets ou de barres obliques.

EDIT: Oui, comme prévu, cela est devenu un défi d'encodage. Si seulement l'encodage pouvait résoudre le problème de la seconde intercalaire, ... alors tout notre code serait beaucoup plus pratique. Peut-être que nous avons besoin d'idées pour des défis plus amusants avec des utilisations pratiques?

mbomb007
la source
Est-ce que la sortie doit avoir cette distribution exacte, ou peut-elle avoir n'importe quelle distribution tant que les 26 dates sont là?
Ismael Miguel
2
@IsmaelMiguel Ils doivent être dans cet ordre.
mbomb007
Hors sujet, mais en regardant la liste, je me demande pourquoi nous avons besoin de moins de secondes intercalaires ces jours-ci qu'au siècle précédent.
M. Lister
@MrLister Voir l'article Wikipédia lié. Je pense que cela a à voir avec la vitesse de rotation changeante de la Terre.
mbomb007

Réponses:

25

CJam, 72 70 69 64 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Idée

Nous commençons par encoder chaque seconde intercalaire en 2 * (Y - 1972) + D , où D est 1 s'il se produit en décembre et 0 sinon.

Le tableau de toutes les secondes intercalaires codées est le suivant:

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

Appelons ce tableau L .

Étant donné que le tableau est en ordre croissant, nous pouvons stocker les différences consécutives au lieu des nombres réels:

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

En traitant ce tableau comme les chiffres d'un nombre de base 15, nous obtenons l'entier

19238985373462115979359619336

dont les chiffres de la base 240 (convertis en caractères) sont

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

Code

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
la source
28
Ce sentiment lorsque vous avez un intégré qui résout presque entièrement le problème et pourtant la solution manuelle dans CJam est plus courte.
Alex A.
9
@AlexA. Il existe des fonctions intégrées dans Mathematica que je peux réimplémenter en moins d'octets dans Mathematica .
Martin Ender
@ MartinBüttner: Brutal.
Alex A.
35

R, 78 75 octets

Intégrés, dites-vous? Bien...

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

R a une variable automatique .leap.secondsqui contient la date et l'heure de chaque insertion de seconde intercalaire, données dans l'heure locale du système. À partir de la version R 3.2.0, cela ne comprend pas aujourd'hui, donc je l'ai ajouté manuellement.

Non golfé + explication:

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

Vous pouvez l' essayer en ligne !

Alex A.
la source
si vous pouvez attribuer "23:59:60" à une variable, vous pourriez enregistrer quelques caractères
pas que Charles
1
@NotthatCharles: J'y avais pensé, mais la méthode de R pour combiner les chaînes n'est pas assez concise pour raccourcir la construction de la date et de l'heure d'aujourd'hui. Merci pour votre contribution!
Alex A.
24

HTML, 594 octets

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
la source
6
@ Vioz- Cette question est étiquetée kolmogorov-complexité et c'est donc une réponse parfaitement légale. Il est peu probable que cela gagne ...
Digital Trauma
10
@mlepage C'est l'une des "failles standard".
Jacob Raihle
4
@Voitcus enregistrer dans un fichier, ouvrir dans un navigateur. C'est un workingcode html
edc65
9
@ AntonyD'Andrea Ouais, alors quoi? La disponibilité n'est pas demandée dans les code golfcontestations.
edc65
5
@anatolyg VOUS N'ÊTES PAS AMUSANT POUR [kolmogorov-complexité]
vijrox
11

C, 160 146 141 140 octets

Première publication, je ne sais pas ce que sont les "failles standard". J'ai des avertissements printf bien sûr.

160 octets:

L'idée originale est d'encoder les secondes intercalaires en utilisant deux bits par an: un pour juin et un pour décembre. Le codage est consommé un bit à la fois par la boucle while interne. Sans un entier de 128 bits, la boucle while externe est nécessaire. Le reste est entièrement comptable et mathématique. :-)

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

L'application des conseils suggérés le ramène à 146 octets. Ensuite, j'ai trouvé un moyen de simplifier la condition while externe (de Y <2000 à seulement Z), en la ramenant à 141 octets. Si proche d'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 octets:

J'ai remarqué que le tiret de la date pouvait être éliminé en rendant la journée négative. Je ne peux pas le faire avec le mois également en raison du zéro en juin. Mais au moins, ça tient dans un tweet maintenant!

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

Jolie version:

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

Version bonus:

J'ai éliminé la boucle externe en décalant les bits d'un entier 64 bits dans un autre, mais c'est 150 octets, en raison du plutôt long "unsigned long long"; si je pouvais utiliser quelque chose comme "uint64", ce serait 138 octets.

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
la source
4
Bienvenue chez PPCG. "Les échappatoires standard" se réfèrent à ce post , mais généralement cela signifie simplement "faites preuve de bon sens et ne trichez pas". :)
Martin Ender
1
Je pense que l'utilisation d'une forboucle permettra d'économiser quelques octets. BTW, int main()-> main(). Vous pourriez trouver cela très utile.
Spikatrix
Aussi: X>>=1est le même que X/=2, 6*(2-Z)est le même que 12-6*Zet 4362608640est un octet plus court que 0x104082000. Le intdevant main()n'est pas nécessaire, et si vous passez main()à main(Z)alors vous pouvez supprimer la déclaration Z=1.
squeamish ossifrage
Solution vraiment sympa - une autre chose à penser - vous pouvez changer if(X&1)printf(...);avec X&1?printf(...):1;ce qui économise 1 octet
euanjt
et plutôt que d' while(X){...}utiliser des virgules afin que vous puissiez supprimer les accolades - while(X)X&1?printf("%d-%02d-%d 23:59:60\n",Y,6*(2-Z),31-Z):1,Y+=Z^=1,X>>=1;économiser encore 2 octets
euanjt
9

Python 3, 91

Utilise l'encodage et le formatage des chaînes par Sp3000 , mais stocke les valeurs dans un objet Python 3 octets plutôt qu'un nombre magique.

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

Le codage n'a besoin que de 86 des 256 valeurs possibles d'un octet, donc une plage de caractères imprimables est utilisée pour le rendre plus agréable.

xnor
la source
7

Brainfuck, 806

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

Vous pouvez l' exécuter sur cet interprète en ligne.

Peter Olson
la source
6

Python 2, 111 104 octets

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

Encodage de base et plus d'encodage de base.

Sp3000
la source
5

GNU sed + date: 112

Les distributions Linux courantes ont également des secondes intercalaires intégrées. Utilisation de GNU sed et 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 + date: 90

Sécuriser quelques personnages en coupant le chemin:

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 réglé par Toby Speight: 84

Version profondément golfée proposée dans les commentaires:

sed -nr 's/^([0-9]+).*/date -d "1899-12-31 \1sec" "+%F 23:59:60"/ep' /u*/s*/z*/leap*
Jens Erat
la source
Merci de m'avoir appris où trouver les données en quelques secondes. Malheureusement, mon date(GNU 8.23) les affiche comme la première seconde de la minute suivante. Qu'utilisez-vous qui comprend la minute de 60 secondes?
Toby Speight
Avec GNU coreutils, je l' ai eu jusqu'à 76, le rasage octets avec le -rdrapeau, en remplaçant dateavec le s///emodificateur, et en remplaçant %Y-%m-%davec %Fdans date: TZ = UTCsed -nr 's/^([0-9]+).*/date -d "1900-1-1 \1sec" "+%F %T"/ep' /u*/s*/z*/leap*
Toby Speight
Je savais que j'avais raté quelque chose. Il semble qu'il n'y ait aucun moyen de le spécifier manuellement, du moins pas pire que la plupart des autres solutions. Voyons voir si quelqu'un propose une bibliothèque de dates pour jouer les chiffres en prenant correctement en charge ces secondes.
Jens Erat
J'y suis arrivé en utilisant 1899-12-31 \1secla date et le codage 23:59:60en dur comme heure: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 nouvelle ligne à l'intérieur `` est significative et comptée.

Pour tester, exécutez l'extrait ci-dessous (étant EcmaScript 6, Firefox uniquement)

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

edc65
la source
2

PHP, 198 octets

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

Malheureusement, je ne sais pas si je peux insérer \ndans la fonction date. Si c'est le cas, c'est 3 octets de moins à cause de ."".

Voitcus
la source
Vous pouvez (int)supprimer les deux et supprimer des espaces. La date renvoie une erreur.Si le fuseau horaire par défaut n'est pas défini, désactivez-le avec un @. 187 octets: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 code machine + DOS, 92 octets

Hexdump du code:

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

Pour l'exécuter, écrivez les 92 octets dans un comfichier et exécutez sous Windows 32 bits ou DOSBox.

Le code utilise une image bitmap de 87 bits, une par semestre. Les bits sont organisés en groupes de 16, à partir de MSB.

Décodage du 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

En raison de la structure du code, certains bits sont perdus lors du décodage, j'ai donc dû les répéter. Cette répétition ne gonfle pas le bitmap parce que j'ai quand même dû remplir 87 bits à 96 bits.

Après avoir imprimé (ou non imprimé) la seconde intercalaire, le code augmente la date d'un semestre, en utilisant des manipulations sur les codes ASCII du message de sortie.

Code source (peut être assemblé avec 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,'$'
anatolyg
la source
Je voudrais tester cela, mais je n'arrive pas à trouver un seul éditeur n'importe où qui vous permette de coller de l'hex et de l'enregistrer dans un fichier binaire.
M. Lister
@MrLister, tout éditeur hexadécimal normal devrait le faire pour vous.
TheDoctor
1

Pyth - 88 84 octets

Convertit en char pour compresser les données et enregistre les données 06-30versus en 12-31tant que nombre binaire.

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

(il y a un espace à la fin)

Essayez-le ici en ligne .

Maltysen
la source
1

Python 2, 123 121 116 116 114 111

J'ai réussi à le faire assez court, mais je ne sais pas combien de temps il peut devenir plus court. J'ai essayé d'utiliser exec, mais le formatage devient trop coûteux.

J'ai utilisé un encodage base 16 de la table à partir de la page Wikipédia liée.

Edit: L'utilisation de l'encodage hexadécimal est plus courte que la base 36 (voir la version la moins jouée.)

Essayez-le ici

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

Moins 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)
mbomb007
la source
1

C, 155 149 147 octets

Voici une autre approche en C, utilisant des chaînes et un encodage de longueur d'exécution. Pas aussi concis que mon autre solution C, mais peut-être peut-il être amélioré?

155 octets:

Utilisation d'une chaîne pour contenir le mois / jour.

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

Suppression de la chaîne mois / jour.

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

Suppression de l'initialisation de l'année.

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

Si j'ai réencodé le tampon pour que le nombre de sauts s'applique avant (et non après) l'exécution, je pourrais réorganiser les instructions dans la boucle while externe, utiliser l'opérateur virgule et éliminer les accolades, en économisant 2 octets.

Je peux enregistrer un autre octet en rendant la journée négative (comme dans mon autre solution).

Joli:

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

Explication:

Les exécutions sont codées en octets. Chaque octet a un bit pour dire si c'est juin ou décembre, 3 bits pour un comptage de longueur, 3 bits pour un comptage de saut et 1 bit haut inutilisé.

Le nombre de sauts est le nombre d'années à sauter après une course; il est compensé par -1 pour permettre deux secondes intercalaires en 1972. La durée correspond au nombre d'années consécutives; il pourrait probablement être compensé par +1, mais ce n'est pas le cas actuellement.

Ainsi, un octet signifie: "Faites des années de LONGUEUR en JUIN (ou DÉCEMBRE) en secondes intercalaires, puis sautez SKIP-1 ans" avant de passer à l'octet suivant.

Les octets sont décalés de 33 pour les rendre lisibles et éviter un encodage sophistiqué.

Cela signifie que bien que nous ayons suffisamment de bits de saut pour couvrir 1998-2005, nous sommes hors de portée ASCII, nous avons donc une longueur supplémentaire nulle. De plus, 1979 apparaît tout seul parce que la longueur 1972-1979 est trop longue.

Il y a suffisamment de bits dans les octets, donc ces problèmes pourraient être résolus en fin de compte.

mlepage
la source
1

q / kdb +, 95 94 93 octets

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

Explication

Pour chaque année + 1 , codez pour les années depuis 1905 en tant que caractère ASCII, par exemple:

1972 -> 1973 -> 68 -> D

6h$xtours "D"dos à 68. Puisque ql'époque de la date est 2000.01.01, nous soustrayons 95et effectuons la conversion des nombres entiers en date "d"$"m"$-12*95-6h$x.

La raison pour laquelle nous + 1 ci-dessus est de soustraire le nombre de jours à partir du début de l'année prochaine pour obtenir le 31 décembre ou le 30 juin de l' année réelle , à savoir 1 ou 185 jours. Par conséquent, "DEFGHIJKSUV[^eh"représente les années avec une seconde intercalaire en décembre, et "DMNOQXYZ]lo"pour celles de juin. L'appariement-soustraction se fait via (a;b){x-y}'(c;d), où aet bsont les années qui seront soustraites par cet le dnombre de jours respectivement.

" "0:([]...)prépare les résultats pour nous donner la mise en forme correcte, avec une petite mise en garde qu'un en-tête de colonne sera généré. 1_supprime cet en-tête et applique finalement ascpour obtenir la commande correcte.

edit : 're-base' pour soustraire 95 ans au lieu de 100 (sauver 1 caractère).

edit 2 : réordonner le positionnement des opérandes à l'intérieur de la fonction de conversion des nombres entiers en date.

hjk
la source
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"

Vous pouvez jouer avec elle sur repl.it .

Edit: Complètement battu! Les réponses de compression sont incroyablement courtes.

sudo rm -rf slash
la source
Étonnamment, ma réponse PHP est plus courte, utilisant un algorithme similaire. Je me suis toujours attendu à ce que Python soit plus compact. Peut-être pourriez-vous jouer au golf un peu plus?
Voitcus du
Je regarderai. Je pense que le meilleur itinéraire est la compression, et d'autres l'ont déjà fait
sudo rm -rf slash
0

PHP, 164 octets

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

Ceci n'est qu'une modification de l'idée de @ Voitcus

pranzer
la source
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))

Quelques aperçus

Fondamentalement, d(x)décompresse un vecteur de 3 entiers à partir d'un seul entier à 2 chiffres. d(x)est construit comme la fonction inverse (sur les heures de 26 secondes bissextiles) de c(v), qui à son tour est une fonction de compression qui transforme un triplet tel que (1998,12,31) en un nombre comme 85. Pour dériver la liste [20 , 21 ... 28,58] J'ai conçu un autre algorithme pour vérifier que la fonction de compression est bijective sur le domaine. Autrement dit, je me suis assuré que le programme suivant ne produit pas de doublons, et j'ai utilisé sa sortie comme liste du programme ci-dessus.

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 fonction de compression a c(v)été conçue pour être bijective en utilisant un schéma très simple. Prenons un exemple (1998,12,31).

  • L'expression (v [0]% 10) * 10 sélectionne les unités de l'année (par exemple 1 9 9 8 -> 8) et en fait le dixième chiffre de la sortie (maintenant x = 80).
  • Il n'y a qu'une combinaison de deux mois-jours dans laquelle se produit la seconde intercalaire, j'ai donc décidé d'utiliser le composant jour pour distinguer le cas 06,30 du cas 12,31. L'expression v [2]% 30 est 0 si le jour est 30, et 1 si le jour est 31. Dans notre exemple, nous ajoutons 1 à x (donc, maintenant x = 81).
  • Enfin, j'ai observé que ce puzzle ne concerne que 5 décennies; par conséquent, si je mappe la première décennie (les années 70) à 0 et la dernière décennie (les années 2010) à 4, je peux faire des trucs sympas. Plus précisément, si au lieu de mapper à 0,1,2,3,4, je mappe à 0,2,4,6,8, je peux ajouter cette valeur aux unités de x, qui, en raison de la règle précédente, est soit 0 soit 1. Donc, à la fin, nous avons aussi que cette dernière étape ne visse pas la bijection, et nous obtenons que les unités d'un cas 06,30 sont l'une de 0,2,4,6,8 et que les unités d'un 12,31 cas sont l'un des 1,3,5,7,9. Par conséquent, la bijection est évidente. Dans notre exemple, 1998 est dans la troisième décennie (70s-> 0, 80s-> 1, 90s-> 2) donc nous ajoutons 2 * 2 = 4. On obtient donc x = 85.

J'ai écrit le programme pour vérifier que cela est vrai, puis je l'ai défini d(x)comme l'inverse de c(v). Dans notre exemple, c ((1998,12,31)) est 85 et d (85) s'imprime correctement 1998-12-31 23:59:60.

damix911
la source
1
Retirez q=x%10et remplacez qavec x%10partout. C'est plus court. Je donne également une description utile de quelques golf supplémentaires sur votre programme ici . Je recommande de consulter la page Conseils pour jouer au golf en Python .
mbomb007
Il s'agit de code-golf , vous devriez donc essayer de raccourcir la longueur de votre code de toutes les manières possibles.
mbomb007
-1

gzip, 114 octets

Hexdump:

1f8b080853f9975502006c006dd04b0a80300c84e1bde01dbc40218fa6697aff8309e2a6fa6f3f86cc10adb426a3b95ce62b6a0d398f07d59aeb8e4ed80983701026e1242cc0a9307e1aa11306615211b59710527b3961270cba9994fc7fc944829092faeedc313e7803993cfafb20020000

Créez un fichier avec les octets décrits ci-dessus.

Extraire en utilisant gunzip ou un autre programme de décompression pour obtenir un nouveau fichier nommé "l". Ce fichier contient la sortie souhaitée.

Stef Heyenrath
la source