From ec9e02b52fb7c7720de4dc6f9729c84e9f6a81fa Mon Sep 17 00:00:00 2001 From: Anthony Oteri Date: Fri, 2 Dec 2022 13:13:45 -0500 Subject: [PATCH] Day 2 is in the bag --- day2/Cargo.lock | 7 + day2/Cargo.toml | 8 + day2/data/input.txt | 2500 ++++++++++++++++++++++++++++++++++++++ day2/data/input_test.txt | 3 + day2/src/main.rs | 232 ++++ 5 files changed, 2750 insertions(+) create mode 100644 day2/Cargo.lock create mode 100644 day2/Cargo.toml create mode 100644 day2/data/input.txt create mode 100644 day2/data/input_test.txt create mode 100644 day2/src/main.rs diff --git a/day2/Cargo.lock b/day2/Cargo.lock new file mode 100644 index 0000000..63c2f60 --- /dev/null +++ b/day2/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day2" +version = "0.1.0" diff --git a/day2/Cargo.toml b/day2/Cargo.toml new file mode 100644 index 0000000..8aa34bb --- /dev/null +++ b/day2/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day2/data/input.txt b/day2/data/input.txt new file mode 100644 index 0000000..9671db1 --- /dev/null +++ b/day2/data/input.txt @@ -0,0 +1,2500 @@ +A Z +C Z +A X +B Z +C X +A X +A X +A Z +C Y +A X +C Z +C Y +B Z +B X +A X +B X +C X +C X +C Z +B Z +B Y +C X +C X +C Z +C X +C X +C X +A Y +B Y +C Y +C Z +B Y +B X +C Z +B Z +B Y +B Y +C Z +C X +C Y +B Z +B Z +A X +A X +C Z +C X +A X +B Z +C X +C X +B Z +B Z +C Z +A X +A X +A Z +C Z +C Z +C Z +A X +B Z +A X +B Y +C Z +C X +B Z +C X +C Y +B Z +A X +B Z +A Z +C X +B Z +C Z +C X +C Z +C X +C Z +C Y +C Z +C Y +C X +C Z +C Z +C Z +C Z +A X +B Z +B X +C X +C Z +C Z +A Y +C Z +C X +B Y +B Z +C Z +C X +B Z +A Z +C Z +C Z +C Z +C Z +C Z +B X +A X +B Z +B Y +B Z +C X +C Y +B Z +A X +A X +A Z +C X +C Z +B Z +C Z +C X +A X +A X +A X +C Z +B Z +A Z +C Z +C X +B Z +B Z +C X +B X +C X +C X +C X +B Z +C X +B Z +A X +A Z +A Z +C Z +C Y +C Z +B Y +C Z +C Z +C X +C X +A X +C Z +A Z +B Z +A X +C Z +C Z +B Z +A Z +C X +B Z +C Z +C X +C Y +C Y +B Y +B Z +C Y +C Z +B Z +C Z +B Z +C X +A X +B X +C Y +B Z +C Z +B X +A X +C Z +C Z +C Z +C X +B Y +A X +C Y +C Z +B X +A Z +C Z +C X +B Y +A Y +C Z +C Z +B Y +A X +A Z +B Y +C Z +B X +C Z +C Z +B X +C Z +C X +A X +C Z +A X +C X +B Z +C Y +C Z +A Z +B Z +A X +A X +C X +A Y +C Y +C X +C Z +C Z +C Z +C Z +C Z +B Y +A X +A Z +B Y +C Z +C X +C X +B Z +C X +A Z +A X +C Z +B X +B Z +A Z +B X +A X +A X +B Z +B Y +B Y +C X +C Z +C Z +C Y +C X +C Z +C Z +B X +A X +B X +C X +C X +B Z +B Z +C X +C X +B Z +B Z +A Z +B Z +B Z +C Z +A Z +A Z +C X +B Z +A X +C X +A X +C Z +A X +C Z +B X +C X +B Z +A Y +C Z +B X +C Y +C X +B Z +C Y +C Z +B X +B X +B Z +C X +C Z +B Z +C Z +C X +A X +A X +C Y +B X +A Z +B Y +C X +B Y +C Z +B Y +B Z +C Y +C Z +A Z +C X +C X +C X +C Z +A Y +A Z +C Z +C Z +B Z +B Z +B Z +A Z +C Z +C X +C Z +C Z +A X +C Z +C X +B X +C Z +C X +C Z +A X +B X +C Z +C X +B Z +C Y +A Y +A X +C X +A X +B X +C X +C Z +A Z +C Z +C Z +B Z +A X +C Z +C Z +C Z +B Z +A X +C Z +C Z +C Z +C Z +B Y +C X +B Z +C Z +B X +C Z +C X +C Y +B X +A Y +A Y +C Y +B Y +C X +B Y +C X +A X +C Z +C X +C X +B Z +C X +B Z +C Z +C Z +A X +B Y +C X +C Z +B X +C Z +C Y +B Z +A X +B Z +B Z +B X +A Z +A X +C Z +A Y +A X +A X +C Y +B Y +C X +B Y +B X +A X +C Y +A X +B Z +B Y +B Y +A X +A X +A Z +C X +A X +C Y +A X +A X +C Y +C Z +B Z +B Y +B X +A X +A X +B Z +C Z +B X +A Y +A Z +C Y +A X +C Z +C X +A Z +C Z +C Z +C Y +C X +C Z +A Z +C Y +C Z +C Z +C Z +C X +C Z +A X +C Y +B Y +C Y +B Y +A X +B Y +B Z +B Z +B X +B Z +C Z +B Z +C Z +B X +C Z +B Z +B Z +C Z +C Z +A Z +A Z +C X +B Y +B Y +C Z +C X +C Z +A Z +A X +C Y +C Z +B Z +C Z +A X +B Z +A X +A Z +A X +A X +C X +B Z +B Z +C Z +C X +A X +B X +A X +A X +A Z +C Y +B Y +B X +A X +C X +B Y +C Z +B X +C X +B Z +B Z +C Z +B Z +C Z +C Y +C Y +A X +A Z +C X +A X +C Z +A Z +B X +C X +A X +B Z +B Z +B Z +C Z +C Z +C Z +C Y +B Z +C X +C X +C X +B Z +B Z +B Z +A X +A X +A Z +C Z +C X +A X +B X +A Z +C X +A X +C Z +C Z +C Z +C Z +C Y +C Z +B Z +C X +C Z +A Z +A Z +B Z +C X +A X +A X +A X +C X +C X +C X +C X +B X +C X +B Y +C Z +C Z +C Z +B Z +B Z +C Z +B Y +C Y +C X +A Z +C Y +C Z +A X +C X +C Z +C Z +A X +C Y +B Y +C X +C Z +C X +B X +C Z +B Z +B Y +A X +C X +C Z +B Z +B X +A Z +C Y +C X +C Y +B Z +A Z +C X +C X +A X +A Y +B Y +C Y +C Z +C Z +C Z +C Y +A X +A X +B X +B Y +A Z +C Z +C Y +B Z +C Z +C X +C Z +A X +C Z +C X +C Y +C X +C X +C X +C Z +C Z +C Z +A X +C Z +C X +C X +B X +C X +B Y +A X +C X +A X +C Y +C X +C Z +C X +C Z +C X +B Z +A X +C Z +C X +C Z +C Y +C X +C X +C Z +B Z +C Z +C Z +C X +B Z +C Z +B X +C Z +B Z +C X +B X +C Z +C Y +B X +C Z +C Y +A X +B Z +B Z +C Y +B Y +B X +C Y +C X +C X +B Z +B Y +C X +C Z +B Z +C Y +C X +C Z +C Y +B Z +A Z +C Z +C Z +C Z +C Y +C Z +C Z +C Z +C X +B Z +B Z +C Z +C X +C X +C Z +C Z +C X +A Z +B Z +B X +C X +C Z +A Z +C X +C Z +B Z +A X +C Z +C Z +B Z +C Z +B Y +A X +A X +A Z +B Z +A Z +A X +B Z +C X +B Z +B Z +B Y +A X +B X +B Z +B Z +A X +C Z +B Z +C X +A X +B Z +B Z +C Z +B Y +C Z +B Z +B Y +C X +A Z +B Y +A X +A X +C X +C Z +A Z +C X +C Z +A Z +B Z +C Z +C Z +C X +C Y +C Z +A X +C X +C Z +B Y +B Z +A X +C X +B Z +C X +B Z +C Z +C Y +C Z +B Z +C X +A Z +C Z +C Z +B Z +B X +A Z +C Z +C Z +C Z +C Z +A Z +C X +B Z +C Y +B X +C Z +A X +B Y +C Z +B X +B X +C X +A Z +C X +C X +C Z +A Y +C Y +C Z +B Z +A X +B Z +C Z +A Z +C Y +B Z +B Z +C X +C Z +A Z +C X +C X +C Z +C Z +C Z +A X +C Z +A X +C Z +C X +C Z +C Z +C X +A Z +B Y +B Z +A X +C Y +C Z +B Z +B Z +A X +B Z +A Z +C Z +C Z +A X +C X +A Y +C Z +C X +C Z +B Y +C Y +B Z +B Z +A X +C Z +C Z +A Z +A X +C Z +C Z +C Y +C Z +A X +B Z +A X +B Y +C X +B Z +C X +B X +A X +B Y +A Y +C X +B Y +B Y +B Z +C Z +A Z +B Z +A X +C Z +C Z +A X +B Z +A X +A X +B Y +B Z +A Y +C Z +C X +A X +C Z +A Z +C Y +B Z +C X +C Y +B Z +B X +A X +C Z +C X +A Z +A Z +C Z +A Z +C Z +C Z +C Z +A Z +A Z +C Z +C Z +A X +B X +B Z +C X +A Y +C Z +C Z +B Z +C Z +C Z +C X +A X +A Z +C X +B Z +C X +C Z +C X +A X +B X +C X +B Z +C X +A Z +C Z +B X +C Z +B Y +A X +C Z +C X +C X +C Z +B Z +C X +C Z +A X +A X +C X +B Z +C Z +B Z +A Z +C Z +A Z +C Z +C Y +A Z +A X +B Y +A X +B X +C X +C Z +C Y +C X +C Z +C X +C X +B X +B Z +B Y +C Y +C Z +C X +C Y +C X +C X +C Z +C Y +C X +C X +C Z +C X +C Y +C Z +B X +A Y +C X +B X +A Z +C Z +C X +C Y +B X +C Z +A X +B Z +B Z +A X +A X +B Z +B Z +A Z +A X +B X +C Y +A Z +C Z +B Z +A X +B X +B Z +A X +A Z +C Y +B X +B Y +C Z +C X +A Z +C Z +C Z +C Z +B Y +B X +A Z +B Y +A X +A Z +B Z +C X +A X +C X +B Y +A Z +C X +C X +A X +A X +A X +C X +B Z +B Z +C Z +C Z +A X +B Z +C Z +B Z +C X +B Y +C Z +A X +C Z +A X +A Z +C Z +B Z +C Z +B Y +A X +C Z +B Z +C X +C Z +C Z +C Z +C Y +C X +C Y +B Y +B Z +C Z +B X +C Z +C X +A X +C Z +B Y +C Y +C Z +B Z +C X +C Z +C Z +C Z +C X +A Y +B Y +C Y +A X +A Z +C Z +B Z +C Z +B Z +A X +A X +C Z +C X +B Z +B Z +A Z +C Z +A Z +C Y +B X +C Z +A X +B Y +A X +C Z +C Z +A Z +A Z +A X +C Z +B Z +C Z +B Y +A X +C Z +B Z +B Z +A X +A X +C X +B X +B X +B Z +A Z +C Z +C X +C Y +B Z +C X +A X +C Z +C Z +C Z +C Z +B Y +C Z +B Z +C Z +B X +C Z +C X +A X +B Y +C Z +C Z +A X +B Y +B Y +B Y +B Z +A X +B Z +B Z +A X +C Z +C Z +C Z +B Z +B Z +A X +C Z +C Z +C X +C Z +C Z +C Z +C Y +A Z +C X +C Y +C X +B Z +A X +C Z +C X +A Z +A Z +C Z +B Z +B Z +C X +B Z +C X +B Z +C X +C X +B Y +C Z +C Y +B Z +C X +C Z +C X +C X +C X +A X +C Y +C X +A X +B Z +A Z +C Z +C X +C X +C Z +B Z +C X +C Z +A Z +B Z +C Z +C X +C Z +C Z +A Z +C Z +A X +C Z +A Z +C Z +A X +B Y +C X +A X +C Z +B Z +A X +B Y +A Z +C Z +C Z +B Y +A X +B Z +A X +B Z +C Z +C X +B Z +C Z +B Z +C X +B Y +B X +C Y +A Z +C Y +C X +C Y +C X +C X +A Z +B Z +A Z +A X +A X +A X +C X +C Z +A X +B X +A X +C X +B Z +C Z +C Y +A Z +C X +C Z +B Y +B Z +A X +A Z +C Z +C X +B Y +A X +B Y +C Y +A X +A Z +B Z +C Z +C Z +A Z +C Z +C X +C Y +C X +C X +C Y +A X +C Z +C X +C Z +C Z +A Z +C Z +C Z +C Y +C Z +B Y +C Z +C Z +C Z +C Z +C X +A X +C Z +C Z +C X +C Z +C X +C Z +A X +A Z +B Z +B Y +A X +C X +C Y +A X +B X +C X +C X +A Z +C X +C Y +B X +C Z +A Z +C X +A X +B Z +C Y +C Z +C X +A Y +C Z +C Y +C Z +C Z +B Z +B Z +B Z +C Z +C Z +A X +B X +A X +B Y +B Z +B Z +C X +C X +C Z +A Z +A X +B X +B Z +B Z +A X +C Z +B Z +B Z +C Z +C Z +C Z +B Z +C X +C X +B Z +C Y +B Z +C X +B X +C X +A Z +A X +C Z +C Z +B Y +A X +A Y +C Z +A Z +C X +B Y +C X +A Z +B Y +B X +C Z +C X +B Y +C Z +B Z +C X +C X +C Z +B Z +C Z +C Z +C X +C X +C Z +C X +C X +C Z +A X +C X +C X +B Z +C Z +A X +C X +C X +A Z +C Z +C Z +B Y +B Z +B X +C Z +A X +A X +B Y +C X +C X +B Y +C Z +A Z +B Y +B Y +C X +C X +C X +C X +A X +B Z +B Y +B Z +C X +C Z +B Z +B Y +C Z +B Z +A X +C X +C X +C Z +A X +C X +C X +C Z +C Y +B X +C X +C Y +B Z +C X +C Y +C Z +C Z +A Z +B X +C Z +B X +A Z +C Z +C X +C X +A Z +C X +B Z +A Z +C X +C X +B X +C Z +C X +A X +C Z +C Z +B Z +B Y +C X +C Y +C Z +C Z +A Z +C Z +C Y +C Y +A X +C Z +A X +B Z +B Z +C Z +B X +B Z +A Z +A Z +B Z +B Y +B Z +C X +B Y +B Z +A X +B X +C Y +A X +C Z +B Z +C X +A X +B X +C Y +B Z +C Z +A X +C X +B Z +C X +A Z +C X +C Z +C Z +B X +C X +A Z +C X +B Z +C Z +C Z +C X +B Z +C Z +B X +C X +C Z +B Z +B Z +A X +C X +C Z +C Z +C Z +A X +C X +C Z +B Z +C Y +C X +C X +C Z +C X +C Z +C X +C X +C Z +B Z +B Z +C Z +B Z +C Z +B X +C Z +A X +C Z +C X +C X +C Z +B Y +B Z +B Z +B Z +C Z +B X +C X +B Z +A X +C X +A X +C X +C X +A Z +B Y +B X +A X +C Z +B Y +C X +A X +B Z +B Z +C Z +B Z +C Z +A Y +A Z +C X +C Y +A Y +C X +B Y +C X +C Y +C Z +B Z +C Z +B Z +B X +C Z +B X +B X +C Z +A Z +B Z +C Z +B Z +C Z +C Z +B Z +C X +C Z +C Z +C Z +C Z +A Z +C Z +B Z +B Z +B Z +C Z +C Z +C Z +A X +B X +C Z +A X +C X +B Z +C X +C Z +B Y +C Z +C Z +A X +C Z +C X +C X +C X +B Z +C Y +C Z +B Z +A X +C X +C X +C X +C Z +A Z +A Z +B Y +B Z +B Z +C X +A X +C X +C X +A X +B X +B Z +B Z +C X +C Z +C Z +C X +B X +A X +A Z +C X +C Z +B Z +B Y +C Z +A X +B X +B Z +C Z +C Y +C Z +C X +C Z +C Z +B Z +C Y +C X +A X +B Z +C Y +A Z +C Z +B Y +A X +A Z +A X +C Z +C Y +C Z +C Y +A Z +B Z +B Z +C Z +C Z +C X +C Z +C Y +C Z +C Z +B Y +A X +B Z +C Z +C X +C X +A Z +B Z +B Z +B Y +B Z +C Y +B Z +C Z +A X +C X +C X +B X +C Z +A X +C Y +B X +C Z +C Z +B Y +C Z +B Y +C Z +A Z +C Z +B Y +A X +C X +C X +C Z +C X +C Z +B Y +B Z +C Z +B Z +C Z +A X +B Z +C X +C Y +A Z +B Z +C X +A Z +C Y +B Y +C Y +C Z +C Z +A Z +A Z +C X +B Y +C Z +B Z +A X +B Z +A X +C X +C Z +B Z +C X +B Z +C X +A Y +C Z +B Z +C X +C X +C X +B X +B Y +A Y +B Z +A X +C X +C Z +B Y +C Z +C Z +B X +B X +A Y +C X +C Z +C X +C Z +C X +C X +C Z +C Z +C X +A X +C Z +B Z +B X +A X +B X +A Z +B X +C Z +C Z +A Z +C X +C X +A X +C Z +C X +C Z +C X +C X +C Z +A Z +C Z +A Z +C Z +B Z +C Z +C Y +C X +C Z +B Z +B Z +C Y +B Y +C X +C Y +A Z +A X +A X +A Z +C X +C X +C Z +C Z +B Z +C Z +A X +C Z +C X +B Z +A X +C Z +C Z +B Z +B Z +B X +B Z +A X +C Z +B Z +A Z +C X +C X +A Z +C Y +B Y +C X +B Z +C X +C Z +B Y +A Y +B Y +A X +C Y +C X +C Z +A X +A Z +B Z +B Y +C Y +B Z +A Y +B X +C Z +C Z +C X +A X +C Z +C Y +A Z +B Z +C Z +A Z +C Y +C Z +B X +C X +A Z +C Z +B Z +A X +B Y +C X +A X +B Y +C Z +B Z +C Z +C Y +A Z +C Z +B Z +C Z +C Z +A X +C Z +C Z +A Z +C X +C Z +A X +C Z +C Z +C Z +C Y +A X +B Z +B Z +A X +C Z +B Y +C Z +A X +C Y +B Z +C Z +A X +C Y +A Z +C X +B Y +C X +B Z +C Y +A Z +C X +C X +C Y +C X +A X +B Z +C X +C X +C X +B Z +B Y +B Z +C X +B Y +C Z +A X +C Z +A Z +C Y +C X +C Z +A Z +B Z +B Z +C X +A Z +A X +C Z +B X +A X +A X +B X +C X +C X +A Z +B Z +C Z +C X +B Z +A Z +A Z +C Z +C X +B Y +C X +C X +C X +C Z +C X +A X +C X +C Y +C Z +A X +C Y +B Z +B Z +A X +C Z +B Z +B Y +C Y +C X +A Z +B Y +A X +A Z +B Z +C X +B Z +A Z +C Y +C X +C X +C Z +B X +A X +C Z +C Z +C X +B Y +C Z +A Z +C Z +C Z +B Z +C X +C X +C Z +B Z +C Z +B Y +B Z +A X +B Z +A X +B Z +B Z +C Z +A Z +A X +A X +B Y +C Z +A Y +B Z +C Z +A Z +A Y +C Z +C Z +A X +C Y +C Z +C Z +A Z +C Y +C Z +A X +B Y +C Z +A X +B X +C X +A Z +C Z +A Z +C Y +C Z +C Y +A X +C X +B Z +B X +C Z +C Z +B Z +C Z +C Y +C X +B Z +A X +C Y +B Z +A Z +C Z +C X +B X +C Z +C Z +C Z +A X +C X +B X +C Y +A X +A Z +C X +C Y +C X +C X +A Z +A Z +C X +C X +C X +A X +A X +C X +A X +A X +A X +C Z +B Z +C Y +C Z +C Z +C X +C Y +A X +B Z +C Y +B Y +A X +A X +A Z +A Z +C Y +C Y +C X +C Z +A X +A X +C Z +C Z +B Z +B Z +C Z +A X +C X +C X +C X +A Z +C Z +A Z +B Y +B Y +C X +B Z +B Z +C Z +C Z +B Z +C Y +B Z +B X +B Z +C Z +A Z +A X +C X +A Y +C Z +A X +C X +A X +B X +C X +B Z +A X +C Z +B Z +C X +B Z +C Z +C X +A X +C Z +B Z +C Z +A Z +A X +A Z +C Z +C Z +B X +C Z +A Z +B Y +C Z +B X +B Z +C X +B X +A Z +C Z +C X +A Y +A X +C X +B Z +C X +C Y +C Y +C X +C Y +C Y +B X +B Z +A X +B Y +B Z +C Z +B Z +C Z +C Z +B Z +C X +C X +B Z +B Z +C X +C X +A X +C X +B Y +B X +C Z +B Z +A X +A Z +A Y +C Z +A Z +B Z +A Z +C X +C X +A Y +C X +B Z +B Y +B Y +C Z +B X +B Z +A X +B Y +C Z +C Z +A X +B Y +A Z +C Z +C Z +B Z +A Z +C Z +B Z +C Y +C X +B Z +A Z +A X +A X +A X +C Z +A Z +A X +C Y +C Y +B Z +C Z +B Y +C X +B Z +C X +B Z +B Y +C Z +A X +A X +B Z +A Z +B Z +C Z +C Z +A X +C X +C Z +A Z +A X +C Z +C X +B Z +C Z +A Z +C Z +B X +B Z +A X +C Z +C Z +A X +C X +A Z +C Z +A X +C Z +A Z +C X +C X +B Z +C Z +C X +B X +A X +B Z +B Y +B X +C Z +B X +B Z +C X +C Z +B Z +A Z +C Z +B Z +C Z +B X +B Y +C Z +C Y +C Z +B Y +B Z +C Z +A X +C X +C X +B Z +B Z +A X +A Y +A Z +C X +B X +C Z +C X +B Z +C X +A X +A X +B Z +B Y +B Z +B Y +C Y +C Z +B Z +C Y +B Z +C X +A X +B Y +C Z +A X +A X +C X +C Z +B Z +C Y +C Z +C X +C X +C Z +C X +B Z +C Y +C Z +A X +C X +B X +A X +B X +C X +C Z +A Z +A X +A Z +A X +A X +A X +A Y +A X +B Z +B Y +A X +C Z +A Z +C X +C Z +A Z +A Y +C Z +B Z +B Z +B Z +C X +A X +A X +C Z +C X +A X +C Z +C X +A X +C Y +B Z +C Z +C X +C X +C X +C Z +C X +C Y +B Y +C X +B Y +B Z +C X +C Z +A X +B Z +C Z +C X +A Y \ No newline at end of file diff --git a/day2/data/input_test.txt b/day2/data/input_test.txt new file mode 100644 index 0000000..25097e8 --- /dev/null +++ b/day2/data/input_test.txt @@ -0,0 +1,3 @@ +A Y +B X +C Z \ No newline at end of file diff --git a/day2/src/main.rs b/day2/src/main.rs new file mode 100644 index 0000000..6b0fabb --- /dev/null +++ b/day2/src/main.rs @@ -0,0 +1,232 @@ +use std::convert::TryFrom; +use std::error::Error; +use std::ops::Not; + +#[derive(PartialEq, Eq)] +enum Part { + Part1, + Part2, +} + +#[derive(Debug, Eq, PartialEq)] +enum Game { + Win, + Lose, + Draw, +} + +impl TryFrom<&str> for Game { + type Error = &'static str; + + fn try_from(string: &str) -> Result { + match string { + "X" => Ok(Game::Lose), + "Y" => Ok(Game::Draw), + "Z" => Ok(Game::Win), + _ => Err("ParseError"), + } + } +} + +impl Not for Game { + type Output = Game; + + fn not(self) -> Self::Output { + match self { + Self::Win => Self::Lose, + Self::Lose => Self::Win, + Self::Draw => Self::Draw, + } + } +} + +#[derive(Debug, Eq, PartialEq)] +enum Hand { + Rock = 1, + Paper = 2, + Sizzors = 3, +} + +impl TryFrom<&str> for Hand { + type Error = &'static str; + + fn try_from(string: &str) -> Result { + match string { + "A" | "X" => Ok(Hand::Rock), + "B" | "Y" => Ok(Hand::Paper), + "C" | "Z" => Ok(Hand::Sizzors), + _ => Err("ParseError"), + } + } +} + +impl From<&Hand> for u32 { + fn from(hand: &Hand) -> u32 { + match *hand { + Hand::Rock => 1, + Hand::Paper => 2, + Hand::Sizzors => 3, + } + } +} + +impl Hand { + fn cmp(&self, other: &Self) -> Game { + match *self { + Hand::Rock => match *other { + Hand::Rock => Game::Draw, + Hand::Paper => Game::Lose, + Hand::Sizzors => Game::Win, + }, + Hand::Paper => match *other { + Hand::Rock => Game::Win, + Hand::Paper => Game::Draw, + Hand::Sizzors => Game::Lose, + }, + Hand::Sizzors => match *other { + Hand::Rock => Game::Lose, + Hand::Paper => Game::Win, + Hand::Sizzors => Game::Draw, + }, + } + } + + fn opponent_from_result(&self, game: &Game) -> &Hand { + let result = (self, game); + + match result { + (hand, Game::Draw) => hand, + (&Hand::Rock, &Game::Win) | (&Hand::Paper, &Game::Lose) => &Hand::Sizzors, + (&Hand::Sizzors, &Game::Win) | (&Hand::Rock, &Game::Lose) => &Hand::Paper, + (&Hand::Paper, &Game::Win) | (&Hand::Sizzors, &Game::Lose) => &Hand::Rock, + } + } +} + +fn score(theirs: &Hand, yours: &Hand) -> u32 { + let score: u32 = yours.into(); + + match yours.cmp(theirs) { + Game::Win => score + 6, + Game::Draw => score + 3, + Game::Lose => score, + } +} + +fn score_line(line: &str, part: &Part) -> Result> { + let mut splits = line.split_whitespace(); + let theirs = Hand::try_from(splits.next().unwrap())?; + + match *part { + Part::Part1 => { + let yours = Hand::try_from(splits.next().unwrap())?; + Ok(score(&theirs, &yours)) + } + Part::Part2 => { + let result = Game::try_from(splits.next().unwrap())?; + let yours = theirs.opponent_from_result(&(!result)); + Ok(score(&theirs, yours)) + } + } +} + +fn score_lines(lines: &[&str], part: &Part) -> u32 { + lines.iter().map(|l| score_line(l, part).unwrap()).sum() +} + +fn main() { + let input = include_str!("../data/input.txt"); + + let lines: Vec<&str> = input.lines().collect(); + println!("Part 1 answer {}", score_lines(&lines, &Part::Part1)); + println!("Part 2 answer {}", score_lines(&lines, &Part::Part2)); +} + +#[cfg(test)] +pub mod tests { + use super::*; + use std::error::Error; + + #[test] + fn test_compare() { + assert_eq!(Hand::Rock.cmp(&Hand::Paper), Game::Lose); + assert_eq!(Hand::Paper.cmp(&Hand::Sizzors), Game::Lose); + assert_eq!(Hand::Sizzors.cmp(&Hand::Rock), Game::Lose); + } + #[test] + fn test_hand_from_str() -> Result<(), Box> { + assert_eq!(Hand::try_from("A")?, Hand::Rock); + assert_eq!(Hand::try_from("B")?, Hand::Paper); + assert_eq!(Hand::try_from("C")?, Hand::Sizzors); + + assert_eq!(Hand::try_from("X")?, Hand::Rock); + assert_eq!(Hand::try_from("Y")?, Hand::Paper); + assert_eq!(Hand::try_from("Z")?, Hand::Sizzors); + + Ok(()) + } + + #[test] + fn test_game_from_str() -> Result<(), Box> { + assert_eq!(Game::try_from("X")?, Game::Lose); + assert_eq!(Game::try_from("Y")?, Game::Draw); + assert_eq!(Game::try_from("Z")?, Game::Win); + Ok(()) + } + #[test] + fn test_score() { + let theirs = Hand::Rock; + let yours = Hand::Paper; + assert_eq!(score(&theirs, &yours), 8); + + let theirs = Hand::Paper; + let yours = Hand::Rock; + assert_eq!(score(&theirs, &yours), 1); + + let theirs = Hand::Sizzors; + let yours = Hand::Sizzors; + assert_eq!(score(&theirs, &yours), 6); + } + + #[test] + fn test_other_hand() { + assert_eq!(Hand::Rock.opponent_from_result(&Game::Win), &Hand::Sizzors); + assert_eq!(Hand::Rock.opponent_from_result(&Game::Lose), &Hand::Paper); + assert_eq!(Hand::Rock.opponent_from_result(&Game::Draw), &Hand::Rock); + + assert_eq!(Hand::Paper.opponent_from_result(&Game::Win), &Hand::Rock); + assert_eq!( + Hand::Paper.opponent_from_result(&Game::Lose), + &Hand::Sizzors + ); + assert_eq!(Hand::Paper.opponent_from_result(&Game::Draw), &Hand::Paper); + + assert_eq!(Hand::Sizzors.opponent_from_result(&Game::Win), &Hand::Paper); + assert_eq!(Hand::Sizzors.opponent_from_result(&Game::Lose), &Hand::Rock); + assert_eq!( + Hand::Sizzors.opponent_from_result(&Game::Draw), + &Hand::Sizzors + ); + } + + #[test] + fn test_score_line() -> Result<(), Box> { + assert_eq!(score_line("A Y", &Part::Part1)?, 8); + assert_eq!(score_line("B X", &Part::Part1)?, 1); + assert_eq!(score_line("C Z", &Part::Part1)?, 6); + + assert_eq!(score_line("A Y", &Part::Part2)?, 4); + assert_eq!(score_line("B X", &Part::Part2)?, 1); + assert_eq!(score_line("C Z", &Part::Part2)?, 7); + + Ok(()) + } + + #[test] + fn test_score_lines_from_file() { + let input = include_str!("../data/input_test.txt"); + let lines: Vec<&str> = input.lines().collect(); + assert_eq!(score_lines(&lines, &Part::Part1), 15); + assert_eq!(score_lines(&lines, &Part::Part2), 12); + } +}