{ lib, input }: with builtins; with lib; rec { digits = { zero = "0"; one = "1"; two = "2"; three = "3"; four = "4"; five = "5"; six = "6"; seven = "7"; eight = "8"; nine = "9"; }; toDigit = maybeDigit: digits.${maybeDigit} or maybeDigit; allNeedles = flatten (mapAttrsToList (key: value: [ key (toString value) ]) digits); allNeedlesReverse = map reverseString allNeedles; reverseString = string: concatStrings (reverseList (stringToCharacters string)); firstMatch = haystack: needles: let prefixNeedle = findFirst (needle: hasPrefix needle haystack) null needles; in if prefixNeedle != null then prefixNeedle else firstMatch (substring 1 (stringLength haystack - 1) haystack) needles; firstLast = line: let first = firstMatch line allNeedles; last = reverseString (firstMatch (reverseString line) allNeedlesReverse); in fromJSON (toDigit first + toDigit last); lines = splitString "\n" input; result = foldl' add 0 (map firstLast lines); }