From 8e747d160499bbdd1232f6355964a736afb1aced Mon Sep 17 00:00:00 2001 From: Rebecca Le Date: Mon, 9 Dec 2024 17:22:05 +0800 Subject: [PATCH] 2024 day 9 part 2 - this needs optimization --- README.md | 4 +-- lib/y2024/README.md | 3 +- lib/y2024/day09.ex | 67 ++++++++++++++++++++++++++++++++++----- test/y2024/day09_test.exs | 2 +- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2475549..1310162 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ My Elixir solutions for [Advent of Code](https://adventofcode.com/) (all years). -

436 stars

-

17 stars
+

437 stars

+

18 stars
44 stars
50 stars
46 stars
diff --git a/lib/y2024/README.md b/lib/y2024/README.md index 4cfba37..f7ca1f4 100644 --- a/lib/y2024/README.md +++ b/lib/y2024/README.md @@ -2,7 +2,7 @@ My Elixir solutions for [Advent of Code 2024](https://adventofcode.com/2024). -17 stars +18 stars ## Benchmarks @@ -31,4 +31,5 @@ day 07, part 2 14.76 67.73 ms ±1.35% 67.51 ms 71. day 08, part 1 1.07 K 0.93 ms ±6.91% 0.90 ms 1.07 ms day 08, part 2 0.83 K 1.20 ms ±7.78% 1.17 ms 1.38 ms day 09, part 1 9.27 107.87 ms ±0.84% 107.61 ms 111.83 ms +day 09, part 2 0.23 4.43 s ±0.12% 4.43 s 4.43 s ``` diff --git a/lib/y2024/day09.ex b/lib/y2024/day09.ex index d90316f..88b8246 100644 --- a/lib/y2024/day09.ex +++ b/lib/y2024/day09.ex @@ -42,13 +42,64 @@ defmodule Y2024.Day09 do |> elem(1) end - # @doc """ - # iex> Day09.part2("update or delete me") - # "update or delete me" - # """ - # def part2(input) do - # input - # end + @doc """ + iex> Day09.part2(Integer.digits(2333133121414131402)) + 2858 + """ + def part2(input) do + input + |> Enum.reduce({0, true, []}, fn num, {file_id, fill?, list} -> + type = if fill?, do: :fill, else: :gap + next_file_id = if fill?, do: file_id + 1, else: file_id + {next_file_id, !fill?, [%{type: type, file_id: file_id, num: num} | list]} + end) + |> elem(2) + |> Enum.reverse() + |> defrag([]) + |> Enum.reduce({0, 0}, fn record, {index, acc} -> + if record.type == :gap do + {index + record.num, acc} + else + acc = + Enum.reduce(0..(record.num - 1), acc, fn sub_index, acc -> + acc + (index + sub_index) * record.file_id + end) + + {index + record.num, acc} + end + end) + |> elem(1) + end + + defp defrag([], list), do: Enum.reverse(list) + + defp defrag([%{type: :fill} = head | tail], list) do + defrag(tail, [head | list]) + end + + defp defrag([%{type: :gap, num: num} = head | tail], list) do + filler = + Enum.find(Enum.reverse(tail), fn %{num: check_num, type: type} -> + type == :fill && check_num <= num + end) + + if filler do + list = [filler | list] + + tail = + Enum.map(tail, fn record -> + if record == filler, do: %{type: :gap, num: filler.num}, else: record + end) + + if num - filler.num == 0 do + defrag(tail, list) + else + defrag([%{type: :gap, num: num - filler.num} | tail], list) + end + else + defrag(tail, [head | list]) + end + end def parse_input(input) do input @@ -58,5 +109,5 @@ defmodule Y2024.Day09 do 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 diff --git a/test/y2024/day09_test.exs b/test/y2024/day09_test.exs index 1a59267..62e0d1f 100644 --- a/test/y2024/day09_test.exs +++ b/test/y2024/day09_test.exs @@ -4,5 +4,5 @@ defmodule Y2024.Day09Test do doctest Day09 test "verification, part 1", do: assert(Day09.part1_verify() == 6_241_633_730_082) - # test "verification, part 2", do: assert(Day09.part2_verify() == "update or delete me") + test "verification, part 2", do: assert(Day09.part2_verify() == 6_265_268_809_555) end