-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_04.mjs
63 lines (50 loc) · 2.11 KB
/
day_04.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import * as fs from 'node:fs';
const inputData = fs.readFileSync('input.txt', 'utf-8').trim().split('\n\n').map(data => data);
const [_drawnNumbers, ..._bingoBoards] = inputData;
const drawnNumbers = _drawnNumbers.split(',').map(n => parseInt(n));
class BingoBoard {
constructor(data) {
this.board = data.split('\n').map(row => row.trim().split(/\s+/).map(n => parseInt(n)));
}
get isAnyRowFilled() {
return this.board.some(row => row.every(cell => cell === 'X'));
}
get isAnyColumFilled() {
return Array
.from({ length: this.board[0].length }, (_, i) => this.board.map((row) => row[i]))
.some(row => row.every(cell => cell === 'X'));
}
get unmarkedNumbers() {
return this.board.flatMap(row => row.filter(cell => typeof cell === 'number'));
}
get sumOfUnmarkedNumbers() {
return this.unmarkedNumbers.reduce((acc, cur) => acc + cur, 0);
}
tryDaubOffNumber(number) {
this.board.forEach(row => {
const i = row.findIndex(cell => cell === number);
if (i >= 0) row[i] = 'X';
});
};
}
const bingoBoards = _bingoBoards.map(data => new BingoBoard(data));
const findWinner = () => {
for (let number of drawnNumbers) {
bingoBoards.forEach(board => board.tryDaubOffNumber(number));
const winningBoards = bingoBoards.filter(board => board.isAnyRowFilled || board.isAnyColumFilled);
if (winningBoards.length) return { winningBoard: winningBoards[0], lastDrawnNumber: number };
}
};
const { lastDrawnNumber, winningBoard } = findWinner();
console.log(`Part 1: ${lastDrawnNumber * winningBoard.sumOfUnmarkedNumbers}`);
const findLoser = () => {
let losingBoard;
for (let number of drawnNumbers) {
bingoBoards.forEach(board => board.tryDaubOffNumber(number));
const losingBoards = bingoBoards.filter(board => !board.isAnyRowFilled && !board.isAnyColumFilled);
if (losingBoards.length === 1) losingBoard = losingBoards[0];
if (!losingBoards.length) return { losingBoard, lastDrawnNumber: number };
}
};
const { lastDrawnNumber: lastDawnForLoser, losingBoard } = findLoser();
console.log(`Part 2: ${losingBoard.sumOfUnmarkedNumbers * lastDawnForLoser}`);