141 lines
3.7 KiB
TypeScript
141 lines
3.7 KiB
TypeScript
import { readLines } from "https://deno.land/std@0.177.1/io/read_lines.ts";
|
|
|
|
class BingoBoard {
|
|
board: string[][];
|
|
hits: boolean[][];
|
|
|
|
constructor(board: string[][]) {
|
|
this.board = board;
|
|
this.hits = [[false,false,false,false,false],
|
|
[false,false,false,false,false],
|
|
[false,false,false,false,false],
|
|
[false,false,false,false,false],
|
|
[false,false,false,false,false]];
|
|
}
|
|
|
|
checkRow(j:number): boolean {
|
|
for (let i = 0; i < this.board.length; i++) {
|
|
if (!this.hits[i][j]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
checkColumn(j:number): boolean {
|
|
for (let i = 0; i < this.board[j].length; i++) {
|
|
if (!this.hits[j][i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
hit(num:string) {
|
|
for (let i = 0; i < this.board.length; i++) {
|
|
for (let j = 0; j < this.board[i].length; j++) {
|
|
if (this.board[i][j] == num) {
|
|
this.hits[i][j] = true;
|
|
return [i,j];
|
|
}
|
|
}
|
|
}
|
|
return [-1,-1];
|
|
}
|
|
|
|
hitAndSolve(num:string): boolean {
|
|
const [x,y] = this.hit(num);
|
|
if (x == -1 || y == -1) {
|
|
return false
|
|
}
|
|
return this.checkRow(y) || this.checkColumn(x);
|
|
}
|
|
|
|
sumOfUnmarkedNumbers(): number {
|
|
let sum = 0;
|
|
for (let i = 0; i < this.board.length; i++) {
|
|
for (let j = 0; j < this.board[i].length; j++) {
|
|
if (!this.hits[i][j]) {
|
|
sum += +this.board[i][j];
|
|
}
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
}
|
|
|
|
async function Part1() {
|
|
const file = await Deno.open("./Day4/input.txt");
|
|
|
|
const lines = readLines(file);
|
|
const numbers: string[] = (await lines.next()).value.split(",");
|
|
const boards: BingoBoard[] = [];
|
|
|
|
let currBoard: string[][] = [];
|
|
|
|
for await (const line of lines) {
|
|
if (line == "") {
|
|
continue;
|
|
}
|
|
currBoard.push(line.split(" ").filter(x => x != ""));
|
|
if (currBoard.length == 5) {
|
|
boards.push(new BingoBoard(currBoard));
|
|
currBoard = [];
|
|
}
|
|
}
|
|
|
|
for (const num of numbers) {
|
|
for (const b of boards) {
|
|
if (b.hitAndSolve(num)) {
|
|
return +num * b.sumOfUnmarkedNumbers();
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
async function Part2() {
|
|
const file = await Deno.open("./Day4/input.txt");
|
|
|
|
const lines = readLines(file);
|
|
const numbers: string[] = (await lines.next()).value.split(",");
|
|
const boards: BingoBoard[] = [];
|
|
|
|
let currBoard: string[][] = [];
|
|
|
|
for await (const line of lines) {
|
|
if (line == "") {
|
|
continue;
|
|
}
|
|
currBoard.push(line.split(" ").filter(x => x != ""));
|
|
if (currBoard.length == 5) {
|
|
boards.push(new BingoBoard(currBoard));
|
|
currBoard = [];
|
|
}
|
|
}
|
|
|
|
const isDeadBoard: boolean[] = new Array(boards.length);
|
|
isDeadBoard.fill(false);
|
|
let deadBoards = boards.length;
|
|
|
|
for (const num of numbers) {
|
|
for (const i in boards) {
|
|
if (isDeadBoard[i]) {
|
|
continue
|
|
}
|
|
const b = boards[+i];
|
|
if (b.hitAndSolve(num)) {
|
|
if (deadBoards == 1) {
|
|
return +num * b.sumOfUnmarkedNumbers();
|
|
} else {
|
|
isDeadBoard[i] = true;
|
|
deadBoards--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
console.log("Part1: " + await Part1());
|
|
console.log("Part1: " + await Part2()); |