AdventOfCode2024/08/index.ts
2024-12-12 22:26:35 -05:00

145 lines
4.3 KiB
TypeScript

import fs from "node:fs";
import { printTime, now } from "../util";
type Coord = [number, number];
const test = false;
const data = fs.readFileSync(
test ? "./inputs/testinput" : "./inputs/input",
"utf8"
);
let timer = now.instant();
console.log(
"part one:",
Object.entries(
data
.split("\n")
.slice(0, -1)
.reduce((m, curr, row) => {
curr.split("").forEach((v, col) => {
if (v !== ".") {
m[v] = m[v] ? [...m[v], [row, col]] : [[row, col]];
}
});
return m;
}, {} as Record<string, Array<Coord>>)
)
.map(([_, locations]) => {
return locations.reduce((antinodes, curr, i, array) => {
return [
...antinodes,
...array.slice(i + 1).reduce((total, next) => {
return [
...total,
[
curr[0] - Math.abs(curr[0] - next[0]),
curr[1] > next[1]
? curr[1] + Math.abs(curr[1] - next[1])
: curr[1] - Math.abs(curr[1] - next[1]),
] as Coord,
[
next[0] + Math.abs(curr[0] - next[0]),
curr[1] < next[1]
? next[1] + Math.abs(curr[1] - next[1])
: next[1] - Math.abs(curr[1] - next[1]),
] as Coord,
];
}, [] as Array<Coord>),
];
}, [] as Array<Coord>);
})
.map((antinodes) => {
return antinodes.filter((antinode) => {
let maxWidth = test ? 12 : 50;
return !(
antinode[0] < 0 ||
antinode[1] < 0 ||
antinode[0] >= maxWidth ||
antinode[1] >= maxWidth
);
});
})
.flat() // merge the frequencies
// because arrays are not comparable, we need to filter out duplicates after strigifying them
.map((v) => JSON.stringify(v))
.reduce((total, v, i, a) => {
return a.indexOf(v) === i ? total + 1 : total;
}, 0),
printTime(now.instant().since(timer))
);
timer = now.instant();
console.log(
"part two:",
Object.entries(
data
.split("\n")
.slice(0, -1)
.reduce((m, curr, row) => {
curr.split("").forEach((v, col) => {
if (v !== ".") {
m[v] = m[v] ? [...m[v], [row, col]] : [[row, col]];
}
});
return m;
}, {} as Record<string, Array<Coord>>)
)
.map(([_, locations]) => {
return locations.reduce((antinodes, curr, i, array) => {
return [
...antinodes,
curr, // include the antennas themselves
...array.slice(i + 1).reduce((total, next) => {
// draw the line north...
let localCurr = curr;
while (localCurr[0] > 0 && localCurr[1] > 0) {
let k = total.push([
localCurr[0] - Math.abs(localCurr[0] - next[0]),
localCurr[1] > next[1]
? localCurr[1] + Math.abs(localCurr[1] - next[1])
: localCurr[1] - Math.abs(localCurr[1] - next[1]),
]);
next = localCurr;
localCurr = total[k - 1];
}
return total;
}, [] as Array<Coord>),
...array.slice(i + 1).reduce((total, next) => {
// ...and south
let localCurr = curr;
while (next[0] < (test ? 12 : 50) && next[1] < (test ? 12 : 50)) {
let k = total.push([
next[0] + Math.abs(localCurr[0] - next[0]),
localCurr[1] < next[1]
? next[1] + Math.abs(localCurr[1] - next[1])
: next[1] - Math.abs(localCurr[1] - next[1]),
]);
localCurr = next;
next = total[k - 1];
}
return total;
}, [] as Array<Coord>),
];
}, [] as Array<Coord>);
})
.map((antinodes) => {
return antinodes.filter((antinode) => {
let maxWidth = test ? 12 : 50;
return !(
antinode[0] < 0 ||
antinode[1] < 0 ||
antinode[0] >= maxWidth ||
antinode[1] >= maxWidth
);
});
})
.flat()
.map((v) => JSON.stringify(v))
.reduce((total, v, i, a) => {
return a.indexOf(v) === i ? total + 1 : total;
}, 0),
printTime(now.instant().since(timer))
);