advent-of-code-2023/src/day_four.ts

89 lines
2.2 KiB
TypeScript
Raw Permalink Normal View History

2023-12-04 08:12:05 +00:00
import fs from "fs";
import {whitespace, int, string} from "parjs";
import {between, manySepBy, then} from "parjs/combinators";
const cardIdParser = int()
.pipe(between(whitespace()))
.pipe(between(string('Card'), string(': ')));
const numbersParser = int()
.pipe(between(whitespace()))
.pipe(manySepBy(whitespace()));
const winningNumberParser = numbersParser
.pipe(between(cardIdParser, string('|')))
.pipe(then(numbersParser));
2023-12-04 08:12:05 +00:00
export class Scratchcard {
private readonly numbers: number[];
private readonly winningNumbers: number[];
private children: Scratchcard[] = [];
constructor(input: string) {
const [
winningNumbers,
numbers
] = winningNumberParser.parse(input).value;
2023-12-04 08:12:05 +00:00
this.winningNumbers = winningNumbers;
this.numbers = numbers;
2023-12-04 08:12:05 +00:00
}
private parseNumberList(input: string): number[] {
return [...input.matchAll(/\d+/g)].map(match => parseInt(match[0], 10));
}
public get matches() {
return this.numbers.filter(number => this.winningNumbers.includes(number));
}
get score() {
const matches = this.matches;
if (!matches.length) return 0;
return Math.pow(2, matches.length - 1);
2023-12-04 08:12:05 +00:00
}
get isWinner() {
return Boolean(this.matches.length);
}
public setChildren(children: Scratchcard[]) {
this.children = children;
}
get size(): number {
return 1 + this.children.reduce((totalSize, child) => totalSize + child.size, 0);
}
}
export class ScratchcardSet {
private readonly scratchcards: Scratchcard[];
constructor(inputs: string[]) {
this.scratchcards = inputs.map(input => new Scratchcard(input));
this.scratchcards.forEach((scratchcard, index) => {
if (scratchcard.isWinner) {
const children = this.scratchcards.slice(index + 1, index + 1 + scratchcard.matches.length);
scratchcard.setChildren(children);
}
});
}
get totalScore() {
return this.scratchcards.reduce((total, scratchcard) => total + scratchcard.score, 0);
}
get length() {
return this.scratchcards.reduce((totalSize, scratchcard) => totalSize + scratchcard.size, 0);
}
}
export const runDayFour = () => {
const input = fs.readFileSync('./inputs/day_four_input.txt', 'utf8').split('\n').filter(Boolean);
const scratchCards = new ScratchcardSet(input);
console.log(scratchCards.totalScore);
console.log(scratchCards.length);
}