今天是星期几(或其他日期)?


12

任务

编写一个程序或函数来计算用户输入的日期的星期几名称。

输入输出

输入是一个字符串,YYYYMMDD

输入值示例:

20110617:2011年6月17日
19040229:1904年2月29日
06661225:666年12月25日
00000101:1月1日,0
99991231:9999年12月31日

您可以假设所有输入均有效。请注意,零年有效。

输出是0和之间的整数6。每个整数代表星期几的名称。您可以自由决定哪个整数代表星期几的名称,像这样

0:星期一
1:星期二
2:星期三
...
6:星期日

(按顺序)或这一

0:星期一
1:星期三
2:周日
...
6:星期六

(顺序不对)。

测试用例

输入周日输出(在此示例中使用[0..6-> Monday..Sunday]。)

20110617星期五4
19500101星期日6
22220202星期六5
19000228星期三2
19000301星期四3
19450815星期三2
19040229星期一0
19040301星期二1
17760704星期四3
20000228星期一0
20000229星期二1
20000301星期三2
20121223星期日6
00000401星期六5
66660606星期三2
59161021星期六5

限制

不能使用任何类型的函数/类/ ......这些都与时间戳或日期,就像Date在课堂上Java/ JavaScript/ ActionScript,或getdate在功能上PHP

您应该使用Gregorian压延机,现在很多人都使用它。

当然,最短的代码胜出。如果两个代码的长度相同,则得票最多的代码将获胜。

(到期日:当有5个以上的代码具有超过(或相等的)+1票数时。)


今天?为什么,圣诞节!
乔伊·亚当斯

3
写在击(6个字节)乐观溶液:echo 4
真实性2011年

1
@trutheality不,我不是那个意思。我想要的是一个打印/返回某人键入日期的星期几的代码,而不仅仅是打印今天的星期几。
JiminP 2011年

哦,我知道。这就是这个。
真实性2011年

至少有14%的时间正确!
Draco18s不再信任SE

Answers:


2

Ruby,95个 92个字符

0:Monday的简单明了的ruby实现,...

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个字符

  • 坂本算法
  • 0 =星期日

<?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;

注意

不幸的是,由于PHP的动态,弱类型,Sakamoto算法在未明确限制每个除法运算的前提下无法正常运行。


你能再测试一次吗?多年来,它给了我不同的结果(例如,测试用例17760704的结果是星期二而不是星期三)。
霍华德

@霍华德,这很奇怪;我得到了17760704,星期三。但是,我确实有其他不一致之处,我无法解释,例如19040229周二返回。不知道是什么原因造成的。将算法扩展回时,我得到的结果相同y+y/4-y/100+y/400
rintaun 2011年

我可以看到它发生在497 * y / 400上:y=4在这种情况下,返回4,而不是正确的5 y+y/4+y/100+y/400(来自前两个术语才起作用)。那就是困扰我的JavaScript答案的地方。是否有可能创建双精度而不是整数?(我的PHP太弱了,不知道。)
DocMax 2011年

@DocMax:使表达式扩展具有相同的结果(497y / 400应该等效:无论如何都减去y / 100并再次添加y / 400)。我猜想PHP只是将小数点后的所有内容都切掉,而不是四舍五入。我通过在取模前取整对它进行了测试。这修复了两个异常,但是19040229仍返回相同的结果。还有其他想法吗?
rintaun 2011年

@rintaun我不认为这是四舍五入。它们根本不同。从上面的示例(y = 4):497 * 4/400 = 1988/400 = 4,但另一方面4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 。在您的计算中,术语/ 100和/ 400的权重太大,因此无法达到2000。
霍华德

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);
}

至少在我的系统(Linux x86)上,这种做法滥用了除法舍入为零的方式。

魔术常数,有86400两个作用:

  • 从年份中减去以使其为负数,而不会影响星期几。这样一来,划分将向上舍入而不是向下舍入。
  • 转移日期,使星期一将为0。

它也恰好是一天中的秒数。


使用y+=m>2;代替,m>2?y++:0;并剃掉一些字节。
清晰的

2

Javascript,126123个字符

使用Sakamoto的算法(0 =星期日):

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

我怀疑这些分裂可能会崩溃,但是现在我没有看到它。

编辑:改进了划分(~~仅在需要时才需要~)。


2

Python 2中83个 116 113 109字节

实现Sakamoto的算法。欢迎打高尔夫球。在线尝试!

编辑: 我应该已经解决了这个年龄。乔纳森·艾伦(Jonathan Allan)建议的-6个字节+ 2个字节可以实际修复代码。

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

输入应为单个字符串。
msh210

int('032503514624'[m-1])保存6
乔纳森·艾伦

0

Perl-110字节

这是要与perl -p source.pl或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

只需将测试用例复制粘贴到stdin。

这似乎是唯一没有变量,字符串常量和除法的代码。


0

JavaScript(ES6),73个字节(不竞争)

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

尝试一下

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>


为什么不竞争?
程序员

@ programmer5000,检查挑战发布的日期;)
Shaggy
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.