128年?假想的leap年改革


23

根据此视频,太阳年是365天,5小时,48分钟,45秒和138毫秒。在当前的公历中,leap年的规则如下:

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年的日历,无论是给予还是接受。

假设全世界都决定,从现在开始,我们每隔四年使用此系统是一个except年,但第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天。
塞巴斯蒂安

另外,您说的是“打高尔夫好”,那么这是#code-Golf挑战吗?如果是这样,则输入获胜标准(例如,最低字节数/字符),并将其添加为标签。
塞巴斯蒂安

@塞巴斯蒂安在两个方面你都是正确的。我已经编辑了挑战。感谢您的反馈
Sherlock9

1
在阅读标题时,我会毫不动摇地看一下Matt Parker的视频。很高兴看到它也与线程链接在一起:D
PattuX

1
只需采用标准的“星期几”库并相应地修改全局常量,对吗?;)
通配符

Answers:


8

C(gcc),60个字节

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

在线尝试!

Sakamoto方法的简单修改。将输入作为顺序中的整数参数month, day, year,并输出日期(星期几为0索引)。


"-bed=pen+mad."零件做什么?
ericw31415

@ ericw31415它占每个月的天数,只是为了外观起见,它向上移动7的倍数,而不是普通字符(31,28 ...)。
notjagan

是的,我忘记了char仍然代表数字,因此您可以mod 7直接执行。
ericw31415

6

Wolfram语言(Mathematica)57 55 53字节

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

在线尝试!

依次输入三个输入:年,月和日。例如,如果将上面的函数另存为fun,则fun[2048,2,28]告诉您2048年2月28日的星期几。

怎么运行的

该公式m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28]将年转换为公元6年到公元33年之间的等效年份(一年中的星期几完全相同)。为此,我们减去一个偏移量,然后采用year mod 28;但是偏移量是每128年更改一次,并且对于可被128整除的年份,我们必须进行进一步调整,因为等效年份不应该是a年。

无论如何,一旦完成,我们就会使用内置查询来查找当年的月份和日期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个字节感谢Misha Lavrov
-4个字节感谢Arnauld


1
我认为~~y可以更改为y。您不会在输入中得到小数部分,对吗?但我承认我不太会使用JavaScript。
米莎·拉夫罗夫

2
怎么+y+(y>>2)-(y>>7)
Arnauld

@MishaLavrov是的,是的。出于某种原因,我决定将所有内容都设为地板。
ericw31415

2

实际上,37个字节

这是notjaganSakamoto算法的修改的一部分,但是具有一些基于堆栈的技巧,如下所述。输入格式为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字节

notjaganSakamoto算法的修改的另一个端口,但是用base-250代替0325035146240因为Jelly是1索引的,所以不需要多余的数字)。输入格式为month, year, day。输出格式为0-based with Sunday as 0。高尔夫建议非常受欢迎,因为链接很难安排,而且仍然可以打高尔夫球。在线尝试!

编辑: -1字节从使用位移而不是整数除法。重新排列开头和输入格式后为-1个字节。-2个字节,感谢Outgolfer的Erik和caird的coheringaahing。

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.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.