36 lines
930 B
Nix
36 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);
|
|
}
|