128 ans? Réforme hypothétique des années bissextiles

23

L'année solaire est de 365 jours, 5 heures, 48 ​​minutes, 45 secondes et 138 millisecondes, selon cette vidéo . Avec le calendrier grégorien actuel, les règles pour les années bissextiles sont les suivantes:

if      year is divisible by 400, LEAP YEAR
else if year is divisible by 100, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Malheureusement, cette méthode est désactivée d'un jour tous les 3216 ans.

Une méthode possible pour réformer le calendrier est la règle suivante:

if      year is divisible by 128, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Cela a l'avantage de ne pas nous obliger à changer à nouveau nos calendriers pendant encore 625 000 ans, à donner ou à prendre.

Supposons que le monde entier décide que, à partir de maintenant, nous utilisons ce système de chaque quatrième année est une année bissextile sauf tous les 128 ans, en changeant nos calendriers comme suit:

YEAR    GREGORIAN    128-YEAR
2044    LEAP         LEAP
2048    LEAP         COMMON
2052    LEAP         LEAP
 ...
2096    LEAP         LEAP
2100    COMMON       LEAP
2104    LEAP         LEAP
 ...
2296    LEAP         LEAP
2300    COMMON       LEAP
2304    LEAP         COMMON
2308    LEAP         LEAP

Comment cela affecterait-il nos algorithmes de jour de la semaine?

Le défi

  • Étant donné une date de l'année 2000 à l'année 100000, retrouvez le jour de la semaine sous ce nouveau calendrier.
  • Tout format d'entrée et de sortie est autorisé tant que vous spécifiez clairement les formats que vous utilisez.
  • C'est du golf de code alors essayez de rendre vos solutions aussi golfiques que possible!

Cas de test

"28 February 2048" -> "Friday"
"March 1, 2048"    -> "Sat"
(2100, 2, 29)      -> 0           # 0-indexed with Sunday as 0
"2100-02-29"       -> 7           # 1-indexed with Sunday as 7
"28 Feb. 2176"     -> "Wednesday"
"1-Mar-2176"       -> "Th"
"28/02/100000"     -> "F"         # DD/MM/YYYYYY
"Feb. 29, 100000"  -> 6           # 1-indexed with Sunday as 7
"03/01/100000"     -> 1          # MM/DD/YYYYYY and 1-indexed with Sunday as 1

Les suggestions et commentaires sur le défi sont les bienvenus. Bonne chance et bon golf!

Sherlock9
la source
Pour le cas de test n ° 4, vous voulez dire 1 indexé, non? Sinon, il devrait y avoir 8 jours au cours de cette semaine.
Sebastian
De plus, vous dites "bon golf", est-ce donc un défi de # code-golf? Si tel est le cas, indiquez les critères gagnants (par exemple, le plus petit nombre d'octets / caractères) et ajoutez-le en tant que balise.
Sebastian
@Sebastian Vous avez raison sur les deux points. J'ai déjà édité le défi. Merci pour vos commentaires
Sherlock9
1
En lisant le titre, j'ai tout de suite pensé à la vidéo de Matt Parker. Ravi de le voir lié dans le fil aussi: D
PattuX
1
Prenez simplement les bibliothèques standard du jour de la semaine et modifiez les constantes globales en conséquence, non? ;)
Wildcard

Réponses:

8

C (gcc) , 60 octets

f(m,d,y){y-=m<3;return(y+y/4-y/128+"-bed=pen+mad."[m]+d)%7;}

Essayez-le en ligne!

Modification simple de la méthode de Sakamoto . Prend les entrées sous forme d'arguments entiers dans l'ordre month, day, yearet affiche le numéro du jour (indexé 0 le dimanche).

notjagan
la source
Que fait la "-bed=pen+mad."pièce?
ericw31415
@ ericw31415 Il représente la longueur de chaque mois en jours, et simplement pour des raisons d'apparence, il est décalé vers le haut par multiples de 7 au lieu d'être des caractères en ordinaux (31, 28 ...).
notjagan
Bon, j'ai oublié que cela charreprésente toujours un nombre, donc vous pouvez le faire mod 7directement.
ericw31415
6

Wolfram Language (Mathematica) , 57 55 53 octets

DayName@{m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28],##2}&

Essayez-le en ligne!

Prend trois entrées: l'année, le mois et le jour, dans cet ordre. Par exemple, si vous enregistrez la fonction ci-dessus sous fun, fun[2048,2,28]vous indique alors le jour de la semaine du 28 février 2048.

Comment ça marche

La formule m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28]convertit l'année en une année équivalente (une année avec exactement les mêmes jours de la semaine) entre 6 AD et 33 AD. Pour ce faire, on soustrait un offset puis on prend l'année mod 28; mais la compensation change tous les 128 ans, et pour les années divisibles par 128, nous devons procéder à un nouvel ajustement car l'année équivalente ne devrait pas être une année bissextile.

Quoi qu'il en soit, une fois cela fait, nous recherchons le mois et le jour de cette année équivalente à l'aide de la fonction intégrée DayName.

Misha Lavrov
la source
3

Python 2 , 67 octets

def f(m,d,y):y-=m<3;return(y+y/4-y/128+int("0032503514624"[m])+d)%7

Essayez-le en ligne!

int("..."[m])peut être remplacé par ord("-bed=pen+mad."[m]).

M. Xcoder
la source
3

JavaScript, 65 59 octets

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+y+(y>>2)-(y>>7)+d)%7)

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+~~y+~~(y/4)-~~(y/128)+d)%7)

Utilise la méthode de Sakamoto. Donne0=Sunday, 1=Monday, 2=Tuesday...

-2 octets grâce à Misha Lavrov
-4 octets grâce à Arnauld

ericw31415
la source
1
Je pense que ça ~~ypeut être changé en y. Vous n'obtiendrez pas une fraction d'année en entrée, non? Mais j'avoue que je ne parle pas couramment JavaScript.
Misha Lavrov
2
Et alors +y+(y>>2)-(y>>7)?
Arnauld
@MishaLavrov Oui, c'est vrai. Pour une raison quelconque, j'ai décidé que je devrais tout mettre au sol.
ericw31415
2

En fait , 37 octets

Il s'agit d'un portage de la modification de notjagan de l'algorithme de Sakamoto , mais avec quelques astuces basées sur la pile comme décrit ci-dessous. Le format d'entrée est day, year, month. Le format de sortie est 0-indexed with Sunday as 0. Suggestions de golf bienvenues! Essayez-le en ligne!

;"0032503514624"Ei)3>±+;¼L;¼¼½L±kΣ7@%

Explication

                     Implicit input: day, year, month (month is at TOS)
;"0032503514624"Ei)  Get the month code, convert to float, rotate to bottom of the stack
3>±+                 If 3>month, add -1 to year
;¼L                  Push floor(year/4) to stack
;¼¼½L±               Push floor(year/4) and append -floor(year/128) to stack.
kΣ                   Wrap the stack (y/128, y/4, y, month_code, d) in a list and sum
7@%                  Get the sum modulo 7
                     Implicit return
Sherlock9
la source
2

Gelée , 32 31 30 28 octets

Un autre port de la modification par notjagan de l'algorithme de Sakamoto mais avec un nombre de base 250 à la place de 032503514624(pas besoin d'extra 0car Jelly est indexé 1). Le format d'entrée est month, year, day. Le format de sortie est 0-based with Sunday as 0. Les suggestions de golf sont les bienvenues car la façon dont les liens étaient difficiles à organiser et peut encore être golfable. Essayez-le en ligne!

Modifier: -1 octet en utilisant le décalage de bits au lieu de la division entière. -1 octet de réarrangement du début et du format d'entrée. -2 octets grâce à Erik l'Outgolfer et le caird coinheringaahing.

3>_@µæ»7,2I+µ“Ṿ⁵Ḥ9{’D³ị+⁵+%7

Explication

         Three arguments: month, year, day
3>_@     Subtract (month<3) from year. Call it y.
µ        Start a new monadic chain.
æ»7,2    Bit shift y by both 7 and 2 (equivalent to integer division by 128 and by 4).
I+       y + y/4 - y/128
µ        Start a new monadic chain.
“Ṿ⁵Ḥ9{’  The number 732573514624 in base 250.
D        The list [7, 3, 2, 5, 7, 3, 5, 1, 4, 6, 2, 4].
³ị       Get the month code from the list (1-based indexing).
+⁵+      Add y, our month code, and day together.
%7       Modulus 7.
Sherlock9
la source
29 octets
caird coinheringaahing