Created
December 7, 2019 18:53
-
-
Save ludekstepan/0f4a168e163f1c6bbadcd475f82219a1 to your computer and use it in GitHub Desktop.
Advent of code 2019
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
const input = | |
`COM)B | |
B)C | |
C)D | |
D)E | |
E)F | |
B)G | |
G)H | |
D)I | |
E)J | |
J)K | |
K)L | |
K)YOU | |
I)SAN`.split("\n") | |
interface Orbit { | |
name: string | |
parent?: Orbit | |
depth?: number | |
} | |
const map = new Map<string, Orbit>() | |
function getOrCreate(name: string): Orbit { | |
if (map.has(name)) { | |
return map.get(name)! | |
} else { | |
const orbit: Orbit = { name } | |
map.set(name, orbit) | |
return orbit | |
} | |
} | |
for (const row of input) { | |
const [center, orbiter] = row.split(')') | |
const centerNode = getOrCreate(center) | |
const orbiterNode = getOrCreate(orbiter) | |
if (orbiterNode.parent) { | |
console.warn(`Node ${orbiterNode.name} already has parent ${orbiterNode.parent.name}`) | |
} | |
orbiterNode.parent = centerNode | |
} | |
for (const [, orbit] of map) { | |
let depth = 0 | |
let current = orbit | |
while (current.parent) { | |
depth++ | |
current = current.parent | |
} | |
orbit.depth = depth | |
} | |
function* mapWith<T, U>(mapper: (value: T) => U, iterable: Iterable<T>): Iterable<U> { | |
for (const value of iterable) { | |
yield mapper(value) | |
} | |
} | |
function reduce<T, R>(reducer: (previous: R, current: T) => R, initial: R, iterable: Iterable<T>): R { | |
let previous = initial | |
for (const current of iterable) { | |
previous = reducer(previous, current) | |
} | |
return previous | |
} | |
const x = reduce((a, b) => a + b!, 0, mapWith(x => x.depth, map.values())) | |
function* parents(orbit: Orbit) { | |
let current = orbit | |
while (current.parent) { | |
current = current.parent | |
yield current | |
} | |
} | |
function findCommonParent(a: Orbit, b: Orbit) { | |
const parentsA = new Set(parents(a)) | |
for (const parentB of parents(b)) { | |
if (parentsA.has(parentB)) { | |
return parentB | |
} | |
} | |
return undefined | |
} | |
const YOU = map.get('YOU')! | |
const SUN = map.get('SAN')! | |
const common = findCommonParent(YOU, SUN)! | |
const dist = YOU.depth! + SUN.depth! - 2*common.depth! - 2 | |
console.log(YOU, SUN, findCommonParent(YOU, SUN), dist) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment