Edd Mann Developer

Advent of Code 2015 - Day 16 - Aunt Sue

On the sixteenth day of Advent of Code 2015 we are tasked with working out which Aunt Sue (there are 500!?) sent us a gift, so we can send them a thank you card.

Part 1

For part one we are provided with a list of all the Aunt Sues (identified 1-500) and things that we remember about each one. We have been gifted a My First Crime Scene Analysis Machine so we are able to get readings from the provided wrapping paper. To determine which Aunt Sue sent the gift we must compare these readings with all the properties we know about them.

To begin, we parse the input into a form with can subsequently work with.

type Aunt = { id: number; properties: { [name: string]: number } };

const parseAunts = (input: string): Aunt[] =>
  input.split('\n').map(line => ({
    id: toInt(line.match(/\d+/)[0]),
    properties: Object.fromEntries(
      [...line.matchAll(/(\w+): (\d+)/g)].map(([_, k, v]) => [

With each Aunts properties now parsed, we move on to creating several number-based comparator curried functions which will come in handy going forward.

type Comparator = (value: number) => boolean;

const equalTo = (x: number): Comparator => (y: number) => x === y;
const lessThan = (x: number): Comparator => (y: number) => y < x;
const greaterThan = (x: number): Comparator => (y: number) => y > x;

In doing this, we are then able to provide the supplied reading and comparator logic to a function which will find the given Aunt which matches all these conditions.

const findAuntWithReadings = (
  aunts: Aunt[],
  readings: { [name: string]: Comparator }
): Aunt =>
  aunts.find(({ properties }) =>
    Object.entries(properties).every(([k, v]) => readings[k](v))

The function above iterates over all the supplied Auntsโ€™ properties and returns the first one that meets all the readings critiera. For part one we are asked to find the Aunt which matches the exact reading values - supplying these readings to the function above returns the desired Aunts identifier ๐ŸŒŸ.

const part1 = (input: string): number =>
  findAuntWithReadings(parseAunts(input), {
    children: equalTo(3),
    cats: equalTo(7),
    samoyeds: equalTo(2),
    pomeranians: equalTo(3),
    akitas: equalTo(0),
    vizslas: equalTo(0),
    goldfish: equalTo(5),
    trees: equalTo(3),
    cars: equalTo(2),
    perfumes: equalTo(1),

Part 2

For part two we are required to tweak the readings criteria and supply several greater/less-than comparators in place of the equality checks as so:

const part2 = (input: string): number =>
  findAuntWithReadings(parseAunts(input), {
    children: equalTo(3),
    cats: greaterThan(7),
    samoyeds: equalTo(2),
    pomeranians: lessThan(3),
    akitas: equalTo(0),
    vizslas: equalTo(0),
    goldfish: lessThan(5),
    trees: greaterThan(3),
    cars: equalTo(2),
    perfumes: equalTo(1),

With these amendments made we can use the same functions as implemented in part one to return the revised found Aunts identifier ๐ŸŒŸ.