"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}`);