diff --git a/day10/default.nix b/day10/default.nix new file mode 100644 index 0000000..a3cf278 --- /dev/null +++ b/day10/default.nix @@ -0,0 +1,98 @@ +{ pkgs, lib }: + +with lib; + +let + # See https://github.com/NixOS/nixpkgs/pull/205457 + toInt = str: + let + inherit (builtins) match fromJSON; + # RegEx: Match any leading whitespace, possibly a '-', one or more digits, + # and finally match any trailing whitespace. + strippedInput = match "[[:space:]]*(-?[[:digit:]]+)[[:space:]]*" str; + + # RegEx: Match a leading '0' then one or more digits. + isLeadingZero = match "0[[:digit:]]+" (head strippedInput) == []; + + # Attempt to parse input + parsedInput = fromJSON (head strippedInput); + + generalError = "toInt: Could not convert ${escapeNixString str} to int."; + + octalAmbigError = "toInt: Ambiguity in interpretation of ${escapeNixString str}" + + " between octal and zero padded integer."; + + in + # Error on presence of non digit characters. + if strippedInput == null + then throw generalError + # Error on presence of leading zero/octal ambiguity. + else if isLeadingZero + then throw octalAmbigError + # Error if parse function fails. + else if !isInt parsedInput + then throw generalError + # Return result. + else parsedInput; + + lineToInstruction = line: + if line == "noop" + then { type = "n"; } + else { type = "a"; val = toInt (elemAt (splitString " " line) 1); }; + + foldToSignalState = { cycles ? 0, X ? 0, nextX ? 1 }: instructions: let + instr = head instructions; + nextSignalState = if instr.type == "n" + then { cycles = 1; X = nextX; inherit nextX; } + # Implicit `addx` + else { cycles = 2; X = nextX; nextX = nextX + instr.val; }; + in if instructions == [] then [] else [nextSignalState] ++ (foldToSignalState nextSignalState (tail instructions)); + + repeat = item: times: map (const item) (range 1 times); + + expandSignalStates = signalStates: let + s = head signalStates; + in if signalStates == [] + then [] + else (repeat s.X s.cycles) ++ (expandSignalStates (tail signalStates)); + + takeWithStride = n: l: + if l == [] then [] else [(head l)] ++ takeWithStride n (drop n l); + + signalStates = pipe ./input.txt [ + fileContents + (splitString "\n") + (map lineToInstruction) + (foldToSignalState {}) + expandSignalStates + ]; + + answer1 = pipe signalStates [ + (imap1 (i: v: i * v)) + (drop 19) + (takeWithStride 40) + (foldr add 0) + toString + ]; + + splitAtInterval = n: list: + if list == [] then [] + else [(take n list)] ++ (splitAtInterval n (drop n list)); + + f = i: v: if v <= i && i <= v + 2 then "#" else "."; + + answer2 = pipe signalStates [ + (splitAtInterval 40) + (map (imap1 f)) + (map (concatStringsSep "")) + (concatStringsSep "\n") + toString + ]; + +in pkgs.writeText "answers" '' + Task1: + ${answer1} + + Task2: + ${answer2} +'' diff --git a/day10/input.txt b/day10/input.txt new file mode 100644 index 0000000..008b1e7 --- /dev/null +++ b/day10/input.txt @@ -0,0 +1,139 @@ +noop +noop +noop +addx 5 +noop +addx 1 +addx 2 +addx 5 +addx 2 +addx 1 +noop +addx 5 +noop +addx -1 +noop +addx 5 +noop +noop +addx 5 +addx 1 +noop +noop +addx 3 +addx 2 +noop +addx -38 +noop +addx 3 +addx 2 +addx -5 +addx 12 +addx 2 +addx 27 +addx -40 +addx 19 +addx 2 +addx 19 +addx -18 +addx 2 +addx 5 +addx 2 +addx -23 +addx 22 +addx 4 +addx -34 +addx -1 +addx 5 +noop +addx 2 +addx 1 +addx 20 +addx -17 +noop +addx 25 +addx -17 +addx -2 +noop +addx 3 +addx 19 +addx -12 +addx 3 +addx -2 +addx 3 +addx 1 +noop +addx 5 +noop +noop +addx -37 +addx 3 +addx 4 +noop +addx 24 +addx -6 +addx -15 +addx 2 +noop +addx 6 +addx -2 +addx 6 +addx -12 +addx -2 +addx 19 +noop +noop +noop +addx 3 +noop +addx 7 +addx -2 +addx -24 +addx -11 +addx 4 +addx 3 +addx -2 +noop +addx 7 +addx -2 +addx 2 +noop +addx 3 +addx 7 +noop +addx -2 +addx 5 +addx 2 +addx 5 +noop +noop +noop +addx 3 +addx -35 +addx 35 +addx -21 +addx -14 +noop +addx 5 +addx 2 +addx 33 +addx -7 +addx -23 +addx 5 +addx 2 +addx 1 +noop +noop +addx 5 +addx -1 +noop +addx 3 +addx -23 +addx 30 +addx 1 +noop +addx 4 +addx -17 +addx 11 +noop +noop diff --git a/flake.nix b/flake.nix index 3b851c1..ff7513f 100644 --- a/flake.nix +++ b/flake.nix @@ -14,6 +14,7 @@ day06 = pkgs.callPackage ./day06 { }; day07 = pkgs.callPackage ./day07 { }; day08 = pkgs.callPackage ./day08 { }; + day10 = pkgs.callPackage ./day10 { }; }; }; }