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)) );