Skip to content

Commit

Permalink
2024 day 19 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenseacat committed Dec 19, 2024
1 parent 9218b5c commit 045c123
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 28 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=454%20stars&style=for-the-badge&color=green" alt="454 stars" /></p>
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=35%20stars&style=for-the-badge&color=yellow" alt="35 stars" /></a><br />
<p><img src="https://img.shields.io/static/v1?label=Total&message=455%20stars&style=for-the-badge&color=green" alt="455 stars" /></p>
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=36%20stars&style=for-the-badge&color=yellow" alt="36 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
5 changes: 3 additions & 2 deletions 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=35%20stars&style=for-the-badge&color=yellow" alt="35 stars" /><!-- stars 2024 end -->
<!-- stars 2024 start --><img src="https://img.shields.io/static/v1?label=2024&message=36%20stars&style=for-the-badge&color=yellow" alt="36 stars" /><!-- stars 2024 end -->

## Benchmarks

Expand Down Expand Up @@ -48,5 +48,6 @@ day 16, part 2 13.07 76.51 ms ±5.00% 76.09 ms 85.
day 17, part 1 45.64 K 21.91 μs ±15.81% 21.17 μs 37.50 μs
day 18, part 1 22.53 44.38 ms ±5.11% 44.48 ms 48.54 ms
day 18, part 2 4.04 247.58 ms ±3.18% 247.68 ms 260.90 ms
day 19, part 1 19.46 51.38 ms ±1.08% 51.16 ms 53.08 ms
day 19, part 1 4.30 232.82 ms ±1.78% 230.67 ms 240.83 ms
day 19, part 2 4.31 232.07 ms ±0.63% 231.50 ms 236.27 ms
```
60 changes: 39 additions & 21 deletions lib/y2024/day19.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,61 @@ defmodule Y2024.Day19 do

def part1(%{from: from_towels, to: to_towels}) do
Enum.count(to_towels, fn to ->
can_make?(to, from_towels)
ways_to_make(to, from_towels) != 0
end)
end

# @doc """
# iex> Day19.part2("update or delete me")
# "update or delete me"
# """
# def part2(input) do
# input
# end
def part2(%{from: from_towels, to: to_towels}) do
Enum.map(to_towels, fn to ->
ways_to_make(to, from_towels)
end)
|> Enum.sum()
end

defp can_make?(to, from_towels) do
find_towel_list([{to, []}], from_towels) != nil
def ways_to_make(to, from_towels) do
queue = add_to_queue(PriorityQueue.new(), to)
find_towel_list(queue, from_towels, %{})
end

defp find_towel_list([], _from_towels), do: nil
defp find_towel_list([{[], made} | _rest], _from_towels), do: Enum.reverse(made)
defp add_to_queue(queue, item) do
PriorityQueue.push(queue, item, -String.length(item))
end

defp find_towel_list([{to, made} | rest], from_towels) do
new =
from_towels
|> Enum.filter(fn from -> List.starts_with?(to, from) end)
|> Enum.map(fn from -> {Enum.drop(to, length(from)), [from | made]} end)
def find_towel_list(queue, from_towels, seen) do
do_find_towel_list(PriorityQueue.pop(queue), from_towels, seen)
end

defp do_find_towel_list({:empty, _queue}, _from_towels, _seen), do: 0

find_towel_list(new ++ rest, from_towels)
defp do_find_towel_list({{:value, ""}, _queue}, _from_towels, seen), do: Map.fetch!(seen, "")

defp do_find_towel_list({{:value, to}, queue}, from_towels, seen) do
{seen, queue} =
from_towels
|> Enum.filter(fn from -> String.starts_with?(to, from) end)
|> Enum.reduce({seen, queue}, fn from, {seen, queue} ->
rest = String.slice(to, String.length(from), 1000)
to_count = Map.get(seen, to, 1)

if Map.has_key?(seen, rest) do
{Map.update!(seen, rest, &(&1 + to_count)), queue}
else
{Map.put(seen, rest, to_count), add_to_queue(queue, rest)}
end
end)

find_towel_list(queue, from_towels, seen)
end

def parse_input(input) do
[from, to] = String.split(input, "\n\n", trim: true)

%{
from: String.split(from, ", ") |> Enum.map(&String.graphemes/1),
to: String.split(to, "\n", trim: true) |> Enum.map(&String.graphemes/1)
from: String.split(from, ", "),
to: String.split(to, "\n", trim: true)
}
end

def part1_verify, do: input() |> parse_input() |> part1()
# def part2_verify, do: input() |> parse_input() |> part2()
def part2_verify, do: input() |> parse_input() |> part2()
end
10 changes: 7 additions & 3 deletions test/y2024/day19_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ defmodule Y2024.Day19Test do
assert Day19.parse_input(@sample) |> Day19.part1() == 6
end

test "part2" do
assert Day19.parse_input(@sample) |> Day19.part2() == 16
end

test "parse_input" do
assert %{from: from, to: to} = Day19.parse_input(@sample)
assert [["r"], ["w", "r"] | _rest] = from
assert [["b", "r", "w", "r", "r"], ["b", "g", "g", "r"] | _rest] = to
assert ["r", "wr" | _rest] = from
assert ["brwrr", "bggr" | _rest] = to
end

test "verification, part 1", do: assert(Day19.part1_verify() == 285)
# test "verification, part 2", do: assert(Day19.part2_verify() == "update or delete me")
test "verification, part 2", do: assert(Day19.part2_verify() == 636_483_903_099_279)
end

0 comments on commit 045c123

Please sign in to comment.