AdventOfCode2024/04/index.ts

102 lines
2.7 KiB
TypeScript

import fs from "node:fs";
import { printTime, now } from "../util";
const test = false;
const data = fs.readFileSync(
test ? "./inputs/testinput" : "./inputs/input",
"utf8"
);
let timer = now.instant();
console.log(
"part one:",
data
.split("\n")
.slice(0, -1)
.reduce(
(coll, curr, index, array) => {
// 2D string matching is a pain. Let's turn it into a 1D problem!
curr.split("").forEach((s, i) => {
// create the columns
coll[i] += s;
// create the left-diagonals
coll[array.length + index + i] += s;
// create the right-diagonals
coll[array.length * 4 + index - i - 2] += s;
});
// include the original row
return [...coll, curr];
},
// pre-populate the array so everything's aligned
Array.from({ length: test ? 10 * 5 - 2 : 140 * 5 - 2 }, () => "")
)
.reduce((total, curr) => {
// and now just do some regexes over the set of 1D strings
// can't do /XMAS|SMAX/ because overlaps like XMASAMX are allowed!
let matchesForward = curr.match(/XMAS/g);
let matchesBackward = curr.match(/SAMX/g);
if (matchesForward) {
total += matchesForward.length;
}
if (matchesBackward) {
total += matchesBackward.length;
}
return total;
}, 0),
printTime(now.instant().since(timer))
);
timer = now.instant();
console.log(
"part two:",
data
.split("\n")
.slice(0, -1)
.reduce((coll, curr, index, array) => {
if (index === 0 || index === array.length - 1) {
// we can entirely skip the first and last rows, since there's no way to get a cross started
return coll;
}
// look for A's
return [
...coll,
...curr.split("").reduce((c, s, i, a) => {
if (i === 0 || i === a.length - 1) {
// same as above, edges are useless
return c;
}
// 1 2
// A
// 3 4
if (s === "A") {
return [
...c,
array[index - 1][i - 1] +
array[index - 1][i + 1] +
array[index + 1][i - 1] +
array[index + 1][i + 1],
];
}
return c;
}, [] as string[]),
];
}, [] as string[])
.reduce((coll, curr) => {
// we could have just done this check above,
// but it's a little more clear, although slower,
// to iterate again.
switch (curr) {
case "MSMS":
case "SSMM":
case "SMSM":
case "MMSS":
coll += 1;
default:
break;
}
return coll;
}, 0),
printTime(now.instant().since(timer))
);