Day 18
Mix.install([
{:kino, "~> 0.14.2"}
])
IEx.Helpers.c("/Users/johnb/dev/2015adventOfCode/advent_of_code.ex")
alias AdventOfCode, as: AOC
alias Kino.Input
require Integer
# Note: when making the next template, something like this works well:
# `cat day01.livemd | sed 's/01/02/' > day02.livemd`
#
Installation and Data
input_p1example = Kino.Input.textarea("Example Data")
input_p1puzzleInput = Kino.Input.textarea("Puzzle Input")
input_source_select =
Kino.Input.select("Source", [{:example, "example"}, {:puzzle_input, "puzzle input"}])
p1data = fn ->
(Kino.Input.read(input_source_select) == :example &&
Kino.Input.read(input_p1example)) ||
Kino.Input.read(input_p1puzzleInput)
end
Solution
defmodule Day18 do
@on "#"
@off "."
def count_on_cells(grid, cell_ids) do
cell_ids
|> Enum.filter(fn cell_id -> grid[cell_id] == @on end)
|> Enum.count()
end
def live_or_die?(grid, cell_id) do
cell = grid[cell_id]
neighbor_ids = AOC.neighbors8(grid, cell_id)
on_count = count_on_cells(grid, neighbor_ids)
case {cell, on_count} do
{@on, 2} -> @on
{@on, 3} -> @on
{@off, 3} -> @on
_ -> @off
end
end
def iterate_life(grid) do
grid
|> AOC.grid_cells()
|> Enum.reduce(grid, fn cell_id, acc ->
Map.put(acc, cell_id, live_or_die?(grid, cell_id))
end)
end
def solve1(text) do
grid = AOC.as_grid(text)
steps = (grid.grid_width < 20) && 4 || 100
updated = Enum.reduce((1..steps), grid, fn step, acc ->
acc = iterate_life(acc)
# IO.puts("=== #{step}")
# IO.puts(AOC.to_text_grid(acc))
acc
end)
count_on_cells(updated, AOC.grid_cells(updated))
end
def corners_stuck_on(grid) do
grid
|> Map.put(0, @on)
|> Map.put(grid.grid_width - 1, @on)
|> Map.put(grid.last_cell - grid.grid_width + 1, @on)
|> Map.put(grid.last_cell, @on)
end
def solve2(text) do
grid = text
|> AOC.as_grid()
|> corners_stuck_on()
steps = (grid.grid_width < 20) && 5 || 100
# IO.puts("=== 0\n#{AOC.to_text_grid(grid)}")
updated = (1..steps)
|> Enum.reduce(grid, fn step, acc ->
acc = acc
|> iterate_life()
|> corners_stuck_on()
# IO.puts("=== #{step}")
# IO.puts(AOC.to_text_grid(acc))
acc
end)
|> corners_stuck_on()
count_on_cells(updated, AOC.grid_cells(updated))
end
end
# Example data:
# .#.#.#
# ...##.
# #....#
# ..#...
# #.#..#
# ####..
p1data.()
|> Day18.solve1()
|> IO.inspect(label: "\n*** Part 1 solution (example: 4)")
# 1061
p1data.()
|> Day18.solve2()
|> IO.inspect(label: "\n*** Part 2 solution (example: 17)")
# 1006