Change your colour scheme

Advent of Code 2023: Day Four


Read the previous Advent of Code posts, or checkout the Git repository.

Day Four was much easier than Day Three, and I’m actually quite pleased with my solution.

Part One

Given a list of “scratchcards” that look like Card ID: list of winning numbers | list of scratched numbers, calculate the score, where the score is 1 if there is 1 match, and then doubles for each subsequent match afterwards.

I realised that is basically just exponents of 2 - 2^0, 2^1 etc. So, I parse each scratchcard into an object, and then to calculate the score I do:

get matches() {
return this.numbers.filter(number => this.winningNumbers.includes(number));
get score() {
if (!this.matches.length) return 0;

return Math.pow(2, this.matches.length - 1);

And then just do Array.prototype.reduce over my list of scratchcards to get the total score. Pretty tidy, I’m happy with it.

Part Two

Now the scoring changes. If a scratchcard is a winner, instead of just having a score, it takes the next n scratchcards from the list, where n is the number of winning numbers matched. If one of the “copied” scratchcards later gets children, that also has to be reflected in the earlier copies (basically, we need to maintain references).

I just made each scratchcard a tree, essentially, with an empty array of children scratchcards, and then pulled references from my Scratchcard list using Array.prototype.slice. I then recursively calculated the total size of my scratchcard set, where each scratchcard implements a size getter, which returns 1 + sum of children sizes.

class Scratchcard {

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);

get totalScore() {
return this.scratchcards.reduce((total, scratchcard) => total + scratchcard.score, 0);

get length() {
return this.scratchcards.reduce((totalSize, scratchcard) => totalSize + scratchcard.size, 0);

And that’s Day Four complete!


About the author

My face

I'm Lewis Dale, a software engineer and web developer based in the UK. I write about writing software, silly projects, and cycling. A lot of cycling. Too much, maybe.