วันนี้เป็นวันอะไร (หรือวันอื่น ๆ )?


12

งาน

เขียนโปรแกรมหรือฟังก์ชันที่คำนวณชื่อสัปดาห์ของวันที่ซึ่งผู้ใช้ป้อน

อินพุตและเอาต์พุต

อินพุตเป็นสตริง, YYYYMMDD.

ตัวอย่างของค่าอินพุต:

20110617: 17 มิถุนายน 2554
19040229: 29 กุมภาพันธ์ 2447
06661225: 25 ธันวาคม 666
00000101: 1 มกราคม 0
99991231: 31 ธันวาคม 9999

คุณอาจจะสมมติว่าอินพุตทั้งหมดนั้นถูกต้อง โปรดทราบว่าปีศูนย์นั้นถูกต้อง

เอาท์พุทเป็นจำนวนเต็มระหว่างและ0 6จำนวนเต็มแต่ละค่าแทนชื่อวันในสัปดาห์ คุณสามารถตัดสินใจได้อย่างอิสระว่าจำนวนเต็มใดที่แสดงถึงชื่อวันต่อสัปดาห์

0: วันจันทร์
1: วันอังคาร
2: วันพุธ
...
6: วันอาทิตย์

(ตามลำดับ) หรืออันนี้

0: วันจันทร์
1: วันพุธ
2: วันอาทิตย์
...
6: วันเสาร์

(ไม่อยู่ในลำดับ)

กรณีทดสอบ

ป้อนข้อมูลเอาต์พุตรายสัปดาห์ ([0..6 -> วันจันทร์ .. วันอาทิตย์] ใช้ในตัวอย่างนี้)

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หรือฟังก์ชั่นในgetdatePHP

คุณควรใช้ปฏิทินเกรโกเรียนซึ่งมีผู้ใช้หลายคนในขณะนี้

แน่นอนว่ารหัสที่สั้นที่สุดจะเป็นผู้ชนะ หากสองรหัสมีความยาวเท่ากันรหัสนั้นที่มีคะแนนโหวตสูงสุดจะเป็นฝ่ายชนะ

(ครบกำหนด: เมื่อมีมากกว่า 5 รหัสที่มีคะแนนมากกว่า (หรือเท่ากัน) +1)


ต่อวัน? ทำไมวันคริสต์มาส!
Joey Adams

3
วิธีการแก้ปัญหาในแง่ดีเขียนในทุบตี (6 echo 4ตัวอักษร):
trutheality

1
@trutheality ไม่ฉันไม่ได้หมายความว่า .. สิ่งที่ฉันต้องการคือรหัสที่พิมพ์ / ส่งคืนวันในสัปดาห์ของวันที่มีคนพิมพ์ไม่ใช่แค่พิมพ์วันในสัปดาห์ของวันนี้
JiminP

โอ้ฉันรู้. นั่นคือสิ่งที่คนนี้ทำ
trutheality

ถูกต้องอย่างน้อย 14% ของเวลา!
Draco18 ไม่ไว้วางใจ SE

คำตอบ:


2

Ruby, 95 92 ตัวอักษร

การดำเนินการทับทิมแบบตรงไปตรงมาแบบเรียบง่ายด้วย 0: วันจันทร์, ...

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 ตัวอักษร

  • อัลกอริทึม Sakamoto
  • 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 ไม่สามารถทำงานได้อย่างถูกต้อง


คุณช่วยทดสอบอีกครั้งได้ไหม เป็นเวลาหลายปีที่ฉันได้ผลลัพธ์ที่ต่างออกไป (เช่น testcase 17760704 ให้ผลตอบแทนวันอังคารแทนวันพุธ)
Howard

@ วิธีการที่แปลกมาก สำหรับ 17760704 ฉันได้รับวันพุธ ฉันได้รับความไม่ลงรอยกันอื่น ๆ ซึ่งฉันไม่สามารถอธิบายได้เช่น 19040229 ส่งคืนวันอังคาร ไม่แน่ใจว่าเกิดจากอะไร ฉันได้รับผลลัพธ์เดียวกันเมื่อฉันขยายอัลกอริทึมกลับไปy+y/4-y/100+y/400เป็น
rintaun

ฉันเห็นว่ามันเกิดขึ้นกับ 497 * y / 400: y=4ในกรณีนั้นจะคืนค่า 4 แทนที่จะเป็น 5 ที่ถูกต้องy+y/4+y/100+y/400(ซึ่งมีเพียงสองคำแรกเท่านั้นที่เข้ามาเล่น) นั่นคือสิ่งที่ภัยพิบัติตอบ JavaScript ของฉัน เป็นไปได้หรือไม่ว่าคู่ถูกสร้างขึ้นแทน ints? (PHP ของฉันอ่อนแอเกินกว่าจะรู้ได้)
DocMax

@DocMax: การปล่อยให้นิพจน์ขยายออกไปจะมีผลลัพธ์เหมือนกัน (497y / 400 ควรเท่ากับ: y / 100 ถูกลบออกและเพิ่ม y / 400 อีกครั้งโดยไม่คำนึงถึง) ฉันเดาว่า PHP กำลังตัดทุกอย่างหลังจากทศนิยมแทนที่จะปัดเศษมัน ฉันทดสอบสิ่งนี้โดยการปัดเศษก่อนโมดูโล วิธีนี้แก้ไขความผิดปกติสองอย่าง แต่ 19040229 ยังคงส่งคืนผลลัพธ์เดียวกัน ความคิดอื่น ๆ ?
rintaun

@ พิมพ์ฉันไม่คิดว่ามันคือการปัดเศษ พวกเขาแตกต่างกันโดยพื้นฐาน นำตัวอย่างจากด้านบน (y = 4): 497 * 4/400 = 1988/400 = 4 แต่ในทางกลับกัน 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . ข้อกำหนด / 100 และ / 400 มีน้ำหนักมากเกินไปในการคำนวณของคุณซึ่งไม่สามารถเข้าถึง 2000
Howard

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, 126 123 ตัวอักษร

การใช้อัลกอริทึมของ 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 ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ ลองออนไลน์!

แก้ไข: ฉันควรแก้ไขอายุนี้มาแล้ว -6 ไบต์จากคำแนะนำของ Jonathan Allan +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
Jonathan Allan

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

@ programmer5000, ตรวจสอบวันที่ความท้าทายถูกโพสต์;)
Shaggy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.