Day 16 - Advent of Code 2015
Mix.install([:kino, :benchee])
:ok
Links
Prompt
— Day 16: Aunt Sue —
Your Aunt Sue has given you a wonderful gift, and you’d like to send her a thank you card. However, there’s a small problem: she signed it “From, Aunt Sue”.
You have 500 Aunts named “Sue”.
So, to avoid sending the card to the wrong person, you need to figure out which Aunt Sue (which you conveniently number 1 to 500, for sanity) gave you the gift. You open the present and, as luck would have it, good ol’ Aunt Sue got you a My First Crime Scene Analysis Machine! Just what you wanted. Or needed, as the case may be.
The My First Crime Scene Analysis Machine (MFCSAM for short) can detect a few specific compounds in a given sample, as well as how many distinct kinds of those compounds there are. According to the instructions, these are what the MFCSAM can detect:
-
children, by human DNA age analysis. -
cats. It doesn’t differentiate individual breeds. - Several seemingly random breeds of dog: samoyeds, pomeranians, akitas, and vizslas.
-
goldfish. No other kinds of fish. -
trees, all in one group. -
cars, presumably by exhaust or gasoline or something. -
perfumes, which is handy, since many of your Aunts Sue wear a few kinds.
In fact, many of your Aunts Sue have many of these. You put the wrapping from the gift into the MFCSAM. It beeps inquisitively at you a few times and then prints out a message on ticker tape:
children: 3
cats: 7
samoyeds: 2
pomeranians: 3
akitas: 0
vizslas: 0
goldfish: 5
trees: 3
cars: 2
perfumes: 1
You make a list of the things you can remember about each Aunt Sue. Things missing from your list aren’t zero - you simply don’t remember the value.
What is the number of the Sue that got you the gift?
To begin, get your puzzle input.
— Part Two —
As you’re about to send the thank you note, something in the MFCSAM’s instructions catches your eye. Apparently, it has an outdated retroencabulator, and so the output from the machine isn’t exact values - some of them indicate ranges.
In particular, the cats and trees readings indicates that there are greater than that many (due to the unpredictable nuclear decay of cat dander and tree pollen), while the pomeranians and goldfish readings indicate that there are fewer than that many (due to the modial interaction of magnetoreluctance).
What is the number of the real Aunt Sue?
Although it hasn’t changed, you can still get your puzzle input.
Input
input = Kino.Input.textarea("Please paste your input file:")
input = input |> Kino.Input.read()
"Sue 1: children: 1, cars: 8, vizslas: 7\nSue 2: akitas: 10, perfumes: 10, children: 5\nSue 3: cars: 5, pomeranians: 4, vizslas: 1\nSue 4: goldfish: 5, children: 8, perfumes: 3\nSue 5: vizslas: 2, akitas: 7, perfumes: 6\nSue 6: vizslas: 0, akitas: 1, perfumes: 2\nSue 7: perfumes: 8, cars: 4, goldfish: 10\nSue 8: perfumes: 7, children: 2, cats: 1\nSue 9: pomeranians: 3, goldfish: 10, trees: 10\nSue 10: akitas: 7, trees: 8, pomeranians: 4\nSue 11: goldfish: 1, perfumes: 4, cars: 6\nSue 12: samoyeds: 6, trees: 6, perfumes: 2\nSue 13: akitas: 10, pomeranians: 0, vizslas: 2\nSue 14: cars: 2, perfumes: 3, children: 4\nSue 15: goldfish: 2, children: 8, cars: 5\nSue 16: goldfish: 9, cars: 0, vizslas: 5\nSue 17: cats: 5, trees: 6, perfumes: 6\nSue 18: cars: 0, perfumes: 8, pomeranians: 7\nSue 19: trees: 2, goldfish: 5, perfumes: 4\nSue 20: akitas: 4, vizslas: 4, trees: 0\nSue 21: pomeranians: 7, trees: 0, goldfish: 10\nSue 22: cars: 4, vizslas: 0, perfumes: 3\nSue 23: vizslas: 8, trees: 1, akitas: 2\nSue 24: children: 7, trees: 0, akitas: 1\nSue 25: goldfish: 3, akitas: 2, trees: 2\nSue 26: pomeranians: 4, vizslas: 4, samoyeds: 2\nSue 27: cars: 0, trees: 8, akitas: 5\nSue 28: perfumes: 6, cats: 0, cars: 2\nSue 29: trees: 7, akitas: 1, vizslas: 1\nSue 30: perfumes: 9, cars: 9, trees: 10\nSue 31: pomeranians: 5, akitas: 9, samoyeds: 1\nSue 32: pomeranians: 10, vizslas: 5, goldfish: 5\nSue 33: vizslas: 2, akitas: 3, trees: 7\nSue 34: goldfish: 10, perfumes: 0, samoyeds: 7\nSue 35: akitas: 6, cats: 7, perfumes: 10\nSue 36: pomeranians: 8, vizslas: 7, akitas: 6\nSue 37: goldfish: 2, cars: 10, children: 7\nSue 38: goldfish: 2, perfumes: 3, cars: 7\nSue 39: trees: 9, vizslas: 10, cars: 5\nSue 40: goldfish: 1, pomeranians: 0, trees: 2\nSue 41: trees: 2, goldfish: 6, vizslas: 3\nSue 42: akitas: 1, cars: 3, vizslas: 3\nSue 43: akitas: 1, pomeranians: 1, vizslas: 3\nSue 44: goldfish: 7, akitas: 3, vizslas: 10\nSue 45: akitas: 8, samoyeds: 8, goldfish: 2\nSue 46: trees: 0, vizslas: 4, cars: 9\nSue 47: cars: 9, trees: 10, perfumes: 4\nSue 48: akitas: 0, vizslas: 5, perfumes: 4\nSue 49: goldfish: 9, trees: 1, cars: 4\nSue 50: goldfish: 2, perfumes: 5, cars: 2\nSue 51: samoyeds: 1, goldfish: 2, perfumes: 7\nSue 52: cars: 0, perfumes: 4, goldfish: 8\nSue 53: goldfish: 9, vizslas: 2, akitas: 9\nSue 54: trees: 1, goldfish: 9, children: 5\nSue 55: cars: 0, akitas: 5, trees: 4\nSue 56: trees: 4, samoyeds: 5, children: 9\nSue 57: children: 0, vizslas: 8, cars: 3\nSue 58: trees: 4, pomeranians: 5, akitas: 5\nSue 59: vizslas: 10, cats: 3, children: 2\nSue 60: cats: 6, vizslas: 2, cars: 2\nSue 61: akitas: 1, vizslas: 0, children: 4\nSue 62: akitas: 4, trees: 9, children: 10\nSue 63: pomeranians: 6, vizslas: 6, cars: 4\nSue 64: perfumes: 8, pomeranians: 1, children: 8\nSue 65: perfumes: 3, goldfish: 6, trees: 5\nSue 66: goldfish: 10, akitas: 8, vizslas: 4\nSue 67: vizslas: 10, samoyeds: 3, trees: 2\nSue 68: samoyeds: 4, cars: 7, perfumes: 3\nSue 69: perfumes: 2, goldfish: 0, trees: 2\nSue 70: trees: 8, vizslas: 7, akitas: 6\nSue 71: cars: 2, children: 7, perfumes: 3\nSue 72: cars: 1, akitas: 9, perfumes: 0\nSue 73: vizslas: 4, akitas: 7, cars: 5\nSue 74: samoyeds: 3, cars: 3, akitas: 2\nSue 75: trees: 2, cars: 1, vizslas: 7\nSue 76: samoyeds: 9, perfumes: 1, trees: 6\nSue 77: trees: 6, perfumes: 10, cars: 7\nSue 78: trees: 0, children: 8, vizslas: 5\nSue 79: vizslas: 0, trees: 0, samoyeds: 1\nSue 80: trees: 6, goldfish: 8, perfumes: 0\nSue 81: samoyeds: 8, pomeranians: 6, akitas: 5\nSue 82: vizslas: 6, perfumes: 9, akitas: 4\nSue 83: cats: 0, vizslas: 3, pomeranians: 10\nSue 84: cars: 4, perfumes: 6, samoyeds: 5\nSue 85: vizslas: 7, trees: 5, goldfish: 7\nSue 86: goldfish: 2, trees: 2, vizslas: 1\nSue 87: trees: 6, goldfish: 10, pomeranians: 4\nSue 88: vizslas: 1, akitas: 0, perfumes: 8\nSue 89: goldfish: 8, akitas: 3, vizslas: 7\nSue 90: vizslas: 9, akitas: 7, perfumes: 9\nSue 91: children: 7, cars: 7, trees: 9\nSue 92: vizslas: 10, akitas: 8, goldfish: 1\nSue 93: goldfish: 7, vizslas: 2, pomeranians: 0\nSue 94: cats: 2, samoyeds: 6, pomeranians: 3\nSue 95: samoyeds: 4, children: 4, pomeranians: 10\nSue 96: pomeranians: 9, cats: 1, goldfish: 3\nSue" <> ...
Solution
defmodule Day16 do
defdelegate parse(input), to: __MODULE__.Input
@ticker_tape [
{"children", 3},
{"cats", 7},
{"samoyeds", 2},
{"pomeranians", 3},
{"akitas", 0},
{"vizslas", 0},
{"goldfish", 5},
{"trees", 3},
{"cars", 2},
{"perfumes", 1}
]
def part1(input) do
Enum.reduce(
@ticker_tape,
parse(input),
fn {name, count}, sue_list ->
Enum.reject(sue_list, fn {_sue_n, sue_map} ->
Map.has_key?(sue_map, name) && sue_map[name] != count
end)
end
)
|> then(fn [{sue_n, _}] -> sue_n end)
end
def part2(input) do
Enum.reduce(
@ticker_tape,
parse(input),
fn {name, count}, sue_list ->
Enum.filter(sue_list, fn {_sue_n, sue_map} ->
if Map.has_key?(sue_map, name) do
case name do
n when n in ~w(cats trees) -> sue_map[name] > count
n when n in ~w(pomeranians goldfish) -> sue_map[name] < count
_ -> sue_map[name] == count
end
else
true
end
end)
end
)
|> then(fn [{sue_n, _}] -> sue_n end)
end
defmodule Input do
def parse(input) when is_binary(input) do
input
|> String.split("\n")
|> parse()
end
def parse(input) when is_list(input) do
Enum.map(input, &parse_line/1)
end
def parse_line(line) do
line
|> String.split([": ", ", ", " "])
|> then(fn [_Sue, n | props] ->
{
String.to_integer(n),
props
|> Enum.chunk_every(2)
|> Enum.map(fn [k, v] -> {k, String.to_integer(v)} end)
|> Enum.into(%{})
}
end)
end
end
end
{:module, Day16, <<70, 79, 82, 49, 0, 0, 15, ...>>,
{:module, Day16.Input, <<70, 79, 82, ...>>, {:parse_line, 1}}}
What is the number of the Sue that got you the gift?
Your puzzle answer was 213.
Day16.part1(input)
213
What is the number of the real Aunt Sue?
Your puzzle answer was 323.
Day16.part2(input)
323
Both parts of this puzzle are complete! They provide two gold stars: **
At this point, you should return to your Advent calendar and try another puzzle.
If you still want to see it, you can get your puzzle input.
Benchmarking
# https://github.com/bencheeorg/benchee
Benchee.run(%{
"Part 1" => fn -> Day16.part1(input) end,
"Part 2" => fn -> Day16.part2(input) end
})
nil
Operating System: macOS
CPU Information: Apple M1 Pro
Number of Available Cores: 10
Available memory: 16 GB
Elixir 1.14.2
Erlang 25.1.2
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 14 s
Benchmarking Part 1 ...
Benchmarking Part 2 ...
Name ips average deviation median 99th %
Part 1 1.04 K 962.19 μs ±3.17% 949.88 μs 1061.49 μs
Part 2 1.02 K 982.69 μs ±3.20% 970.34 μs 1084.19 μs
Comparison:
Part 1 1.04 K
Part 2 1.02 K - 1.02x slower +20.50 μs
nil