37 lines
930 B
Nix
37 lines
930 B
Nix
|
{ lib, utils, ... }:
|
||
|
with lib;
|
||
|
with builtins;
|
||
|
with utils;
|
||
|
let
|
||
|
records = map (l:
|
||
|
let s = reSplit ": " l;
|
||
|
in {
|
||
|
target = toInt (head s);
|
||
|
candidates = map toInt (splitWhitespace (last s));
|
||
|
}) (readLines ./input);
|
||
|
|
||
|
concatInts = x: y: toIntBase10 "${toString x}${toString y}";
|
||
|
|
||
|
canProduce' = current: target: candidates: ops:
|
||
|
if current > target then
|
||
|
false
|
||
|
else if candidates == [ ] then
|
||
|
current == target
|
||
|
else
|
||
|
any (op:
|
||
|
canProduce' (op current (head candidates)) target (tail candidates) ops)
|
||
|
ops;
|
||
|
|
||
|
canProduce = operators: r:
|
||
|
if r.candidates == [ ] then
|
||
|
r.target == 0
|
||
|
else
|
||
|
canProduce' (head r.candidates) r.target (tail r.candidates) operators;
|
||
|
|
||
|
in {
|
||
|
part1 =
|
||
|
listSumWith (getAttr "target") (filter (canProduce [ add mul ]) records);
|
||
|
part2 = listSumWith (getAttr "target")
|
||
|
(filter (canProduce [ add mul concatInts ]) records);
|
||
|
}
|