From bbab540d22d2bbb751a8d88a51db0e2ab6fe4c8b Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 1 Dec 2025 00:32:27 -0700 Subject: [PATCH] Add day 4 --- javascript/day_04/part1.mjs | 80 +++++++++++++++++++++++++++++++++++++ javascript/day_04/part2.mjs | 53 ++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 javascript/day_04/part1.mjs create mode 100644 javascript/day_04/part2.mjs diff --git a/javascript/day_04/part1.mjs b/javascript/day_04/part1.mjs new file mode 100644 index 0000000..fc6fda6 --- /dev/null +++ b/javascript/day_04/part1.mjs @@ -0,0 +1,80 @@ +"use strict"; + +import { readFile } from "fs/promises"; + +if (process.argv.length <= 2) { + console.error(`Needs more args >:(`). + process.exit(0); +} + +const fileToRead = process.argv[2]; +const file = await readFile(fileToRead, `utf-8`); + +/** @type {Array>} */ +const wordSearch = []; +const wordToLookFor = "XMAS" + +for (const line of file.split(`\n`)) { + wordSearch.push(line.split(``)); +}; + +const locationTransformers = { + north: ([y, x], i) => [y - i, x], + northeast: ([y, x], i) => [y - i, x + i], + east: ([y, x], i) => [y, x + i], + southeast: ([y, x], i) => [y + i, x + i], + south: ([y, x], i) => [y + i, x], + southwest: ([y, x], i) => [y + i, x - i], + west: ([y, x], i) => [y, x - i], + northwest: ([y, x], i) => [y - i, x - i], +} + +let total = 0; + +// Iterating the puzzle space +for (let y = 0, l1 = wordSearch.length; y < l1; y++) { + for (let x = 0, l2 = wordSearch[y].length; x < l2; x++) { + + + // Short-circuit for performance + const middle = wordSearch[y][x]; + if (wordToLookFor.at(0) !== middle) { + continue; + }; + + const valid = { + north: true, + northeast: true, + east: true, + southeast: true, + south: true, + southwest: true, + west: true, + northwest: true, + }; + + // Compare each direction against the letters in the word. + for (const i in wordToLookFor) { + const required = wordToLookFor.at(i); + + // Convert the coordinates for each direction then compare + for (const direction in locationTransformers) { + if (!valid[direction]) continue; + const [ newY, newX ] = locationTransformers[direction]( + [y, x], + parseInt(i) + ); + + try { + valid[direction] = wordSearch[newY][newX] === required; + } catch { + valid[direction] = false; + }; + }; + }; + + total += Object.values(valid).filter(v => v).length; + }; +}; + +console.log(`Found ${total} instances of ${wordToLookFor}`); diff --git a/javascript/day_04/part2.mjs b/javascript/day_04/part2.mjs new file mode 100644 index 0000000..1ef34be --- /dev/null +++ b/javascript/day_04/part2.mjs @@ -0,0 +1,53 @@ +"use strict"; + +import { readFile } from "fs/promises"; + +if (process.argv.length <= 2) { + console.error(`Needs more args >:(`). + process.exit(0); +} + +const fileToRead = process.argv[2]; +const file = await readFile(fileToRead, `utf-8`); + +/** @type {Array>} */ +const wordSearch = []; + +for (const line of file.split(`\n`)) { + wordSearch.push(line.split(``)); +}; + + +let total = 0; + +// Iterating the puzzle space, which is reduced by one in both axis' +// in order to reducing the number of iterations since we can't match +// along the edges anyway +for (let y = 1, l1 = wordSearch.length - 1; y < l1; y++) { + for (let x = 1, l2 = wordSearch[y].length - 1; x < l2; x++) { + + + // Short-circuit for performance + const middle = wordSearch[y][x]; + if (`A` !== middle) { + continue; + }; + + try { + const ne = wordSearch[y - 1][x + 1]; + const se = wordSearch[y + 1][x + 1]; + const sw = wordSearch[y + 1][x - 1]; + const nw = wordSearch[y - 1][x - 1]; + + let valid = ne === nw && se === sw; + valid ||= ne === se && nw === sw; + + valid &&= (ne === `M` && se === `S`) || (ne === `S` || se === `M`); + + if (valid) total += 1; + } catch (c){console.error(c)} + + }; +}; + +console.log(`Found ${total} instances of X'd MAS`);