71 lines
1.6 KiB
Nix
71 lines
1.6 KiB
Nix
{ pkgs, lib }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
compartments = pipe (fileContents ./input.txt) [
|
|
(splitString "\n")
|
|
];
|
|
|
|
splitAtMiddle = s: {
|
|
c1 = substring 0 ((stringLength s) / 2) s;
|
|
c2 = substring ((stringLength s) / 2) (stringLength s) s;
|
|
};
|
|
charsToSet = s: foldl (set: c: set // { ${c} = true; }) { } (stringToCharacters s);
|
|
getCommonChar = { c1, c2 }:
|
|
findSingle
|
|
(c: c2.${c} or false)
|
|
"Error: no common chars"
|
|
"Error: multiple chars"
|
|
(attrNames c1);
|
|
mapRange = min: max: f: i: if min <= i && i < max then f i else i;
|
|
transformRange = min: max: offset: i: mapRange min max (x: x + offset) i;
|
|
|
|
charValue = c: pipe c [
|
|
lib.strings.charToInt
|
|
(transformRange 65 91 (-(65 - 27)))
|
|
(transformRange 97 123 (-(97 - 1)))
|
|
];
|
|
|
|
answer1 = pipe compartments [
|
|
(map splitAtMiddle)
|
|
(map (mapAttrs (_: charsToSet)))
|
|
(map getCommonChar)
|
|
(map charValue)
|
|
(foldr add 0)
|
|
toString
|
|
];
|
|
|
|
chunksOf = n: l: if length l <= n
|
|
then [l]
|
|
else [(take n l)] ++ (chunksOf n (drop n l));
|
|
toA123 = l: {
|
|
a1 = elemAt l 0;
|
|
a2 = elemAt l 1;
|
|
a3 = elemAt l 2;
|
|
};
|
|
getCommonChar2 = { a1, a2, a3 }:
|
|
findSingle
|
|
(c: a2.${c} or false && a3.${c} or false)
|
|
"Error: no common chars"
|
|
"Error: multiple chars"
|
|
(attrNames a1);
|
|
|
|
answer2 = pipe compartments [
|
|
(chunksOf 3)
|
|
(map toA123)
|
|
(map (mapAttrs (_: charsToSet)))
|
|
(map getCommonChar2)
|
|
(map charValue)
|
|
(foldr add 0)
|
|
toString
|
|
];
|
|
|
|
in pkgs.writeText "answers" ''
|
|
Task1:
|
|
${answer1}
|
|
|
|
Task2:
|
|
${answer2}
|
|
''
|