import fs from "fs"; import {Engine} from "./day_three"; import {forEach} from "lodash"; export class Scratchcard { private readonly numbers: number[]; private readonly winningNumbers: number[]; private children: Scratchcard[] = []; constructor(input: string) { const [_, withoutId] = input.split(':'); const [winning, ourNumbers] = withoutId.split('|'); this.winningNumbers = this.parseNumberList(winning); this.numbers = this.parseNumberList(ourNumbers); } 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; if (matches.length === 1) return 1; return Math.pow(2, Math.max(matches.length - 1, 1)); } 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); }