Created
September 12, 2022 17:57
-
-
Save lydell/0a64e36040c06a0444089c56402a40db to your computer and use it in GitHub Desktop.
Doomsday algorithm
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(); | |
} |
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/promises"; | |
const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); | |
while (true) { | |
const n = Math.floor(Math.random() * 100); | |
console.log(n); | |
console.time("time"); | |
await rl.question(""); | |
console.log(odd11(n)); | |
console.timeEnd("time"); | |
await rl.question("\n"); | |
} | |
function odd11(y) { | |
const x = (y + 11 * (y % 2)) / 2; | |
return 7 - (x + 11 * (x % 2)) % 7; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment