Day Four ✅
This commit is contained in:
parent
a29299ede8
commit
dcff332499
4
index.ts
4
index.ts
@ -1,3 +1,3 @@
|
|||||||
import { runDayThree } from "./src/day_three";
|
import {runDayFour} from "./src/day_four";
|
||||||
|
|
||||||
runDayThree();
|
runDayFour();
|
41
src/day_four.test.ts
Normal file
41
src/day_four.test.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import {Scratchcard, ScratchcardSet} from "./day_four";
|
||||||
|
|
||||||
|
describe('Day 4', () => {
|
||||||
|
const inputs: [string, number][] = [
|
||||||
|
['Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53', 8],
|
||||||
|
['Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19', 2],
|
||||||
|
['Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1', 2],
|
||||||
|
['Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83', 1],
|
||||||
|
['Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36', 0],
|
||||||
|
['Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11', 0]
|
||||||
|
];
|
||||||
|
|
||||||
|
it.each(inputs)('should score %s with %d', (input, expectedScore) => {
|
||||||
|
const scratchcard = new Scratchcard(input);
|
||||||
|
expect(scratchcard.score).toEqual(expectedScore);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(inputs.map(([input, score]) => [input, score !== 0]))('should return whether %s is a winner', (input, winner) => {
|
||||||
|
const scratchcard = new Scratchcard(input);
|
||||||
|
|
||||||
|
expect(scratchcard.isWinner).toEqual(winner);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should report the correct scratchcard size', () => {
|
||||||
|
const scratchcard = new Scratchcard(inputs[0][0]);
|
||||||
|
const children = inputs.slice(1, 5).map(([input]) => new Scratchcard(input));
|
||||||
|
|
||||||
|
scratchcard.setChildren(children);
|
||||||
|
expect(scratchcard.size).toEqual(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate the total score', () => {
|
||||||
|
const scratchcards = new ScratchcardSet(inputs.map(([input]) => input));
|
||||||
|
expect(scratchcards.totalScore).toEqual(13);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate the total number of scratchcards', () => {
|
||||||
|
const scratchcards = new ScratchcardSet(inputs.map(([input]) => input));
|
||||||
|
expect(scratchcards.length).toEqual(30);
|
||||||
|
});
|
||||||
|
});
|
76
src/day_four.ts
Normal file
76
src/day_four.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user