Finished day 8

This commit is contained in:
Erwin Boskma 2023-01-02 18:36:35 +01:00
parent 495024e66d
commit 3e2e3eb9d4
Signed by: erwin
SSH key fingerprint: SHA256:CyeNoWXd3kjX2Nwu6pDxxdS7OqmPVOy0NavA/KU/ntU
4 changed files with 289 additions and 6 deletions

View file

@ -18,4 +18,5 @@ Day 6: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Fao
Day 7: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Faoc2022%2Fraw%2Fbranch%2Fmain%2Fday7.livemd][Run in Livebook]]
Day 8: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Faoc2022%2Fraw%2Fbranch%2Fmain%2Fday8.livemd][Run in Livebook]]

276
day8.livemd Normal file
View file

@ -0,0 +1,276 @@
# AOC 2022 - Day 8
```elixir
Mix.install(
[
{:req, "~> 0.3.3"},
{:nx, "~> 0.4.1"},
{:exla, "~> 0.4.1"}
],
config: [nx: [default_backend: EXLA.Backend]]
)
```
## Puzzle description
[Day 8: Treetop Tree House](https://adventofcode.com/2022/day/8).
## Input
```elixir
defmodule Load do
def input do
aoc_session = System.fetch_env!("LB_AOC_SESSION")
input_url = "https://adventofcode.com/2022/day/8/input"
Req.get!(input_url, headers: [cookie: "session=#{aoc_session}"]).body
end
end
```
## Solution
```elixir
defmodule Util do
def process(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn row ->
row
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
end)
end
def process2(input) do
input
|> String.split()
|> Enum.with_index()
|> Enum.flat_map(&parse_line/1)
|> Map.new(fn {v, k} -> {k, v} end)
end
defp parse_line({string, row}) do
string
|> String.graphemes()
|> Enum.with_index()
|> Enum.map(fn {char, column} ->
{String.to_integer(char), {row + 1, column + 1}}
end)
end
def count_visible(line) do
line
|> Enum.with_index()
|> Enum.map_reduce(0, fn {h, n}, max ->
cond do
n == 0 ->
{true, h}
h <= max ->
{false, max}
true ->
{true, h}
end
end)
|> elem(0)
end
def transpose(v) do
v
|> List.zip()
|> Enum.map(&Tuple.to_list/1)
end
def score(trees, row, column, rows, columns) do
left_score(trees, row, column, rows, columns) *
right_score(trees, row, column, rows, columns) *
up_score(trees, row, column, rows, columns) *
down_score(trees, row, column, rows, columns)
end
defp left_score(trees, row, column, _rows, _columns) do
list =
for c <- (column - 1)..1 do
trees[{row, c}]
end
|> Enum.with_index()
len = length(list)
list
|> Enum.reduce_while(1, fn {height, position}, score ->
if trees[{row, column}] > height and position + 1 != len,
do: {:cont, score + 1},
else: {:halt, score}
end)
end
defp right_score(trees, row, column, _rows, columns) do
list =
for c <- (column + 1)..columns do
trees[{row, c}]
end
|> Enum.with_index()
len = length(list)
list
|> Enum.reduce_while(1, fn {height, position}, score ->
if trees[{row, column}] > height and position + 1 != len,
do: {:cont, score + 1},
else: {:halt, score}
end)
end
defp up_score(trees, row, column, _rows, _columns) do
list =
for r <- (row - 1)..1 do
trees[{r, column}]
end
|> Enum.with_index()
len = length(list)
list
|> Enum.reduce_while(1, fn {height, position}, score ->
if trees[{row, column}] > height and position + 1 != len,
do: {:cont, score + 1},
else: {:halt, score}
end)
end
defp down_score(trees, row, column, rows, _columns) do
list =
for r <- (row + 1)..rows do
trees[{r, column}]
end
|> Enum.with_index()
len = length(list)
list
|> Enum.reduce_while(1, fn {height, position}, score ->
if trees[{row, column}] > height and position + 1 != len,
do: {:cont, score + 1},
else: {:halt, score}
end)
end
end
```
```elixir
defmodule Part1 do
def run(input) do
trees =
input
|> Util.process()
{trees, horizontal} =
trees
|> Enum.map_reduce([], fn line, acc ->
visible =
[
Util.count_visible(line),
line |> Enum.reverse() |> Util.count_visible() |> Enum.reverse()
]
|> Enum.zip()
|> Enum.map(&(elem(&1, 0) or elem(&1, 1)))
{line, [visible | acc]}
end)
|> then(fn {trees, horizontal} ->
{trees, Enum.reverse(horizontal)}
end)
{_, vertical} =
trees
|> Util.transpose()
|> Enum.map_reduce([], fn col, acc ->
visible =
[
Util.count_visible(col),
col |> Enum.reverse() |> Util.count_visible() |> Enum.reverse()
]
|> Enum.zip()
|> Enum.map(&(elem(&1, 0) or elem(&1, 1)))
{col, [visible | acc]}
end)
|> then(fn {trees, vertical} ->
{trees, Enum.reverse(vertical) |> Util.transpose()}
end)
horizontal
|> Enum.zip(vertical)
|> Enum.map(fn {h, v} ->
h
|> Enum.zip(v)
|> Enum.map(&(elem(&1, 0) or elem(&1, 1)))
end)
|> Enum.map(fn line ->
Enum.count(line, & &1)
end)
|> Enum.sum()
end
end
defmodule Part2 do
def run(input) do
trees = Util.process2(input)
{rows, columns} =
trees
|> Map.keys()
|> Enum.max()
for i <- 2..(rows - 1), j <- 2..(columns - 1) do
{i, j, Util.score(trees, i, j, rows, columns)}
end
|> Enum.max_by(fn {_, _, x} -> x end)
|> elem(2)
end
end
ExUnit.start(autorun: false)
defmodule Test do
use ExUnit.Case, async: true
@example_input ~s(30373
25512
65332
33549
35390)
@input Load.input()
test "it loads the input" do
assert String.length(@input) > 0
end
test "part 1 example" do
assert Part1.run(@example_input) === 21
end
test "part 1" do
assert Part1.run(@input) === 1816
end
test "part 2 example" do
assert Part2.run(@example_input) === 8
end
test "part 2" do
assert Part2.run(@input) === 0
end
end
ExUnit.run()
# [
#    [1, 1, 1, 1, 1],
#    [1, 1, 1, 0, 1],
#    [1, 1, 0, 1, 1],
#    [1, 0, 1, 0, 1],
#    [1, 1, 1, 1, 1]
#  ]
```

View file

@ -4,6 +4,7 @@ packages = [
"libnotify",
"inotify-tools",
"gnumake",
"gcc",
"taplo",
]
@ -55,3 +56,8 @@ value = "9091"
name = "mix"
package = "elixir_1_14"
help = "mix"
[[commands]]
name = "livebook"
command = "livebook $@"
help = "livebook"

View file

@ -10,11 +10,11 @@
]
},
"locked": {
"lastModified": 1667210711,
"narHash": "sha256-IoErjXZAkzYWHEpQqwu/DeRNJGFdR7X2OGbkhMqMrpw=",
"lastModified": 1671489820,
"narHash": "sha256-qoei5HDJ8psd1YUPD7DhbHdhLIT9L2nadscp4Qk37uk=",
"owner": "numtide",
"repo": "devshell",
"rev": "96a9dd12b8a447840cc246e17a47b81a4268bba7",
"rev": "5aa3a8039c68b4bf869327446590f4cdf90bb634",
"type": "github"
},
"original": {
@ -56,11 +56,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1670597555,
"narHash": "sha256-/k939P2S2246G6K5fyvC0U2IWvULhb4ZJg9K7ZxsX+k=",
"lastModified": 1672350804,
"narHash": "sha256-jo6zkiCabUBn3ObuKXHGqqORUMH27gYDIFFfLq5P4wg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2dea0f4c2d6e4603f54b2c56c22367e77869490c",
"rev": "677ed08a50931e38382dbef01cba08a8f7eac8f6",
"type": "github"
},
"original": {