summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Jesus <adbjesus@gmail.com>2024-12-09 23:32:42 +0000
committerAlexandre Jesus <adbjesus@gmail.com>2024-12-09 23:32:42 +0000
commit2d8c5412171605bd0b7fedca407a087827cd1082 (patch)
treef3103fe6f503b32873b96500b413a2005c70716d
parent3195e6784ee5a1c9dfb2349670af440a5fe42770 (diff)
downloadaoc2024-2d8c5412171605bd0b7fedca407a087827cd1082.tar.gz
aoc2024-2d8c5412171605bd0b7fedca407a087827cd1082.zip
Day 9
-rw-r--r--src/day09.exs95
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}")