Created
September 19, 2023 18:46
-
-
Save lydell/96ca5c6e915c28d8b9a73c9f09a6f1b8 to your computer and use it in GitHub Desktop.
Doomsday method trainer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as readline from "readline"; | |
const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); | |
const lower = new Date(process.argv[2] || "0000-01-01"); | |
const upper = new Date(process.argv[3] || "9999-12-31"); | |
const diff = upper - lower; | |
function randomDate() { | |
return new Date(lower.getTime() + Math.random() * diff); | |
} | |
const centuryLookup = { | |
0: 2, | |
1: 0, | |
2: 5, | |
3: 3, | |
}; | |
const dayNames = { | |
0: "Sunday", | |
1: "Monday", | |
2: "Tuesday", | |
3: "Wednesday", | |
4: "Thursday", | |
5: "Friday", | |
6: "Saturday", | |
} | |
function getDoomsday(month, day, isLeapYear) { | |
return { | |
1: isLeapYear ? 4 : 3, | |
2: 7 * Math.floor(day / 7) + (isLeapYear ? 1 : 0), | |
3: 7 * Math.floor(day / 7), | |
4: 4, | |
5: 9, | |
6: 6, | |
7: day <= 4 ? 4 : 11, | |
8: 8, | |
9: 5, | |
10: 10, | |
11: 7, | |
12: day >= 26 ? 26 : 12, | |
}[month]; | |
} | |
function printDetails(date) { | |
// console.log(date.toISOString().slice(0, 10)); | |
const result = []; | |
const year = date.getUTCFullYear(); | |
const firstTwo = Math.floor(year / 100); | |
const centuryNum = centuryLookup[firstTwo % 4]; | |
result.push(`Century: ${firstTwo} % 4 = ${firstTwo % 4} -> ${centuryNum} <---`); | |
const lastTwo = year - firstTwo * 100; | |
let centuryResult; | |
if (lastTwo === 0) { | |
result.push(`Year 00 – use century: ${centuryNum} <---`); | |
centuryResult = centuryNum; | |
} else { | |
const lastTwo11 = | |
lastTwo % 2 === 0 | |
? (result.push(`Even: ${lastTwo}`), lastTwo) | |
: (result.push(`Odd: ${lastTwo} + 11 = ${lastTwo + 11}`), lastTwo + 11); | |
const half = lastTwo11 / 2; | |
result.push(`Half: ${lastTwo11} / 2 = ${half}`); | |
const half11 = | |
half % 2 === 0 | |
? (result.push(`Even: ${half}`), half) | |
: (result.push(`Odd: ${half} + 11 = ${half + 11}`), half + 11); | |
const mod7 = half11 % 7; | |
const diff7 = 7 - mod7; | |
result.push(`Mod7: ${half11} % 7 = ${mod7} -> 7 - ${mod7} = ${diff7}`); | |
const centurySum = centuryNum + diff7; | |
centuryResult = centurySum % 7; | |
if (centurySum < 7) { | |
result.push(`Century result: ${centuryNum} + ${diff7} = ${centurySum} <---`); | |
} else { | |
result.push(`Century result: ${centuryNum} + ${diff7} = ${centurySum} -> ${centurySum} % 7 = ${centuryResult} <---`); | |
} | |
} | |
const month = date.getUTCMonth() + 1; | |
const day = date.getUTCDate(); | |
let isLeapYear = false; | |
if (month <= 2) { | |
result.push(`${month === 1 ? "January" : "February"}: Leap year?`); | |
if (lastTwo === 0) { | |
if (firstTwo % 4 === 0) { | |
result.push(`Year 00 – be careful! ${firstTwo} is divisible by 4 -> Is leap year!`); | |
isLeapYear = true; | |
} else { | |
result.push(`Year 00 – be careful! ${firstTwo} is NOT divisible by 4 -> Not leap year`); | |
} | |
} else if (lastTwo % 4 === 0) { | |
result.push(`Year: ${lastTwo} is divisible by 4 -> Is leap year!`); | |
isLeapYear = true; | |
} else { | |
result.push(`Year: ${lastTwo} is NOT divisible by 4 -> Not leap year`); | |
} | |
} | |
const doomsday = getDoomsday(month, day, isLeapYear); | |
result.push(`Doomsday: ${month} -> ${doomsday}`); | |
let final; | |
if (day === doomsday) { | |
final = centuryResult % 7; | |
result.push(`Is doomsday!`); | |
if (centuryResult < 7) { | |
result.push(`Final: ${final} <---`); | |
} else { | |
result.push(`Final: ${centuryResult} % 7 = ${final} <---`); | |
} | |
} else { | |
const diff = day - doomsday; | |
result.push(`Diff: ${day} - ${doomsday} = ${diff}`); | |
const centuryDiff = centuryResult + diff; | |
result.push(`Century + diff: ${centuryResult} + ${diff} = ${centuryDiff}`); | |
let positiveCenturyDiff = centuryDiff; | |
while (positiveCenturyDiff < 0) { | |
positiveCenturyDiff += 7; | |
result.push(`Positive: ${centuryDiff} + 7 = ${positiveCenturyDiff}`); | |
} | |
final = positiveCenturyDiff % 7; | |
if (positiveCenturyDiff < 7) { | |
result.push(`Final: ${final} <---`); | |
} else { | |
result.push(`Final: ${positiveCenturyDiff} % 7 = ${final} <---`); | |
} | |
} | |
const expected = date.getUTCDay(); | |
if (final !== expected) { | |
result.push(`ERROR: Expected ${expected} but got ${final}`) | |
} | |
result.push(""); | |
result.push(dayNames[final]); | |
return result.join("\n"); | |
} | |
// console.log(printDetails(randomDate())); | |
// console.log(printDetails(new Date(`${Math.floor(9999 * Math.random())}-01-01`))); | |
// console.log(printDetails(new Date(`2022-12-01`))); | |
// process.exit(0); | |
let date; | |
function run() { | |
if (date === undefined) { | |
date = randomDate(); | |
console.log(date.toISOString().slice(0, 10)); | |
console.time("time"); | |
} else { | |
// console.log(date.toUTCString().split(",")[0]); | |
console.log(printDetails(date)); | |
console.timeEnd("time"); | |
date = undefined; | |
} | |
} | |
run(); | |
for await (const _ of rl) { | |
run(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment