2023-12-04 08:12:05 +00:00
|
|
|
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;
|
|
|
|
|
2023-12-04 08:17:01 +00:00
|
|
|
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);
|
|
|
|
}
|