|
|
|
@ -3,7 +3,13 @@ |
|
|
|
-export([solve/1]). |
|
|
|
|
|
|
|
solve(InputData) -> |
|
|
|
{eval(<<"root">>, parse_input(InputData)), none}. |
|
|
|
Monkeys = parse_input(InputData), |
|
|
|
{eval(<<"root">>, Monkeys), undo(human_path(<<"root">>, p2fix(Monkeys), []))}. |
|
|
|
|
|
|
|
% turn the root into a big equal sign |
|
|
|
|
|
|
|
p2fix(#{<<"root">> := {_Op, Left, Right}} = Monkeys) -> |
|
|
|
Monkeys#{<<"root">> := {$-, Left, Right}}. |
|
|
|
|
|
|
|
parse_input(Input) -> parse_input(Input, #{}). |
|
|
|
|
|
|
|
@ -30,6 +36,30 @@ eval(Name, Monkeys) -> |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
undo(HumanPath) -> lists:foldl(fun do_undo/2, 0, HumanPath). |
|
|
|
|
|
|
|
do_undo({_Side, $+, Value}, Target) -> Target - Value; |
|
|
|
do_undo({_Side, $*, Value}, Target) -> Target div Value; |
|
|
|
do_undo({left, $/, Value}, Target) -> Target * Value; |
|
|
|
do_undo({right, $/, Value}, Target) -> Value div Target; |
|
|
|
do_undo({left, $-, Value}, Target) -> Target + Value; |
|
|
|
do_undo({right, $-, Value}, Target) -> Value - Target. |
|
|
|
|
|
|
|
|
|
|
|
human_path(<<"humn">>, _State, Path) -> lists:reverse(Path); |
|
|
|
human_path(Name, Monkeys, Path) -> |
|
|
|
#{Name := Node} = Monkeys, |
|
|
|
case Node of |
|
|
|
Value when is_integer(Value) -> |
|
|
|
not_found; |
|
|
|
{Op, Left, Right} -> |
|
|
|
case human_path(Left, Monkeys, [{left, Op, eval(Right, Monkeys)} | Path]) of |
|
|
|
not_found -> human_path(Right, Monkeys, [{right, Op, eval(Left, Monkeys)} | Path]); |
|
|
|
Found -> Found |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
%% Parse Integer standard code |
|
|
|
parse_int(<<$-, Rest/binary>>) -> |
|
|
|
{AbsoluteValue, Binary} = parse_int0(Rest, 0), |
|
|
|
|