From 2d8c5412171605bd0b7fedca407a087827cd1082 Mon Sep 17 00:00:00 2001 From: Alexandre Jesus Date: Mon, 9 Dec 2024 23:32:42 +0000 Subject: Day 9 --- src/day09.exs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/day09.exs (limited to 'src') 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}") -- cgit v1.2.3