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