diff --git a/day5.erl b/day5.erl new file mode 100644 index 0000000..be984dd --- /dev/null +++ b/day5.erl @@ -0,0 +1,49 @@ +-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]).