-module(day5). -compile(export_all). -export([solve/1]). solve(InputData) -> [DiagramData, Instructions] = binary:split(InputData, <<"\n\n">>, [trim_all]), Diagram = lists:reverse(binary:split(DiagramData, <<"\n">>, [trim_all, global])), Stacks = parse_diagram(Diagram), EndStacks = eval_instructions(Instructions, Stacks), {print_stacks(EndStacks), none}. print_stacks(Stacks) -> lists:reverse( maps:fold(fun (_Key, [Top|_Rest], Acc) -> [Top|Acc] end, [], Stacks) ). eval_instructions(<<>>, Stacks) -> Stacks; eval_instructions(Instructions, Stacks) -> <<"move ", Instruction1/binary>> = Instructions, {Moves, Instruction2} = parse_int(Instruction1), <<" from ", DigitFrom, " to ", DigitTo, $\n, Rest/binary>> = Instruction2, eval_instructions(Rest, eval_move(DigitFrom, DigitTo, Moves, Stacks)). parse_int(String) -> parse_int(String, 0). parse_int(<>, Acc) when Char >= $0 andalso Char =< $9 -> parse_int(Rest, Acc*10+(Char - $0)); parse_int(String, Acc) -> {Acc, String}. eval_move(_DigitFrom, _DigitTo, 0, Stacks) -> Stacks; eval_move(DigitFrom, DigitTo, N, Stacks) when is_integer(N) and (N > 0) -> #{DigitFrom := [Item | StackFrom], DigitTo := StackTo} = Stacks, eval_move(DigitFrom, DigitTo, N-1, Stacks#{DigitFrom := StackFrom, DigitTo := [Item | StackTo]}). parse_diagram([Program | Boxes]) -> parse_diagram(Program, Boxes, #{}). parse_diagram(<<>>, _Boxes, Stacks) -> Stacks; parse_diagram(<>, Boxes, Stacks) when Digit >= $0 andalso Digit =< $9 -> parse_diagram( ProgramRest, lists:map(fun(<<_, Tail/binary>>) -> Tail end, Boxes), Stacks#{Digit => build_stack(Boxes, [])} ); parse_diagram(<<_Char, ProgramRest/binary>>, Boxes, Stacks) -> parse_diagram(ProgramRest, lists:map(fun(<<_, Tail/binary>>) -> Tail end, Boxes), Stacks). build_stack([], Stack) -> Stack; build_stack([<<$\s, _Rest/binary>> | _Rows], Stack) -> Stack; build_stack([<> | Rows], Stack) -> build_stack(Rows, [Item | Stack]).