Sommes-nous alors encore?

22

Je suis un voyageur du temps et je suis obsédé par le passage du temps. J'aime particulièrement les moments où les aiguilles de l'horloge passent à 12, ou quand je peux passer à la page suivante de mon calendrier, ou quand tout le monde crie "Bonne année!"

Veuillez m'écrire un programme pour me montrer à quelle distance je suis du dernier moment à l'autre, sous la forme d'une barre de progression. Par exemple, si je lui dis qu'il est 09h12, il devrait imprimer ceci:

09:00 ####---------------- 10:00

Si je lui dis que le mois est mai 1982, il devrait imprimer ceci:

1982-01 #######------------- 1983-01

Ai-je mentionné que je suis un voyageur du temps? Je voyage n'importe où, de la première milliseconde de 0 à la dernière milliseconde de 9999 AD, donc le programme doit gérer n'importe quelle date et heure dans cette plage.

Contribution

  • L'entrée sera dans l'un des formats suivants:

    • YYYY-MM-DDThh:mm:ss.sss
    • YYYY-MM-DDThh:mm:ss
    • YYYY-MM-DDThh:mm
    • YYYY-MM-DDThh
    • YYYY-MM-DD
    • YYYY-MM

    Ce sont les seuls formats à gérer. Chaque partie aura exactement le nombre de chiffres indiqué, ce qui signifie que les fractions de seconde peuvent avoir des zéros de fin (par exemple .120, jamais .12). Le Test une lettre littérale "T" délimitant la date de l'heure. Les heures sont sur une horloge de 24 heures.

  • Les mois et les jours sont basés sur 1 (voir ci-dessous).

  • Les entrées non valides et hors plage n'ont pas besoin d'être gérées.

  • À la discrétion du programmeur, l'entrée peut avoir une seule nouvelle ligne de fin.

Barre de progression mathématique

Le programme concerne les unités les moins et les moins significatives de l'entrée donnée. Par exemple, si l'entrée a une précision au niveau du jour (par exemple 2016-12-14), la barre de progression indiquera quelle proportion des jours du mois d'entrée s'est écoulée par rapport à ce qui reste.

La barre de progression aura 20 unités (caractères) et la proportion représentée sera arrondie à l'incrément le plus proche de 120 . Par exemple, étant donné 2016-12-14T12:28, la barre de progression affichera Round ( 2860 × 20) = 9 des 20 unités "remplies".

Mois et jours basés sur 1

Bien que le jour du 1er décembre (par exemple) soit 01entré 2016-12-01, aux fins du calcul, il s'agit du 0e jour du mois, car les unités tronquées impliquent la 0e milliseconde de la 0e minute de la 0e heure du jour. En d'autres termes, 2016-12-01c'est 031 du chemin jusqu'en décembre et 2016-12-02est 131 , et ainsi de suite.

De même, 2016-01c'est la 0e milliseconde du 0e jour de janvier, donc dans les calculs c'est 012 , ce qui signifie 2016-12est 1112 .

Oui, cela signifie que des mois et des jours ne rempliront jamais complètement la barre de progression.

Durée et mois bissextiles différents

Chaque mois a un nombre de jours différent et la sortie doit refléter cela, y compris les années bissextiles. La barre de progression du 6 février 2017 sera différente de la barre de progression du 6 février 2016 (ou du 6 janvier des deux années).

Divers

  • Les voyageurs du temps utilisent le calendrier grégorien proleptique . TL; DR: Pas de cas particulier comme les jours manquants en 1752 . L'entrée inclura les dates de l'année 0 après JC
  • Les voyageurs temporels ignorent l'heure d'été.
  • Le programme n'est pas tenu de prendre en compte les secondes intercalaires, mais il le peut.

Sortie

Le programme (ou la fonction) doit imprimer (ou renvoyer sous forme de chaîne) une barre de progression de 20 caractères orientée horizontalement qui est "remplie" pour le temps écoulé et "ouverte" pour le temps restant. Il doit "remplir" de gauche à droite.

La barre de progression doit avoir une étiquette à sa gauche indiquant le début de la période comptée et une autre à sa droite indiquant le début de la période suivante, dans le même format que l'entrée (mais affichant seulement deux unités de précision). Pour notre exemple, 2016-12-14une sortie valide serait:

12-01 #########----------- 01-01

Voici les formats d'étiquette valides pour chacune des périodes possibles:

  • Mois: YYYY-MM
  • Journées: MM-DD
  • Heures: DDThh
  • Minutes: hh:mm
  • Secondes: mm:ss
  • Millisecondes: ss.sss

Aucune unité supplémentaire ne peut être incluse dans les étiquettes et aucune ne peut être omise.

Notes de sortie

  • Les unités "remplies" de la barre de progression seront représentées par un #caractère. Les unités "ouvertes" seront représentées par- .
  • Il doit y avoir exactement un espace entre la barre de progression et chaque étiquette.
  • Les espaces de début ou de fin et / ou une seule nouvelle ligne de fin sont autorisés.

Gagnant

C'est du . Le code le plus court en octets gagne. Des règles standard s'appliquent. Failles standard interdites.

Exemples

Input                      Output
-----------------------    -------------------------------------
2016-12-12T12:17           12:00 ######-------------- 13:00
2016-12-12                 12-01 #######------------- 01-01
0000-01-01T00:00:00.000    00.000 -------------------- 01.000
0000-01-01T00:00           00:00 -------------------- 01:00
1899-12-31T23              31T00 ###################- 01T00
1899-12-31                 12-01 ###################- 01-01
1899-12                    1899-01 ##################-- 1900-01
1982-05-15T17:15           17:00 #####--------------- 18:00
1982-05-15T17              15T00 ##############------ 16T00
1982-05                    1982-01 #######------------- 1983-01
9999-12-31T23:59:59.999    59.000 #################### 00.000
9999-12                    9999-01 ##################-- 10000-01
2000-01-06                 01-01 ###----------------- 02-01
2000-02-06                 02-01 ###----------------- 03-01
2001-02-06                 02-01 ####---------------- 03-01
1742-09-10                 09-01 ######-------------- 10-01
Jordan
la source
4
Faut-il se soucier des secondes intercalaires?
Riley
@Riley Bonne question. No.
Jordan
2
Je suppose que l'heure d'été est ignorée, car il n'y a pas de formulaire standardisé?
CAD97
3
@ CAD97 Bonne question. Vous avez raison. L'heure d'été complique vraiment les choses pour les voyageurs du temps, nous l'ignorons donc.
Jordan
L'exemple "1899-12-31T23" n'est pas valide selon la liste de formats d'entrée fournie, la même chose pour "1982-05-15T17". Veuillez vérifier vos données de test.
zeppelin

Réponses:

4

JavaScript, 282 octets

(x,v=x.split(/\D/g),l=v.length-2,[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),t=(v[l+1]-b)/d*20+.5|0,n=v[l],o=((n|0)+1)%a,r=l?('0'+o).slice(-2):o)=>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

Réussit tous les tests

(
x,
v=x.split(/\D/g),
l=v.length-2,
[a,b,c,d]=("10e5,01,-,12,01,-,"+new Date(v[0],v[1],0).getDate()+",00,T,24,00,:,60,00,:,60,000,.,1000").split`,`.slice(l*3,l*3+4),
t=(v[l+1]-b)/d*20+.5|0,
n=v[l],
o=((n|0)+1)%a,
r=l?('0'+o).slice(-2):o
) =>n+c+b+' '+'#'.repeat(t)+'-'.repeat(20-t)+' '+r+c+b

La fonction de test n'imprime rien pour réussite, les valeurs pour échec.

function test(value,expected){
    if (f(value)!=expected)
    {
        console.log(value);
        console.log(f(value));
        console.log(expected);
     }
}

Les cas de test:

test('2016-12-12T12:17','12:00 ######-------------- 13:00')                 ;
test('2016-12-12','12-01 #######------------- 01-01')                       ;
test('0000-01-01T00:00:00.000','00.000 -------------------- 01.000')        ;
test('0000-01-01T00:00','00:00 -------------------- 01:00')                 ;
test('1899-12-31T23','31T00 ###################- 01T00')                    ;
test('1899-12-31','12-01 ###################- 01-01')                       ;
test('1899-12','1899-01 ##################-- 1900-01')                      ;
test('1982-05-15T17:15','17:00 #####--------------- 18:00')                 ;
test('1982-05-15T17','15T00 ##############------ 16T00')                    ;
test('1982-05','1982-01 #######------------- 1983-01')                      ;
test('9999-12-31T23:59:59.999','59.000 #################### 00.000')        ;
test('9999-12','9999-01 ##################-- 10000-01')                     ;
test('2000-01-06','01-01 ###----------------- 02-01')                       ;
test('2000-02-06','02-01 ###----------------- 03-01')                       ;
test('2001-02-06','02-01 ####---------------- 03-01')                       ;
test('1742-09-10','09-01 ######-------------- 10-01')                       ;
Grax32
la source
2
J'ai dû apprendre une nouvelle langue pour compléter cette version ... c'est très concis!
rexroni
3

Pyth, 213 octets

Mon premier code en pyth! Voir:

+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

Mon code pyth est basé étroitement sur ma réponse python précédente. Voici la version non golfée avec commentaires:

"K is the input, as a list of numbers"
Kr:w"[-T:.]"d7
"Y=year"
=YhK
"k=month"
=k@K1
"H = a list of denominators"
=H[0 ^9T 12 ?q2k+28+q0%Y4-q0%Y400q0%Y100 +30%+k/k8 2 24 60 60 999)
"J is the second-to-last number of the input"
J@K_2
"b is the +1 starting point for months and days"
=b<lK4
"G is the number of hashtags in the statusbar"
=Gs+*[email protected]
"N is the formatted string"
=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lK3 *2lK
+%hNJ+@N1+%eNb+d+*\#G+*\--20G+d+%hN%+J1@H-lK1+@N1%eNb

Il est facile de tester plusieurs valeurs en faisant la boucle de code et en ajoutant une impression de nouvelle ligne à la fin:

Wp+%h=N:[d"%.4d"\-=Z"%.2d"\-Z\TZ\:Z\:Z\."%.3d")-*2lKr:w"[-T:.]"d7 3*2lKJ@K_2+@N1+%eN=b<lK4+d+*\#=Gs+*20c-eKb@=H[0^9T12?q2=k@K1+28+q0%=YhK4-q0%Y400q0%Y100+30%+k/k8 2 24 60 60 999)lK.5+*\--20G+d+%hN%+J1@H-lK1+@N1+%eNb"\n"

Ensuite , je courais cat testinput | pyth code.pyth > outputet diff output testoutput Ou essayer en ligne .

rexroni
la source
2

Python 2, 371 octets

Ce défi était étonnamment difficile! Il semblait que j'allais être un peu moins de 300 jusqu'à ce que je travaille sur le formatage de la chaîne de sortie.

Le genre de partie cool est que ma réponse n'utilise aucun package de date:

import re
s=raw_input()
S=[int(i)for i in re.sub('[-T:.]',' ',s).split()]
l=len(S)
y,m=S[:2]
d=[0,20<<9,12,28+(y%4==0!=y%100)+(y%400==0)if m==2else 30+(m+m/8)%2,24,60,60,999]
a,n=S[-2:]
b=1-(1if l>3else 0)
h=int(20.*(n-b)/d[l]+.5)
x,y,z='- %.4d - %.2d - %.2d T %.2d : %.2d : %.2d . %.3d'.split()[l*2-3:l*2]
print x%a+y+z%b+' '+'#'*h+'-'*(20-h)+' '+x%((a+1)%d[l-1])+y+z%b
rexroni
la source