Created
December 13, 2020 20:00
-
-
Save mkantor/78c0916709883eee7201b0b4c0e56b46 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// @ts-check | |
const schedule = [ | |
13, | |
'x', | |
'x', | |
41, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
997, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
23, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
19, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
29, | |
'x', | |
619, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
37, | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
'x', | |
17, | |
] | |
const buses = schedule.map((a) => (typeof a !== 'number' ? 0 : a)) | |
/** @returns {[number, number]} */ | |
function divmod(x, y) { | |
var div = Math.trunc(x / y) | |
var rem = x % y | |
return [div, rem] | |
} | |
function extended_gcd(a, b) { | |
let [last_remainder, remainder] = [Math.abs(a), Math.abs(b)] | |
let [x, last_x, y, last_y] = [0, 1, 1, 0] | |
let quotient | |
while (remainder != 0) { | |
;[last_remainder, [quotient, remainder]] = [ | |
remainder, | |
divmod(last_remainder, remainder), | |
] | |
;[x, last_x] = [last_x - quotient * x, x] | |
;[y, last_y] = [last_y - quotient * y, y] | |
} | |
return [last_remainder, last_x * (a < 0 ? -1 : 1)] | |
} | |
function invmod(e, et) { | |
const [g, x] = extended_gcd(e, et) | |
if (g != 1) { | |
throw 'Multiplicative inverse modulo does not exist!' | |
} | |
return x % et | |
} | |
function chinese_remainder(mods, remainders) { | |
const max = mods.reduce((a, b) => a * b) // product of all moduli | |
const series = remainders | |
.map((r, index) => [r, mods[index]]) | |
.map((r, m) => (r * max * invmod(max / m, m)) / m) | |
return series.reduce((a, b) => a + b) % max | |
} | |
const ba = buses.filter((a) => a !== 0) | |
console.log( | |
chinese_remainder( | |
ba.map((b) => b[0]), | |
ba.map((a, b) => a - b) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment