05AB1E , 130 128 133 131 124 123 ไบต์
žežfžg)V0[Y`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()ćsO7%2@+Y`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVYI'.¡Q#
ฉันออกไปจากใจ ..
สำหรับภาษากอล์ฟ 05AB1E มันไม่สำคัญเลยไม่ว่าจะเป็นการป้อนข้อมูลด้วย.
หรือ-
หรืออย่างไรก็ตาม 05AB1E ไม่มี builtins สำหรับวัตถุหรือการคำนวณ Date builtin เพียงอย่างเดียวเกี่ยวกับวันที่มีคือวันนี้ปี / เดือน / วัน / ชั่วโมง / นาที / วินาที / microseconds
ด้วยเหตุนี้รหัสเกือบทั้งหมดที่คุณเห็นคือการคำนวณด้วยตนเองเพื่อไปยังวันถัดไปและการคำนวณวันในสัปดาห์
+5 ไบต์เนื่องจากส่วนหนึ่งฉันลืมสูตรของเซลเลอร์ (ปีที่ 1 สำหรับเดือนมกราคมและกุมภาพันธ์) ..
ลองออนไลน์หรือทดลองออนไลน์ด้วยวันที่กำหนดเองของ 'วันนี้''วันนี้'
คำอธิบาย:
กำแพงข้อความที่เข้ามา
โดยทั่วไปรหัสดังต่อไปนี้หลอกรหัส:
1 Date currentDate = today;
2 Integer counter = 0;
3 Start an infinite loop:
4* If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
5 Counter += 1;
6* currentDate += 1; // Set currentDate to the next day in line
7 If(currentDate == parsed input-string):
8 Stop the infinite loop, and output the counter
1) Date currentDate = today;
เป็นส่วนหนึ่งของโปรแกรม 05AB1E นี้:
že # Push today's day
žf # Push today's month
žg # Push today's year
) # Wrap them into a single list
V # Pop and store this list in variable `Y`
2) Integer counter = 0;
และ 3) Start an infinite loop:
ตรงไปตรงมาในโปรแกรม 05AB1E:
0 # Push 0 to the stack
[ # Start an infinite loop
4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
เป็นส่วนแรกที่มีการคำนวณด้วยตนเอง เนื่องจาก 05AB1E ไม่มีตัวสร้างวันที่เราจะต้องคำนวณวันในสัปดาห์ด้วยตนเอง
สูตรทั่วไปในการทำเช่นนี้คือ:
h=(q+⌊13(m+1)5⌋+K+⌊K4⌋+⌊J4⌋−2J)mod7,
เดือนมีนาคมถึงเดือนธันวาคม:
- qคือdayของเดือน (
[1, 31]
)
- mคือดัชนี 1 ดัชนีmonth (
[3, 12]
)
- Kคือปีแห่งศตวรรษ (yearmod100 )
- Jคือศตวรรษที่จัดทำดัชนี 0 (⌊year100⌋)
และสำหรับเดือนมกราคมและกุมภาพันธ์:
- qคือdayของเดือน (
[1, 31]
)
- mคือดัชนี 1month+12 (
[13, 14]
)
- Kเป็นปีของศตวรรษที่สำหรับปีที่ผ่านมา (คน(year−1)mod100 )
- Jคือศตวรรษที่จัดทำดัชนี 0 สำหรับปีที่แล้ว (⌊year−1100⌋)
ส่งผลให้ในวันของสัปดาห์h , โดยที่ 0 = วันเสาร์, 1 = วันอาทิตย์, ... , 6 = วันศุกร์
ที่มา: ความสอดคล้องของ Zeller
เราสามารถเห็นสิ่งนี้ได้ในโปรแกรม 05AB1E นี้:
Y # Push variable `Y`
` # Push the day, month, and year to the stack
U # Pop and save the year in variable `X`
Ð # Triplicate the month
3‹ # Check if the month is below 3 (Jan. / Feb.),
# resulting in 1 or 0 for truthy/falsey respectively
12* # Multiply this by 12 (either 0 or 12)
+ # And add it to the month
# This first part was to make Jan. / Feb. 13 and 14
> # Month + 1
13* # Multiplied by 13
5÷ # Integer-divided by 5
s3‹ # Check if the month is below 3 again (resulting in 1 / 0)
Xα # Take the absolute difference with the year
© # Store this potentially modified year in the register
т% # mYear modulo-100
D4÷ # mYear modulo-100, integer-divided by 4
®т÷©4÷ # mYear integer-divided by 100, and then integer-divided by 4
®·( # mYear integer-divided by 100, doubled, and then made negative
) # Wrap the entire stack into a list
ć # Extract the head (the counter variable that was also on the stack)
s # Swap so the calculated values above are as list at the top
O # Take the sum of this entire list
7% # And then take modulo-7 to complete the formula,
# resulting in 0 for Saturday, 1 for Sunday, and [2, 6] for [Monday, Friday]
2@ # Check if the day is greater than or equal to 2 (so a working day)
5) Counter += 1;
ตรงไปข้างหน้าอีกครั้ง:
# The >=2 check with `2@` results in either 1 for truthy and 0 for falsey
+ # So just adding it to the counter variable is enough
6) currentDate += 1; // Set currentDate to the next day in line
มีความซับซ้อนมากกว่าเดิมเพราะเราต้องทำด้วยตนเอง ดังนั้นสิ่งนี้จะถูกขยายเป็นโค้ดหลอกต่อไปนี้:
a Integer isLeapYear = ...;
b Integer daysInCurrentMonth = currentDate.month == 2 ?
c 28 + isLeapYear
d :
e 31 - (currentDate.month - 1) % 7 % 2;
f If(currentDate.day < daysInCurrentMonth):
g nextDate.day += 1;
h Else:
i nextDate.day = 1;
j If(currentDate.month < 12):
k nextDate.month += 1;
l Else:
m nextDate.month = 1;
n nextDate.year += 1;
แหล่งที่มา:
อัลกอริทึมสำหรับการพิจารณาว่าปีเป็นปีอธิกสุรทินหรือไม่ (แก้ไข: ไม่มีความเกี่ยวข้องอีกต่อไปเนื่องจากฉันใช้วิธีการทางเลือกเพื่อตรวจสอบปีอธิกสุรทินซึ่งบันทึกได้ 7 ไบต์)
อัลกอริทึมสำหรับกำหนดจำนวนวันในหนึ่งเดือน
6a) Integer isLeapYear = ...;
ทำสิ่งนี้ในโปรแกรม 05AB1E:
Y # Push variable `Y`
` # Push the days, month and year to the stack
т‰ # Divmod the year by 100
0K # Remove all items "00" (or 0 when the year is below 100)
θ # Pop the list, and leave the last item
4Ö # Check if this number is visible by 4
U # Pop and save the result in variable `X`
นอกจากนี้ยังใช้ในคำตอบ 05AB1E ของฉันด้วยดังนั้นจึงมีการเพิ่มตัวอย่างบางปีเพื่อแสดงขั้นตอน
6b) currentDate.month == 2 ?
และ 6c) 28 + isLeapYear
ทำเช่นนี้:
D # Duplicate the month that is now the top of the stack
2Q # Check if it's equal to 2
i # And if it is:
\ # Remove the duplicated month from the top of the stack
28X+ # Add 28 and variable `X` (the isLeapYear) together
6d) :
และ 6e) 31 - (currentDate.month - 1) % 7 % 2;
ทำเช่นนี้:
ë # Else:
< # Month - 1
7% # Modulo-7
É # Is odd (shortcut for %2)
31 # Push 31
α # Absolute difference between both
} # Close the if-else
6f) If(currentDate.day < daysInCurrentMonth):
ทำดังนี้:
‹ # Check if the day that is still on the stack is smaller than the value calculated
i # And if it is:
6g) nextDate.day += 1;
ทำเช่นนี้:
Y # Push variable `Y`
¬ # Push its head, the days (without popping the list `Y`)
> # Day + 1
0 # Push index 0
# (This part is done after the if-else clauses to save bytes)
}} # Close the if-else clauses
ǝ # Insert the day + 1 at index 0 in the list `Y`
V # Pop and store the updated list in variable `Y` again
6h) Else:
และ 6i) nextDate.day = 1;
ทำเช่นนี้แล้ว:
ë # Else:
Y # Push variable `Y`
1 # Push a 1
¾ # Push index 0
ǝ # Insert 1 at index 0 (days part) in the list `Y`
6j) If(currentDate.month < 12):
:
D # Duplicate the list `Y`
Ås # Pop and push its middle (the month)
D12‹ # Check if the month is below 12
i # And if it is:
6k) nextDate.month += 1;
:
> # Month + 1
1 # Push index 1
# (This part is done after the if-else clauses to save bytes)
}} # Close the if-else clauses
ǝ # Insert the month + 1 at index 1 in the list `Y`
V # Pop and store the updated list in variable `Y` again
6l) Else:
, 6m) nextDate.month = 1;
และ 6n) nextDate.year += 1;
จะทำดังนี้:
ë # Else:
\ # Delete the top item on the stack (the duplicated month)
1 # Push 1
D # Push index 1 (with a Duplicate)
ǝ # Insert 1 at index 1 (month part) in the list `Y`
¤ # Push its tail, the year (without popping the list `Y`)
> # Year + 1
2 # Index 2
# (This part is done after the if-else clauses to save bytes)
}} # Close the if-else clauses
ǝ # Insert the year + 1 at index 2 in the list `Y`
V # Pop and store the updated list in variable `Y` again
และสุดท้ายที่ 8) If(currentDate == parsed input-string):
และ 9) Stop the infinite loop, and output the counter
:
Y # Push variable `Y`
I # Push the input
'.¡ '# Split it on dots
Q # Check if the two lists are equal
# # And if they are equal: stop the infinite loop
# (And output the top of the stack (the counter) implicitly)