128 років? Гіпотетична реформа високосного року


23

Сонячний рік становить 365 днів, 5 годин, 48 хвилин, 45 секунд і 138 мілісекунд, згідно з цим відео . З чинним григоріанським календарем правила високосних років такі:

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

На жаль, цей метод відключається один день кожні 3216 років.

Одним з можливих методів реформування календаря є наступне правило:

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

Це має перевагу в тому, що ми не вимагаємо від нас знову міняти календарі ще 625 000 років, дарувати чи брати.

Скажімо, весь світ вирішує, що, починаючи з цього часу, ми використовуємо цю систему кожного четвертого року - це високосний рік, крім кожного 128-го року, змінюючи наші календарі так:

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

Як це вплине на алгоритми нашого дня тижня?

Змагання

  • З огляду на дату від 2000 до 100000 року, знайдіть день тижня за цим новим календарем.
  • Будь-який формат введення та виводу дозволений, якщо ви чітко вказали, які формати ви використовуєте.
  • Це кодовий гольф, тому постарайтеся зробити свої рішення максимально гофрованими!

Тестові справи

"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

Пропозиції та відгуки щодо виклику вітаються. Успіхів і хорошого гольфу!


Для тестового випадку №4 ви маєте на увазі 1-індексований, так? Інакше на цьому тижні повинно бути 8 днів.
Себастьян

Крім того, ви кажете "хороший гольф", так це виклик # код-гольф? Якщо так, введіть критерії виграшу (наприклад, найменша кількість байтів / символів) і додайте їх як тег.
Себастьян

@Sebastian Ви маєте рацію в обох аспектах. Я вже редагував виклик. Дякуємо за відгук
Sherlock9

1
Читаючи заголовок, я безперечно хоч із відео Метта Паркера. Приємно бачити, що це також пов'язано в потоці: D
PattuX

1
Просто візьміть стандартні бібліотеки денного тижня і відповідно змініть глобальні константи, правда? ;)
Wildcard

Відповіді:


8

C (gcc) , 60 байт

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

Спробуйте в Інтернеті!

Проста модифікація методу Сакамото . Приймає введення як цілі аргументи в порядку month, day, yearі виводить число дня (0-індексується в неділю).


Що робить "-bed=pen+mad."частина?
ericw31415

@ ericw31415 Він припадає на тривалість кожного місяця в днях, і просто задля появи він зміщується вгору кратними 7, а не символами на парадках (31, 28 ...).
notjagan

Правильно, я забув, що charвсе ще являє собою число, тож ви можете робити mod 7безпосередньо.
ericw31415

6

Мова Вольфрама (Mathematica) , 57 55 53 байт

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

Спробуйте в Інтернеті!

Виконує три входи: рік, місяць та день у такому порядку. Наприклад, якщо ви збережете вищевказану функцію як fun, тоді fun[2048,2,28]вам повідомляється день тижня 28 лютого 2048 року.

Як це працює

Формула m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28]перетворює рік в еквівалентний рік (рік з абсолютно однаковими днями тижня) між 6 н. Е. І 33 н. Е. Для цього віднімаємо зсув і потім беремо рік моди 28; але зміщення змінюється кожні 128 років, і для років, що ділиться на 128, ми повинні здійснити подальше коригування, оскільки еквівалентний рік не повинен бути високосним.

У будь-якому разі, як тільки це буде зроблено, ми шукаємо місяць і день у тому рівноцінному році, використовуючи вбудований DayName.



3

JavaScript, 65 59 байт

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

Використовує метод Сакамото. Дає0=Sunday, 1=Monday, 2=Tuesday...

-2 байти завдяки Міші Лаврову
-4 байти завдяки Арнольду


1
Я думаю, що ~~yможна просто змінити на y. Ви не збираєтесь отримувати частковий рік у вхідних даних, правда? Але я визнаю, що не вільно володію JavaScript.
Міша Лавров

2
Як щодо +y+(y>>2)-(y>>7)?
Арнольд

@MishaLavrov Так, це правда. Чомусь я вирішив, що мені все слід.
ericw31415

2

Власне , 37 байт

Це порт модифікації notjagan в частині алгоритму Сакамото , але з декількома трюками стеки на основі , як описано нижче. Формат вводу є day, year, month. Формат виводу є 0-indexed with Sunday as 0. Пропозиції з гольфу вітаються! Спробуйте в Інтернеті!

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

Пояснення

                     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

2

Желе , 32 31 30 28 байт

Інший порту модифікації notjagan в частині алгоритму Сакамото , але з числом базових 250 замість 032503514624(не потрібен додатковий , 0тому що Желе 1-проіндексовані). Формат вводу єmonth, year, day . Формат виводу є 0-based with Sunday as 0. Пропозиція щодо гольфу дуже вітається, оскільки спосіб, яким посилання було важко влаштувати, і, можливо, все ще може бути гофрованим. Спробуйте в Інтернеті!

Редагувати: -1 байт від використання бітового зсуву замість цілого поділу. -1 байт від перестановки початку та формату введення. -2 байти завдяки Еріку Попелу та Експертному спільному обробленню.

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

Пояснення

         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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.