2 Commits
3277893cfa
...
59cc25c565
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
59cc25c565 |
Day 21-2
|
3 years ago |
|
|
3558cb9f9e |
Day 21-1
|
3 years ago |
1 changed files with 72 additions and 0 deletions
-
72day21.erl
@ -0,0 +1,72 @@ |
|||
-module(day21). |
|||
|
|||
-export([solve/1]). |
|||
|
|||
solve(InputData) -> |
|||
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, #{}). |
|||
|
|||
parse_input(<<>>, Acc) -> Acc; |
|||
parse_input(<<$\n, Rest/binary>>, Acc) -> parse_input(Rest, Acc); |
|||
parse_input(<<Name:4/bytes, $:, $\s, Left:4/bytes, $\s, Op, $\s, Right:4/bytes, Rest/binary>>, Monkeys) -> |
|||
parse_input(Rest, Monkeys#{Name => {Op, Left, Right}}); |
|||
parse_input(<<Name:4/bytes, $:, $\s, RestIn/binary>>, 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. |
|||
|
|||
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), |
|||
{-1 * AbsoluteValue, Binary}; |
|||
parse_int(Binary) -> |
|||
parse_int0(Binary, 0). |
|||
|
|||
parse_int0(<<Digit, Rest/binary>>, Acc) when Digit >= $0 andalso Digit =< $9 -> |
|||
parse_int0(Rest, Acc*10 + Digit - $0); |
|||
parse_int0(Binary, Acc) when is_binary(Binary) -> {Acc, Binary}. |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue