groovyda
Advent of Code 2022 - Day 5
Today’s challenge for me was about using reduce:
defmodule Prob5 do
def move([[h1 | rest] = _list1, list2]) do
[rest, [h1 | list2]]
end
def move_n([l1, l2], n) do
Enum.reduce(1..n, [l1, l2], fn _, acc -> move(acc) end)
end
def single_instruction(input, [n, from_ind, to_ind], move_function) do
from_ind = from_ind - 1
to_ind = to_ind - 1
[from, to] = move_function.([Enum.at(input, from_ind), Enum.at(input, to_ind)], n)
input
|> List.replace_at(from_ind, from)
|> List.replace_at(to_ind, to)
end
def parse_line(line) do
[[n], [from_ind], [to_ind]] = Regex.scan(~r/\d+/, line)
Enum.map([n, from_ind, to_ind], &String.to_integer/1)
end
def move_n_part2([l1, l2], n) do
to_move = Enum.take(l1, n)
[Enum.drop(l1, n), to_move ++ l2]
end
end
I manually parsed the first part of the input into lists, like thus:
test_input = [[:n, :z], [:d, :c, :m], [:p]]
And then parsed the 2nd part of the input into simple lists, and finally ran it through reduce:
Enum.reduce(
instructions,
input,
fn instruction, input -> Prob5.single_instruction(input, instruction, &Prob5.move_n/2) end)
… using the 2 move functions - one for each part.
Let me know how this can be improved!
Thanks
Most Liked
mudasobwa
As always, I am here to advertise Access.
# moving crates (part I)
Enum.reduce(0..count - 1, acc, fn _, acc ->
{v, acc} = get_and_update_in(acc, [Access.at(from - 1)], fn [h|t] -> {h, t} end)
update_in(acc, [Access.at(to - 1)], fn t -> [v|t] end)
end)
# moving crates (part II)
{v, acc} = get_and_update_in(acc, [Access.at(from - 1)], fn l -> Enum.split(l, count) end)
update_in(acc, [Access.at(to - 1)], fn t -> v ++ t end)
mudasobwa
mudasobwa
Finite number of moves is a synonym of reduce/3 through ![]()
adamu
I thought about Access but I thought, “piles of crates with an index” sounds like a map!
Just throwing mine into the mix.
defp move_9000(0, from, to), do: {from, to}
defp move_9000(number, [crate | from], to), do: move_9000(number - 1, from, [crate | to])
defp move_9001(number, from, to) do
{moving, moved_from} = Enum.split(from, number)
{moved_from, moving ++ to}
end
Completing in <100μs so can’t be too bad ![]()
mudasobwa
I could not disagree more.
Oh, wait, I could.
Access is something I use in each and every project, I even created the library to inject a performant Access implementation into home-baked structs (estructura.) Also anyone who dealt with deeply nested structures at least once, would use it again and again for its simplicity, elegance and uniformness.







