Advent of Code 2021 - Day 11
Mix.install([
{:kino, "~> 0.6.1"}
])
Instructions
https://adventofcode.com/2021/day/11
Test Input
test_input = """
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
"""
Puzzle Input
Paste your own input from Advent of Code or copy from sdball 2021 Advent of Code Day 11 input
puzzle_input = Kino.Input.textarea("Please paste your Day 11 puzzle input:")
puzzle_input = Kino.Input.read(puzzle_input)
Input Parsing
defmodule Octopus do
def energy_map(input) do
energy_readings =
input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
String.split(line, "", trim: true)
|> Enum.map(&String.to_integer/1)
end)
for {line, row} <- Enum.with_index(energy_readings),
{energy, column} <- Enum.with_index(line),
into: %{} do
{{row, column}, energy}
end
end
def next(energy_map) do
next(Map.keys(energy_map), energy_map, MapSet.new())
end
def next([key | keys], energy_map, flashes) do
energy_level = energy_map[key]
cond do
is_nil(energy_level) or key in flashes ->
next(keys, energy_map, flashes)
energy_level >= 9 ->
flashes = MapSet.put(flashes, key)
energy_map = Map.put(energy_map, key, 0)
keys = directions(key) ++ keys
next(keys, energy_map, flashes)
true ->
next(keys, Map.put(energy_map, key, energy_level + 1), flashes)
end
end
def next([], energy_map, flashes) do
{energy_map, MapSet.size(flashes)}
end
def inspect({energy_map, flashes}) do
for row <- 0..9 do
IO.puts(for column <- 0..9, do: energy_map[{row, column}] + ?0)
end
IO.inspect(flashes, label: "flashes")
IO.puts("")
energy_map
end
defp directions({row, column}) do
ul = {row - 1, column - 1}
u = {row - 1, column}
ur = {row - 1, column + 1}
l = {row, column - 1}
r = {row, column + 1}
dl = {row + 1, column - 1}
d = {row + 1, column}
dr = {row + 1, column + 1}
[ul, u, ur, l, r, dl, d, dr]
end
end
Part 1 - Test Input
test_input
|> Octopus.energy_map()
|> Octopus.next()
|> Octopus.inspect()
|> Octopus.next()
|> Octopus.inspect()
energy_map = Octopus.energy_map(test_input)
1..10
|> Enum.map_reduce(energy_map, fn _iteration, energy_map ->
{energy_map, flashes} = Octopus.next(energy_map)
{flashes, energy_map}
end)
|> elem(0)
|> Enum.sum()
energy_map = Octopus.energy_map(test_input)
1..100
|> Enum.map_reduce(energy_map, fn _iteration, energy_map ->
{energy_map, flashes} = Octopus.next(energy_map)
{flashes, energy_map}
end)
|> elem(0)
|> Enum.sum()
Part 1 - Puzzle Input
energy_map = Octopus.energy_map(puzzle_input)
1..100
|> Enum.map_reduce(energy_map, fn _iteration, energy_map ->
{energy_map, flashes} = Octopus.next(energy_map)
{flashes, energy_map}
end)
|> elem(0)
|> Enum.sum()
Part 2 - Test Input
Stream.iterate(1, &(&1 + 1))
|> Enum.reduce_while(Octopus.energy_map(test_input), fn step, energy_map ->
{energy_map, flashes} = Octopus.next(energy_map)
case flashes do
100 -> {:halt, step}
_ -> {:cont, energy_map}
end
end)
Part 2 - Puzzle Input
Stream.iterate(1, &(&1 + 1))
|> Enum.reduce_while(Octopus.energy_map(puzzle_input), fn step, energy_map ->
{energy_map, flashes} = Octopus.next(energy_map)
case flashes do
100 -> {:halt, step}
_ -> {:cont, energy_map}
end
end)