Skip to content

Commit

Permalink
2024 day 10, both parts
Browse files Browse the repository at this point in the history
I love when part 2 just falls out from doing part 1
  • Loading branch information
sevenseacat committed Dec 10, 2024
1 parent 5138af9 commit 72d293d
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 3 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
My Elixir solutions for [Advent of Code](https://adventofcode.com/) (all years).

<!-- stars start -->
<p><img src="https://img.shields.io/static/v1?label=Total&message=437%20stars&style=for-the-badge&color=green" alt="437 stars" /></p>
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=18%20stars&style=for-the-badge&color=orange" alt="18 stars" /></a><br />
<p><img src="https://img.shields.io/static/v1?label=Total&message=439%20stars&style=for-the-badge&color=green" alt="439 stars" /></p>
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=20%20stars&style=for-the-badge&color=orange" alt="20 stars" /></a><br />
<a href="./lib/y2023/"><img src="https://img.shields.io/static/v1?label=2023&message=44%20stars&style=for-the-badge&color=green" alt="44 stars" /></a><br />
<a href="./lib/y2022/"><img src="https://img.shields.io/static/v1?label=2022&message=%E2%AD%90%EF%B8%8F%2050%20stars%20%E2%AD%90%EF%B8%8F&style=for-the-badge&color=brightgreen" alt="50 stars" /></a><br />
<a href="./lib/y2021/"><img src="https://img.shields.io/static/v1?label=2021&message=46%20stars&style=for-the-badge&color=green" alt="46 stars" /></a><br />
Expand Down
13 changes: 13 additions & 0 deletions lib/advent/grid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ defmodule Advent.Grid do
|> Enum.reduce(Map.new(), &parse_row/2)
end

def use_number_values(grid) do
grid
|> Enum.map(fn {coord, val} -> {coord, maybe_integer(val)} end)
|> Map.new()
end

defp maybe_integer(val) do
case Integer.parse(val) do
:error -> val
{num, _} -> num
end
end

def size(grid) do
coords = Map.keys(grid)
{row, _} = Enum.max_by(coords, &elem(&1, 0))
Expand Down
4 changes: 3 additions & 1 deletion lib/y2024/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

My Elixir solutions for [Advent of Code 2024](https://adventofcode.com/2024).

<!-- stars 2024 start --><img src="https://img.shields.io/static/v1?label=2024&message=18%20stars&style=for-the-badge&color=orange" alt="18 stars" /><!-- stars 2024 end -->
<!-- stars 2024 start --><img src="https://img.shields.io/static/v1?label=2024&message=20%20stars&style=for-the-badge&color=orange" alt="20 stars" /><!-- stars 2024 end -->

## Benchmarks

Expand Down Expand Up @@ -32,4 +32,6 @@ day 08, part 1 1.07 K 0.93 ms ±6.91% 0.90 ms 1.
day 08, part 2 0.83 K 1.20 ms ±7.78% 1.17 ms 1.38 ms
day 09, part 1 9.26 108.03 ms ±0.66% 107.88 ms 111.50 ms
day 09, part 2 7.28 137.37 ms ±0.68% 137.22 ms 139.75 ms
day 10, part 1 3.85 259.55 ms ±0.92% 259.35 ms 263.61 ms
day 10, part 2 4.18 239.36 ms ±0.50% 238.98 ms 241.62 ms
```
67 changes: 67 additions & 0 deletions lib/y2024/day10.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
defmodule Y2024.Day10 do
use Advent.Day, no: 10

alias Advent.Grid

def part1({grid, path_grid}) do
destinations = Enum.filter(grid, &destination?/1)

grid
|> Enum.filter(&trailhead?/1)
|> Task.async_stream(&find_trailhead_score(&1, path_grid, destinations))
|> Enum.reduce(0, fn {:ok, num}, acc -> acc + num end)
end

def part2({grid, path_grid}) do
destinations = Enum.filter(grid, &destination?/1)

grid
|> Enum.filter(&trailhead?/1)
|> Task.async_stream(&find_trailhead_rating(&1, path_grid, destinations))
|> Enum.reduce(0, fn {:ok, num}, acc -> acc + num end)
end

def parse_input(input) do
grid = input |> Grid.new() |> Grid.use_number_values()
{grid, to_path_grid(grid)}
end

defp to_path_grid(grid) do
Enum.reduce(Map.keys(grid), Graph.new(vertex_identifier: & &1), fn from, graph ->
Enum.reduce(find_valid_movements(grid, from), graph, fn to, graph ->
graph
|> Graph.add_vertices([from, to])
|> Graph.add_edge(from, to)
end)
end)
end

defp trailhead?({_coord, val}), do: val == 0
defp destination?({_coord, val}), do: val == 9

defp find_trailhead_score({coord, _}, path_grid, destinations) do
Enum.count(destinations, fn {dest_coord, _} ->
Graph.get_shortest_path(path_grid, coord, dest_coord) != nil
end)
end

defp find_trailhead_rating({coord, _}, path_grid, destinations) do
Enum.reduce(destinations, 0, fn {dest_coord, _}, count ->
count + (Graph.get_paths(path_grid, coord, dest_coord) |> length)
end)
end

defp find_valid_movements(map, {row, col}) do
case Map.get(map, {row, col}) do
"." ->
[]

value ->
[{row + 1, col}, {row - 1, col}, {row, col - 1}, {row, col + 1}]
|> Enum.filter(fn coord -> Map.get(map, coord) == value + 1 end)
end
end

def part1_verify, do: input() |> parse_input() |> part1()
def part2_verify, do: input() |> parse_input() |> part2()
end
Binary file added lib/y2024/input/day10.txt
Binary file not shown.
67 changes: 67 additions & 0 deletions test/y2024/day10_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
defmodule Y2024.Day10Test do
use ExUnit.Case, async: true
alias Y2024.Day10
doctest Day10

describe "part 1" do
test "sample 1" do
input = """
...0...
...1...
...2...
6543456
7.....7
8.....8
9.....9
"""

assert Day10.parse_input(input) |> Day10.part1() == 2
end

test "sample 2" do
input = """
..90..9
...1.98
...2..7
6543456
765.987
876....
987....
"""

assert Day10.parse_input(input) |> Day10.part1() == 4
end

test "sample 3" do
input = """
10..9..
2...8..
3...7..
4567654
...8..3
...9..2
.....01
"""

assert Day10.parse_input(input) |> Day10.part1() == 3
end

test "sample 4" do
input = """
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
"""

assert Day10.parse_input(input) |> Day10.part1() == 36
end
end

test "verification, part 1", do: assert(Day10.part1_verify() == 638)
test "verification, part 2", do: assert(Day10.part2_verify() == 1289)
end

0 comments on commit 72d293d

Please sign in to comment.