diff --git a/day21.erl b/day21.erl new file mode 100644 index 0000000..9941fc8 --- /dev/null +++ b/day21.erl @@ -0,0 +1,42 @@ +-module(day21). + +-export([solve/1]). + +solve(InputData) -> + {eval(<<"root">>, parse_input(InputData)), none}. + +parse_input(Input) -> parse_input(Input, #{}). + +parse_input(<<>>, Acc) -> Acc; +parse_input(<<$\n, Rest/binary>>, Acc) -> parse_input(Rest, Acc); +parse_input(<>, Monkeys) -> + parse_input(Rest, Monkeys#{Name => {Op, Left, Right}}); +parse_input(<>, Monkeys) -> + {Value, RestOut} = parse_int(RestIn), + parse_input(RestOut, Monkeys#{Name => Value}). + +eval(Name, Monkeys) -> + #{Name := Node} = Monkeys, + case Node of + Value when is_integer(Value) -> Value; + {Op, Left, Right} -> + LeftValue = eval(Left, Monkeys), + RightValue = eval(Right, Monkeys), + case Op of + $+ -> LeftValue + RightValue; + $- -> LeftValue - RightValue; + $/ -> LeftValue div RightValue; + $* -> LeftValue * RightValue + end + end. + +%% Parse Integer standard code +parse_int(<<$-, Rest/binary>>) -> + {AbsoluteValue, Binary} = parse_int0(Rest, 0), + {-1 * AbsoluteValue, Binary}; +parse_int(Binary) -> + parse_int0(Binary, 0). + +parse_int0(<>, Acc) when Digit >= $0 andalso Digit =< $9 -> + parse_int0(Rest, Acc*10 + Digit - $0); +parse_int0(Binary, Acc) when is_binary(Binary) -> {Acc, Binary}.