From 0f4115bec3c1f505eaee0a470354e3748b2ae8fc Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sun, 10 Dec 2023 02:13:03 +0000 Subject: [PATCH] Add 2022 day 2 --- 2022/2/default.nix | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 2022/2/default.nix diff --git a/2022/2/default.nix b/2022/2/default.nix new file mode 100644 index 0000000..bb0e383 --- /dev/null +++ b/2022/2/default.nix @@ -0,0 +1,49 @@ +{ pkgs ? import { } }: +with builtins; +let + inherit (pkgs) lib; + input = builtins.readFile ./input; + # cipher for the opponent's hand + leftCipher = { "A" = "Rock"; "B" = "Paper"; "C" = "Scissors"; }; + # opponent's choice required for a win + winConditions = { "Rock" = "Scissors"; "Scissors" = "Paper"; "Paper" = "Rock"; }; + # inverse of win connections + loseConditions = builtins.listToAttrs (map (pair: lib.nameValuePair pair.value pair.name) (lib.attrsToList winConditions)); + # determines the score for the game from both shape and outcome score + determineScore = game: + let + shapeScore = { "Rock" = 1; "Paper" = 2; "Scissors" = 3; }; + outcomeScore = { "L" = 0; "D" = 3; "W" = 6; }; + gameOutcome = if winConditions.${elemAt game 0} == elemAt game 1 then "W" else if elemAt game 0 == elemAt game 1 then "D" else "L"; + in + outcomeScore.${gameOutcome} + shapeScore.${elemAt game 0}; + # map X to rock, Y to paper and Z to scissors + splitAndDecipher = x: + let + rightCipher = { "X" = "Rock"; "Y" = "Paper"; "Z" = "Scissors"; }; + split = lib.splitString " " x; + us = rightCipher.${elemAt split 1}; + them = leftCipher.${elemAt split 0}; + in + [ us them ]; + # map X to a loss, Z to a win and Y to a draw + splitAndMapToResult = x: + let + split = lib.splitString " " x; + them = leftCipher.${elemAt split 0}; + desiredOutcome = elemAt split 1; + us = if desiredOutcome == "X" then winConditions.${them} else if desiredOutcome == "Z" then loseConditions.${them} else them; + in + [ us them ]; + # split each individual game + games = lib.splitString "\n" input; + # plays game with the given mapper and returns the score + playGame = f: lib.foldl (x: y: x + y) 0 (map determineScore (map f games)); + # plays using part 1 rules with both sides ciphered + part1 = playGame splitAndDecipher; + # plays using aprt 2 rules with our side mapped to final outcome + part2 = playGame splitAndMapToResult; + # build json output + out = builtins.toJSON { inherit part1; inherit part2; }; +in +pkgs.writeText "out" out -- libgit2 1.7.2