diff options
author | Alexandre Jesus <adbjesus@gmail.com> | 2024-12-09 23:32:42 +0000 |
---|---|---|
committer | Alexandre Jesus <adbjesus@gmail.com> | 2024-12-09 23:32:42 +0000 |
commit | 2d8c5412171605bd0b7fedca407a087827cd1082 (patch) | |
tree | f3103fe6f503b32873b96500b413a2005c70716d | |
parent | 3195e6784ee5a1c9dfb2349670af440a5fe42770 (diff) | |
download | aoc2024-2d8c5412171605bd0b7fedca407a087827cd1082.tar.gz aoc2024-2d8c5412171605bd0b7fedca407a087827cd1082.zip |
Day 9
-rw-r--r-- | src/day09.exs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/day09.exs b/src/day09.exs new file mode 100644 index 0000000..1e37cad --- /dev/null +++ b/src/day09.exs @@ -0,0 +1,95 @@ +defmodule Day09 do + def part1(data) do + values = data + |> String.split("\n", trim: true) + |> hd() + |> String.codepoints() + |> Enum.map(& String.to_integer/1) + + files = values + |> Enum.take_every(2) + |> Enum.with_index() + |> Enum.flat_map(fn {v, i} -> Stream.cycle([i]) |> Enum.take(v) end) + + revfiles = files + |> Enum.reverse() + + v2 = values + |> Enum.with_index() + |> Enum.flat_map(fn {v, i} -> Stream.cycle([i]) |> Enum.take(v) end) + |> Enum.with_index() + + c1 = v2 + |> Enum.filter(fn {i, _} -> rem(i, 2) == 0 end) + |> Enum.zip(files) + + c2 = v2 + |> Enum.filter(fn {i, _} -> rem(i, 2) == 1 end) + |> Enum.zip(revfiles) + + (c1 ++ c2) + |> Enum.sort_by(fn {{_, i}, _} -> i end) + |> Enum.take(Enum.count(files)) + |> Enum.map(fn {{_, i}, v} -> i*v end) + |> Enum.sum() + end + + def part2(data) do + values = data + |> String.split("\n", trim: true) + |> hd() + |> String.codepoints() + |> Enum.map(& String.to_integer/1) + |> Enum.scan({0, 0}, fn v, {o, i} -> {v, o+i} end) + + spaces = values + |> tl() + |> Enum.take_every(2) + + values + |> Enum.take_every(2) + |> Enum.with_index() + |> Enum.reverse() + |> locations(spaces) + |> Enum.map(fn {a, b, i} -> i*Enum.sum(b..b+a-1) end) + |> Enum.sum() + end + + defp locations(acc \\ [], revfiles, spaces) + + defp locations(acc, [{{a, b}, i} | t], spaces) do + spaces = Enum.filter(spaces, fn {_, d} -> d < b end) + + s = spaces + |> Enum.filter(fn {c, _} -> c >= a end) + |> Enum.min_by(fn {_, d} -> d end, &<=/2, fn -> nil end) + + if s == nil do + locations([{a, b, i} | acc], t, spaces) + else + spaces = List.delete(spaces, s) + {c, d} = s + spaces = + if c == a do + spaces + else + [{c-a, d+a} | spaces] + end + locations([{a, d, i} | acc], t, spaces) + end + end + + defp locations(acc, [], _) do + acc + end +end + +data = IO.read(:stdio, :eof) + +{time1 , ans1} = :timer.tc(fn -> Day09.part1(data) end) +IO.puts("Time : #{time1 / 1000000}") +IO.puts("Answer: #{ans1}") + +{time2 , ans2} = :timer.tc(fn -> Day09.part2(data) end) +IO.puts("Time : #{time2 / 1000000}") +IO.puts("Answer: #{ans2}") |