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

Предложения и отзывы о проблеме приветствуются. Удачи и хорошего гольфа!

Sherlock9
источник
Для теста № 4 вы имеете в виду 1-индексированный, верно? В противном случае на этой неделе должно быть 8 дней.
Себастьян
Кроме того, вы говорите «хороший гольф», так что, это проблема # code-golf? Если это так, укажите критерий выигрыша (например, минимальное количество байтов / символов) и добавьте его в качестве тега.
Себастьян
@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 в воскресенье).

notjagan
источник
Что делает "-bed=pen+mad."часть?
ericw31415
@ ericw31415 Он учитывает длину каждого месяца в днях, и просто ради удобства он сдвигается на 7 крат вместо того, чтобы быть символами на ординалах (31, 28 ...).
Notjagan
Хорошо, я забыл, что charвсе еще представляет число, так что вы можете сделать mod 7напрямую.
ericw31415
6

Wolfram Language (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 байта благодаря Арно

ericw31415
источник
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
Sherlock9
источник
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.
Sherlock9
источник
29 байт
caird coinheringaahing