2024 Day 9 part 2 (inefficient)
This commit is contained in:
parent
9d60658882
commit
ae3695c161
1 changed files with 44 additions and 5 deletions
|
@ -27,11 +27,50 @@ defmodule Day9 do
|
||||||
|> elem(0)
|
|> elem(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Wrote a crazy long implementation, but was fatally flawed because it didn't consider that
|
# Super inefficient, but this is the 2nd attempt after trying to be more efficient
|
||||||
# moving a block needs to leave contiguous spaces behind if there were spaces on either side.
|
# worked on the sample but not the actual input
|
||||||
# Maybe can store the spaces as ranges, then merge the ranges?
|
def part2(input) do
|
||||||
def part2(_input) do
|
{_, _, _, disk, files} =
|
||||||
:ok
|
Enum.reduce(input, {0, 0, true, %{}, []}, fn len, {idx, id, file?, disk, files} ->
|
||||||
|
if file? do
|
||||||
|
disk = Map.put(disk, idx, {:file, id, len})
|
||||||
|
files = [{idx, id, len} | files]
|
||||||
|
{idx + len, id + 1, not file?, disk, files}
|
||||||
|
else
|
||||||
|
disk = Map.put(disk, idx, {:space, len})
|
||||||
|
{idx + len, id, not file?, disk, files}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
Enum.reduce(files, disk, fn {idx, id, len}, disk ->
|
||||||
|
# This scans the disk every time. Could possibly optimise by storing the known
|
||||||
|
# eligible spaces separately
|
||||||
|
case Enum.find(0..(idx - 1), &match?({:space, gap} when gap >= len, disk[&1])) do
|
||||||
|
nil ->
|
||||||
|
disk
|
||||||
|
|
||||||
|
space_idx ->
|
||||||
|
{:space, spaces} = Map.fetch!(disk, space_idx)
|
||||||
|
disk = disk |> Map.delete(idx) |> Map.put(space_idx, {:file, id, len})
|
||||||
|
|
||||||
|
remainder_spaces = spaces - len
|
||||||
|
|
||||||
|
if remainder_spaces > 0 do
|
||||||
|
Map.put(disk, space_idx + len, {:space, remainder_spaces})
|
||||||
|
else
|
||||||
|
disk
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> Enum.reduce(0, fn
|
||||||
|
{_idx, {:space, _}}, checksum ->
|
||||||
|
checksum
|
||||||
|
|
||||||
|
{idx, {:file, id, len}}, checksum ->
|
||||||
|
for idx <- idx..(idx + len - 1), reduce: checksum do
|
||||||
|
checksum -> checksum + idx * id
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def input do
|
def input do
|
||||||
|
|
Loading…
Reference in a new issue