Quel est le jour aujourd'hui (ou à d'autres dates)?


12

Tâche

Écrivez un programme ou une fonction qui calcule un nom de jour d'une semaine que l'utilisateur saisit.

Entrée sortie

L' entrée est une chaîne de caractères, YYYYMMDD.

Exemple de valeurs d'entrée:

20110617: 17 juin 2011
19040229: 29 février 1904
06661225: 25 décembre 666
00000101: 1er janvier 0
99991231: 31 décembre 9999

Vous pouvez supposer que toutes les entrées sont valides. Notez que l' année zéro est valide.

La sortie est un entier entre 0et 6. Chaque entier représente un nom de jour de la semaine. Vous pouvez décider librement quel entier représente un nom de jour de la semaine, comme celui-ci

0: lundi
1: mardi
2: mercredi
...
6: dimanche

(dans l'ordre) ou celui-ci

0: lundi
1: mercredi
2: dimanche
...
6: samedi

(pas dans l'ordre).

Cas de test

Entrée Sortie hebdomadaire ([0..6 -> lundi..dimanche] est utilisé dans cet exemple.)

20110617 vendredi 4
19500101 dimanche 6
22220202 samedi 5
19000228 mercredi 2
19000301 jeudi 3
19450815 mercredi 2
19040229 lundi 0
19040301 mardi 1
17760704 jeudi 3
20000228 lundi 0
20000229 mardi 1
20000301 mercredi 2
20121223 dimanche 6
00000401 samedi 5
66660606 mercredi 2
59161021 samedi 5

Restriction

Vous ne devez utiliser aucun type de fonction / classe / ... lié à l'horodatage ou à la date, comme la Dateclasse dans Java/ JavaScript/ ActionScriptou la getdatefonction dans PHP.

Vous devriez utiliser le calendrier grégorien , qui est utilisé par de nombreuses personnes maintenant.

Bien sûr, le code le plus court gagne. Si deux codes ont la même longueur, alors le code avec les votes les plus élevés l'emporte.

(En raison: lorsqu'il y a plus de 5 codes qui ont plus de (ou égal) +1votes.)


Aujourd'hui? Pourquoi, le jour de Noël!
Joey Adams

3
Solution Optimiste écrit en Bash (6 caractères): echo 4.
trueeality

1
@trutheality Non, je ne voulais pas dire cela. Ce que je voulais, c'est un code qui imprime / renvoie le jour de la semaine d'une date tapée par quelqu'un, pas seulement le jour de la semaine d'aujourd'hui.
JiminP

Oh, je sais. C'est ce que fait celui-ci.
trueeality

C'est vrai au moins 14% du temps!
Draco18 ne font plus confiance au SE

Réponses:


2

Ruby, 95 92 caractères

Mise en œuvre simple et simple de Ruby avec 0: lundi, ...

p ((y=(d=gets.to_i)/(k=100)/k-((m=d/k%k)<3?1:0))+y/4-y/k+y/400+"squsptrotqro"[-m].ord+d%k)%7

4

PHP - 101 97 103 125 caractères

  • Algorithme de Sakamoto
  • 0 = dimanche

Code

<?php fscanf(STDIN,"%4d%2d%2d",$y,$m,$d);@$a=a032503514624;$y-=$m<3;$z=$y+1;echo($y+$y/4%$z-$y/100%$z+$y/400%$z+$a[$m]+$d)%7;

Remarque

Malheureusement, en raison du typage dynamique et faible de PHP, l'algorithme Sakamoto ne fonctionne pas correctement sans couvrir explicitement chaque opération de division.


Pouvez-vous s'il vous plaît tester à nouveau? Depuis quelques années cela me donne des résultats différents (par exemple testcase 17760704 donne mardi au lieu de mercredi).
Howard

@Howard, c'est très étrange; pour 17760704, je reçois mercredi. J'obtiens cependant d'autres incohérences, que je ne peux pas expliquer, par exemple 19040229 revient mardi. Je ne sais pas ce qui pourrait causer cela. J'obtiens les mêmes résultats lorsque je développe l'algorithme y+y/4-y/100+y/400.
rintaun

Je peux voir cela se produire avec 497 * y / 400: y=4dans ce cas, renvoie 4, au lieu des 5 corrects y+y/4+y/100+y/400(où seuls les deux premiers termes entrent en jeu). C'est ce qui afflige ma réponse JavaScript. Est-il possible que des doubles soient créés au lieu des ints? (Mon PHP est trop faible pour le savoir.)
DocMax

@DocMax: Laisser l'expression développée a le même résultat (497y / 400 devrait être équivalent: y / 100 est soustrait et y / 400 ajouté à nouveau malgré tout). Je suppose que PHP coupe simplement tout après la décimale au lieu de l'arrondir. J'ai testé cela en arrondissant avant le modulo. Cela corrige deux des anomalies, mais 19040229 renvoie toujours le même résultat. D'autres idées?
rintaun

@rintaun je ne pense pas que ce soit l'arrondi. Ils sont fondamentalement différents. Prenons l'exemple d'en haut (y = 4): 497 * 4/400 = 1988/400 = 4 mais d'autre part 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . Les termes / 100 et / 400 prennent trop de poids dans votre calcul de sorte que le 2000 ne peut pas être atteint.
Howard

2

C - 129

main(y,m,d,s)
{
    scanf("%04d%02d%02d",&y,&m,&d);
    y-=s=86400;
    d+=y+"-addgbegcfadf"[m];
    m>2?y++:0;
    putchar(48+(d+y/4-y/100+y/400+s+s)%7);
}

Cela abuse de la façon dont la division arrondit vers zéro, au moins sur mon système (Linux x86).

La constante magique,, 86400sert à deux fins:

  • Soustrayez de l'année pour la rendre négative, sans affecter le jour de la semaine. Cela rend donc les divisions arrondies au lieu de baisser.
  • Décalez le numéro du jour pour que lundi soit 0.

Il se trouve également que c'est le nombre de secondes dans une journée.


Utilisez y+=m>2;au lieu de m>2?y++:0;et rasez quelques octets.
Plus clair

2

Javascript, 126 123 caractères

En utilisant l'algorithme de Sakamoto avec 0 = dimanche:

prompt().replace(/(....)(..)(..)/,function(_,y,m,d){y-=m<3;alert((+d+y-~(y/4)+~(y/100)-~(y/400)+ +".621462403513"[+m])%7)})

Je soupçonne que les divisions peuvent s'effondrer, mais pour l'instant je ne le vois pas.

Edit: Amélioration des divisions (pas besoin ~~quand vous le pouvez ~).


2

Python 2 , 83 116 113 113 109 octets

Implémente l'algorithme de Sakamoto . Suggestions de golf bienvenues. Essayez-le en ligne!

Edit: j'aurais dû corriger cela il y a longtemps. -6 octets à partir des suggestions de Jonathan Allan +2 octets pour réellement réparer le code.

def w(s):m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:]);return(y+y/4-y/100+y/400+int('032503514624'[m-1])+d)%7

L'entrée doit être une seule chaîne.
msh210

int('032503514624'[m-1])sauve 6
Jonathan Allan

0

Perl - 110 octets

Voici une solution à exécuter avec perl -p source.pl OU perl -pe 'here-is-code'.

s/((..)(..))(..)(..)/(1+3*$1+$2-2*($1%4+$2%4)-(2<$4?$4+(1&$4&&4-(8&$4)):(2^$4)+(!($3%4)-!-$3+!($2%4)))+$5)%7/e

Copiez-collez simplement les cas de test dans stdin.

Cela semble être le seul code sans variables, constantes de chaîne et divisions.


0

JavaScript (ES6), 73 octets (non concurrent)

d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)

Essayez-le

f=
d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)
o.innerText=f(i.value="59161021")
oninput=_=>i.value.length==8&&(o.innerText=f(i.value))
<input id=i type=number><pre id=o>


Pourquoi ne pas concurrencer?
programmer5000

@ programmer5000, vérifiez la date à laquelle le défi a été publié;)
Shaggy
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.