Apologies if the title doesn't make sense, I'm struggling to describe what it is precisely but hopefully, the following will enlighten you.
This is part of an AoC challenge but I believe it's a specific enough question that one might run into it anyway. For the challenge, I don't think I'm going at it the right way, building a tree would be better but now I just want to know how to solve this issue.
My data looks like the following:
iex(249)> Day7.part1
[
%{path: ["/", "a", "e"], size: 584},
%{path: ["/", "a"], size: 94269},
%{path: ["/", "d"], size: 24933642},
%{path: ["/"], size: 23352670}
]
What I want to do is iterate through where I compare the :path
values, if they match then the shorter list must be the parent and the parent :size
will be updated such that size: parent.size + child.size
. Or something like that at least.
iex(249)> Day7.part1
[
%{path: ["/", "a", "e"], size: 584},
%{path: ["/", "a"], size: 94853},
%{path: ["/", "d"], size: 24933642},
%{path: ["/"], size: 48381165}
]
def child_dirs([], system), do: system
def child_dirs([head | tail] = dirs, system) do
Enum.map(dirs, fn x ->
if x.path == List.delete_at(head.path, -1) do
system = system ++ [%{path: x.path, size: head.size + x.size}]
end
end)
child_dirs(tail, system)
end
Which results in the following
iex(281)> Day7.part1 |> Day7.child_dirs([])
[]
But if I change system = system ++ ...
to inspect it, like so IO.inspect(system = system ++ [%{path: x.path, size: head.size + x.size}])
. I get the following:
iex(284)> Day7.part1 |> Day7.child_dirs([])
[%{path: ["/", "a"], size: 94853}]
[%{path: ["/"], size: 23446939}]
[%{path: ["/"], size: 48286312}]
[]
So it's clearly working in some regard but just not adding the updated values to the ongoing accumulator named system
.
Any help or advice would be much appreciated :)
That’s most likely not the optimal way, but it’s the most clean and idiomatic one, AFACT.
input
[
%{path: ["/", "a", "e"], size: 584},
%{path: ["/", "a"], size: 94269},
%{path: ["/", "d"], size: 24933642},
%{path: ["/"], size: 23352670}
]
Walk through the list, select from this list elements which start with the current one, and sum them all.
for %{path: path} <- input do
size =
input
|> Enum.filter(&Enum.slice(&1.path, 0..length(path)-1) == path)
|> Enum.map(& &1.size)
|> Enum.sum()
%{path: path, size: size}
end
#⇒ [
# %{path: ["/", "a", "e"], size: 584},
# %{path: ["/", "a"], size: 94853},
# %{path: ["/", "d"], size: 24933642},
# %{path: ["/"], size: 48381165}
# ]