Day 09
Mix.install([
{:kino, "~> 0.8.0"},
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
])
:ok
Input
{:ok, result} = KinoAOC.download_puzzle("2022", "9", System.fetch_env!("LB_AOC_SESSION"))
input = result
"R 2\nD 2\nU 2\nD 1\nL 1\nD 2\nR 2\nL 2\nR 1\nD 2\nL 1\nU 2\nR 1\nD 1\nR 1\nL 1\nD 1\nR 2\nU 2\nL 2\nR 2\nU 2\nR 1\nL 1\nD 2\nR 1\nD 1\nR 1\nD 1\nR 1\nL 2\nR 1\nD 1\nL 1\nU 2\nL 1\nD 1\nL 1\nR 1\nU 2\nD 1\nU 2\nL 2\nR 2\nD 1\nL 1\nR 1\nD 1\nL 1\nU 1\nR 2\nD 1\nR 1\nD 2\nL 1\nD 2\nL 1\nD 2\nR 1\nL 1\nD 2\nL 1\nR 1\nD 2\nL 2\nR 2\nL 1\nU 2\nR 1\nU 2\nR 2\nU 1\nD 1\nU 2\nL 1\nD 2\nL 2\nR 2\nL 1\nR 1\nU 2\nD 1\nR 1\nL 2\nU 1\nD 2\nU 1\nL 2\nR 2\nD 1\nU 1\nL 2\nU 2\nL 1\nR 1\nD 1\nR 2\nD 1\nR 1\nD 2\nR 1\nD 1\nR 1\nD 2\nL 2\nU 2\nL 1\nD 1\nL 1\nR 2\nU 1\nD 1\nU 2\nL 2\nD 3\nL 3\nU 3\nR 1\nD 3\nR 1\nD 3\nR 2\nD 2\nU 3\nD 2\nL 3\nR 3\nU 3\nR 1\nU 3\nD 3\nL 1\nD 2\nU 1\nR 2\nL 2\nR 3\nL 2\nD 3\nL 2\nR 1\nD 1\nU 1\nD 2\nR 2\nL 1\nU 1\nR 3\nU 2\nD 3\nL 3\nU 2\nL 3\nR 2\nD 2\nU 2\nR 1\nU 3\nR 2\nD 1\nU 2\nD 3\nU 2\nR 3\nU 2\nL 3\nU 3\nD 2\nR 3\nU 3\nL 3\nU 2\nL 1\nD 3\nL 2\nD 3\nR 3\nL 2\nR 3\nD 1\nU 1\nL 3\nR 3\nD 2\nL 3\nU 2\nR 2\nU 1\nR 3\nD 3\nR 1\nU 2\nL 2\nU 1\nR 1\nU 1\nD 2\nL 2\nR 1\nD 3\nR 1\nD 3\nU 1\nR 2\nU 2\nL 2\nU 2\nL 3\nD 3\nU 2\nL 3\nU 1\nL 2\nD 1\nU 3\nL 2\nR 3\nD 1\nR 3\nL 3\nU 1\nL 3\nR 2\nD 3\nU 3\nL 3\nD 4\nL 1\nU 1\nR 3\nL 1\nD 4\nU 4\nL 4\nD 4\nU 1\nD 3\nR 1\nD 4\nL 1\nU 2\nD 1\nR 3\nL 4\nD 2\nU 2\nR 1\nL 4\nU 4\nR 4\nD 1\nR 3\nD 1\nR 4\nU 4\nD 1\nU 3\nD 4\nL 3\nR 2\nD 4\nL 2\nU 4\nD 3\nU 4\nD 2\nU 2\nL 3\nR 4\nL 4\nU 2\nL 1\nU 4\nD 4\nR 4\nU 4\nR 2\nU 4\nR 1\nU 3\nR 3\nU 4\nR 4\nU 2\nL 1\nU 3\nD 4\nL 1\nR 1\nL 2\nR 2\nD 2\nU 3\nR 3\nL 1\nD 2\nR 4\nD 1\nR 4\nL 2\nU 4\nD 2\nR 4\nU 2\nD 4\nR 1\nU 3\nL 3\nD 2\nR 2\nU 1\nL 4\nR 1\nU 2\nR 4\nD 3\nR 1\nL 2\nU 1\nR 2\nL 2\nU 2\nR 3\nL 2\nD 4\nU 4\nL 1\nU 2\nD 1\nU 2\nD 1\nL 2\nR 4\nL 5\nD 2\nU 5\nL 1\nR 2\nL 3\nU 3\nD 3\nL 1\nD 1\nU 4\nL 4\nU 3\nD 5\nR 1\nL 4\nU 1\nL 2\nR 4\nD 1\nL 4\nD 1\nU 4\nD 1\nL 2\nD 5\nL 5\nD 4\nR 3\nU 2\nL 4\nU 4\nL 4\nR 5\nD 1\nL 2\nR 5\nU 4\nD 5\nL 2\nU 4\nD 1\nL 3\nR 5\nD 4\nL 1\nD 3\nL 3\nU 2\nR 2\nD 4\nL 4\nU 1\nD 2\nL 5\nD 2\nL 2\nU 3\nR 3\nU 3\nD 2\nU 4\nR 3\nL 3\nD 2\nL 2\nR 3\nD 2\nL 3\nR 4\nU 4\nR 4\nD 2\nR 1\nD 1\nL 4\nR 4\nD 3\nR 2\nU 4\nL 2\nD 3\nU 4\nL 3\nR 5\nL 2\nR 1\nD 4\nL 5\nD 2\nU 5\nL 4\nU 2\nR 3\nL 4\nR 1\nU 3\nR 3\nL 2\nU 2\nL 3\nR 5\nL 3\nR 3\nU 3\nL 3\nU 5\nD 4\nU 5\nD 4\nL 4\nD 2\nR 5\nL 3\nU 2\nD 3\nL 4\nR 1\nD 1\nR 5\nL 3\nR 2\nL 3\nU 3\nD 1\nU 5\nR 2\nL 2\nD 5\nR 3\nU 4\nR 3\nL 1\nR 6\nL 4\nD 4\nU 4\nR 4\nU 2\nR 4\nD 1\nU 3\nR 1\nU 5\nD 3\nL 4\nR 5\nL 3\nU 6\nL 5\nD 3\nR 1\nD 2\nU 5\nL 1\nR 5\nU 4\nR 1\nU 1\nR 3\nL 2\nD 5\nU 4\nL 1\nU 2\nR 3\nL 5\nR 2\nD 3\nU 3\nD 6\nR 1\nD 2\nL 3\nR 3\nL 3\nU 4\nR 4\nU 4\nR 6\nU 1\nL 6\nR 6\nL 4\nU 6\nL 2\nD 1\nR 5\nL 5\nU 3\nD 6\nU 5\nL 4\nU 2\nR 1\nL 3\nD 6\nU 5\nR 4\nU 2\nD 3\nR 4\nL 1\nD 4\nU 6\nR 1\nD 6\nU 2\nD 5\nU 4\nL 4\nR 6\nD 2\nR 6\nL 1\nR 3\nD 4\nR 5\nL 6\nU 5\nL 3\nR 6\nU 1\nL 3\nD 7\nU 2\nD 5\nR 5\nD 7\nR 6\nD 6\nR 7\nD 7\nL 3\nR 4\nL 1\nU 6\nR 2\nL 7\nU 7\nD 1\nR 1\nD 1\nU 5\nR 4\nU 2\nD 5\nU 6\nL 2\nR 1\nU 5\nL 1\nU 7\nR 1\nD 2\nL 4\nD 4\nL 5\nU 4\nL 2\nD 5\nR 7\nD 7\nR 5\nL 3\nU 7\nR 7\nD 1\nL 2\nU 3\nL 2\nU 7\nL 2\nU 3\nL 6\nD 6\nL 2\nD 6\nL 6\nU 3\nL 3\nU 7\nD 3\nL 4\nU 5\nD 5\nL 4\nD 7\nU 3\nR 7\nD 5\nR 3\nL 6\nU 2\nL 2\nU 1\nL 1\nU 4\nD 7\nL 7\nD 2\nU 6\nL 2\nU 2\nL 4\nR 3\nL 6\nR 2\nD 7\nL 6\nD 3\nL 6\nR 1\nU 4\nR 6\nL 7\nD 7\nR 4\nU 7\nL 6\nR 3\nD 1\nU 3\nD 2\nU 3\nR 2\nL 7\nU 1\nR 4\nD 4\nU 2\nR 5\nD 5\nR 4\nL 3\nU 1\nR 7\nL 5\nD 4\nL 3\nD 7\nU 2\nD 4\nU 4\nL 1\nD 4\nR 7\nL 6\nU 3\nL 4\nD 5\nU 1\nD 1\nL 6\nR 7\nD 1\nL 4\nD 1\nL 5\nR 8\nD 4\nL 8\nR 4\nD 4\nU 3\nL 5\nR 5\nL 8\nU 4\nR 2\nD 6\nR 5\nL 1\nU 8\nL 1\nD 5\nU 5\nD 4\nL 6\nU 6\nD 8\nR 6\nD 3\nU 7\nR 8\nD 7\nL 2\nU 4\nD 4\nL 2\nR 2\nU 5\nL 4\nR 3\nL 2\nU 5\nD 8\nL 8\nD 3\nU 4\nD 2\nL 2\nU 4\nR 5\nL 6\nU 4\nR 5\nU 4\nL 7\nD 8\nR 8\nD 7\nR 5\nD 6\nU 2\nR 1\nD 3\nL 6\nU 3\nD 5\nU 6\nL 7\nR 1\nL 4\nR 4\nL 4\nR 3\nL 4\nU 3\nD 7\nU 8\nD 4\nR 6\nL 7\nR 2\nL 2\nU 7\nD 2\nR 1\nD 5\nU 1\nD 7\nR 2\nL 8\nR 8\nU 4\nR 9\nL 4\nR 5\nL 2\nD 6\nL 9\nU 2\nR 5\nD 4\nR 9\nU 4\nD 8\nR 9\nU 5\nD 4\nU 4\nL 4\nU 3\nR 5\nL 8\nD 9\nU 2\nL 8\nU 5\nD 4\nL 1\nD 4\nU 3\nD 7\nU 5\nD 5\nR 9\nL 2\nD 5\nL 7\nD 1\nL 2\nR 6\nD 9\nU 1\nL 6\nR 2\nD 2\nR 5\nD 8\nR 2\nD 3\nL 4\nD 5\nR 2\nD 8\nL 3\nD 6\nU 2\nL 4\nD 9\nL 6\nR 5\nL 7\nU 2\nD 8\nU 5\nL 6\nU 1\nL 9\nR 9\nD 1\nR 3\nU 9\nL 2\nU 8\nR 8\nD 8\nR 7\nU 7\nR 6\nL 2\nU 4\nD 2\nL 4\nU 4\nD 2\nR 8\nL 6\nR 9\nD 9\nL 6\nD 4\nL 5\nU 8\nD 2\nR 6\nD 7\nU 3\nR 6\nL 9\nU 6\nL 8\nU 8\nD 6\nU 9\nD 5\nU 8\nL 6\nR 6\nL 6\nR 9\nL 2\nU 4\nL 4\nU 1\nD 4\nR 1\nU 7\nD 5\nR 4\nU 4\nD 5\nL 9\nR 2\nU 5\nL 2\nR 10\nL 5\nR 1\nL 2\nU 3\nD 2\nR 7\nL 2\nR 6\nL 3\nR 6\nU 7\nL 1\nU 6\nR 6\nU 2\nL 3\nR 3\nL 1\nR 9\nL 5\nU 9\nL 9\nD 9\nU 4\nD 2\nR 6\nD 6\nR 8\nD 2\nU 6\nL 5\nR 2\nU 10\nL 3\nD 6\nR 3\nD 6\nU 2\nD 7\nR 1\nU 7\nD 2\nR 8\nL 5\nU 4\nL 5\nR 6\nU 6\nD 1\nL 5\nD 5\nR 5\nD 4\nL 5\nU 3\nR 4\nL 5\nR 2\nL 5\nD 10\nR 4\nL 2\nR 4\nL 7\nU 9\nR 3\nD 6\nR 7\nL 10\nD 7\nU 4\nL 9\nD 6\nL 7\nR 3\nU 7\nR 5\nU 6\nL 1\nU 2\nL 5\nD 6\nR 8\nL 7\nR 7\nD 1\nU 9\nR 1\nL 4\nU 4\nR 1\nL 3\nD 2\nL 8\nD 10\nL 9\nD 8\nR 5\nD 6\nL 7\nD 2\nU 11\nD 2\nU 6\nL 3\nU 8\nD 11\nU 9\nD 9\nR 11\nU 11\nL 8\nU 11\nR 11\nU 2\nD 6\nR 11\nD 7\nL 6\n" <> ...
Part 1
defmodule PartOne do
def resolve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn x -> String.split(x, "", trim: true) end)
|> then(fn x ->
max_row = Enum.count(x)
max_col = Enum.at(x, 0) |> Enum.count()
Enum.with_index(x, fn element, row_index ->
Enum.with_index(element, fn _tree, col_index ->
if row_index == 0 or row_index == max_row - 1 or col_index == 0 or
col_index == max_col - 1 do
true
else
check_visible(x, row_index, col_index)
end
end)
end)
end)
|> Enum.reduce(0, fn row, count ->
count +
Enum.reduce(row, 0, fn tree, c ->
if tree do
c + 1
else
c
end
end)
end)
end
defp check_visible(x, row_index, col_index) do
row = Enum.at(x, row_index)
row_left = row |> Enum.slice(0..(col_index - 1))
row_right = row |> Enum.slice((col_index + 1)..(Enum.count(x) - 1))
elem = row |> Enum.at(col_index)
col = Enum.map(x, fn x -> Enum.at(x, col_index) end)
col_top = col |> Enum.slice(0..(row_index - 1))
col_bottom = col |> Enum.slice((row_index + 1)..(Enum.count(col) - 1))
visible =
is_visible(row_left, elem) || is_visible(row_right, elem) ||
is_visible(col_top, elem) || is_visible(col_bottom, elem)
visible
end
defp is_visible(row, elem) do
Enum.all?(row, fn x -> x < elem end)
end
end
{:module, PartOne, <<70, 79, 82, 49, 0, 0, 19, ...>>, {:is_visible, 2}}
input
|> PartOne.resolve()
--- Part One ---
Result: 1789
:ok
ExUnit.start(autorun: false)
defmodule PartOneTest do
use ExUnit.Case, async: true
import PartOne
test "part one" do
input = "30373
25512
65332
33549
35390"
result = run(input)
assert result == 21
end
end
ExUnit.run()
.
Finished in 0.00 seconds (0.00s async, 0.00s sync)
1 test, 0 failures
Randomized with seed 61016
%{excluded: 0, failures: 0, skipped: 0, total: 1}
Part 2
defmodule PartTwo do
def resolve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn x ->
String.split(x, "", trim: true)
|> Enum.map(fn x -> String.to_integer(x) end)
end)
|> then(fn x ->
max_row = Enum.count(x)
max_col = Enum.at(x, 0) |> Enum.count()
Enum.with_index(x, fn element, row_index ->
Enum.with_index(element, fn _tree, col_index ->
if row_index == 0 or row_index == max_row - 1 or col_index == 0 or
col_index == max_col - 1 do
0
else
calc_score(x, row_index, col_index)
end
end)
end)
end)
|> Enum.map(fn row -> Enum.max(row) end)
|> Enum.max()
end
defp calc_score(x, row_index, col_index) do
row = Enum.at(x, row_index)
row_left = row |> Enum.slice(0..(col_index - 1)) |> Enum.reverse()
row_right = row |> Enum.slice((col_index + 1)..(Enum.count(x) - 1))
elem = row |> Enum.at(col_index)
col = Enum.map(x, fn x -> Enum.at(x, col_index) end)
col_top = col |> Enum.slice(0..(row_index - 1)) |> Enum.reverse()
col_bottom = col |> Enum.slice((row_index + 1)..(Enum.count(col) - 1))
scenic_score =
[
count_visible(row_left, elem),
count_visible(row_right, elem),
count_visible(col_top, elem),
count_visible(col_bottom, elem)
]
|> Enum.reduce(1, fn x, acc -> acc * x end)
scenic_score
end
defp count_visible([], _elem) do
0
end
defp count_visible(row, elem) do
Enum.reduce_while(row, 0, fn x, acc ->
cond do
x < elem -> {:cont, acc + 1}
true -> {:halt, acc + 1}
end
end)
end
end
{:module, PartTwo, <<70, 79, 82, 49, 0, 0, 19, ...>>, {:count_visible, 2}}
input
|> PartTwo.resolve()
--- Part One ---
Result: 314820
:ok
ExUnit.start(autorun: false)
defmodule PartTwoTest do
use ExUnit.Case, async: true
import PartTwo
test "part one" do
input = "30373
25512
65332
33549
35390"
result = run(input)
assert result == 8
end
end
ExUnit.run()
.
Finished in 0.00 seconds (0.00s async, 0.00s sync)
1 test, 0 failures
Randomized with seed 61016
%{excluded: 0, failures: 0, skipped: 0, total: 1}