const sample = await Deno.readTextFile("sample.txt"); const input = await Deno.readTextFile("input.txt"); type Row = T[]; type Matrix = Row[]; type Board = Matrix; const rotateMatrix = (matrix: Matrix): Matrix => matrix.map((_, index) => matrix.map((row) => row[index])); const checkMatrixForEmptyRow = ( matrix: Matrix ): boolean => Boolean(matrix.find((row) => row.every((value) => value === undefined))); const filterMatrix = ( matrix: Matrix, number: number ): Matrix => matrix.map((row) => row.map((value) => (value !== number ? value : undefined)) ); const parseNumbers = (data: string): number[] => data.split("\n")[0].split(",").map(parseFloat); const parseBoards = (data: string): Board[] => data .split("\n\n") .slice(1) .filter(Boolean) .map((board) => board .split("\n") .filter(Boolean) .map((line) => line.trim().split(/\ +/).map(parseFloat)) ); const solvePart1 = (data: string): number => { const numbers = parseNumbers(data); const boards = parseBoards(data); return numbers.reduce( ({ boards, result }, number): { boards: Board[]; result: number } => { if (result > -1) { return { boards, result }; } const filteredBoards = boards.map((board) => filterMatrix(board, number)); const matchingBoard = filteredBoards.find(checkMatrixForEmptyRow); return { boards: filteredBoards, result: matchingBoard ? matchingBoard .flatMap((row) => row.map((v) => v ?? 0)) .reduce((sum, value) => sum + value, 0) * number : result, }; }, { boards: boards.concat(boards.map(rotateMatrix)), result: -1 } ).result; }; console.log("Sample:", solvePart1(sample)); // 4512 console.log("Input", solvePart1(input)); // 38913 const solvePart2 = (data: string): number => { const numbers = parseNumbers(data); const parsedBoards = parseBoards(data); const r = numbers .reduce( (boards, number, index) => [ ...boards, boards[index].map((variant) => variant.map((board) => filterMatrix(board, number)) ), ], [parsedBoards.map((board) => [board, rotateMatrix(board)])] ) .map((boards, index) => ({ number: numbers[index - 1], boards: boards })); const n2 = r.filter(({ boards }) => boards.flatMap((variant) => variant).find(checkMatrixForEmptyRow) ); return console.log("n2", n2); const n = r.find(({ boards }) => boards.find(checkMatrixForEmptyRow)); return console.log("r", r, n?.number); return numbers.reduce( ( { boards, result }, number, index ): { boards: Board[]; result: number } => { if (result > -1) { return { boards, result }; } let filteredBoards = boards.map((board) => filterMatrix(board, number)); let matchingBoard = filteredBoards.find(checkMatrixForEmptyRow); if (matchingBoard) { if (filteredBoards.length === parsedBoards.length * 2) { /* console.log("here", index, number, filteredBoards); */ filteredBoards = filteredBoards.filter((fb) => fb !== matchingBoard); matchingBoard = undefined; } else if (filteredBoards.length === parsedBoards.length * 2 - 1) { filteredBoards = filteredBoards.filter((fb) => fb !== matchingBoard); matchingBoard = filteredBoards[0]; console.log( "here", index, number, matchingBoard, matchingBoard .flatMap((row) => row.map((v) => v ?? 0)) .reduce((sum, value) => sum + value, 0) ); } } /* const mb = filteredBoards.filter(checkMatrixForEmptyRow); */ /* console.log( */ /* "index, number", */ /* index, */ /* number, */ /* /* matchingBoard && filteredBoards.indexOf(matchingBoard) */ /* mb.length */ /* ); */ return { boards: filteredBoards, result: matchingBoard ? matchingBoard .flatMap((row) => row.map((v) => v ?? 0)) .reduce((sum, value) => sum + value, 0) * number : result, }; }, { boards: parsedBoards.concat(parsedBoards.map(rotateMatrix)), result: -1 } ).result; }; console.log("Sample:", solvePart2(sample)); // 4512 /* console.log("Input", solvePart1(input)); // 38913 */