From b5c8aae7a0497810331759b47a22f0b2ebe765b1 Mon Sep 17 00:00:00 2001
From: Oscar Najera <hi@oscarnajera.com>
Date: Fri, 2 Dec 2022 20:19:19 +0100
Subject: [AoC2022] Rust 02-02

---
 AoC2022/02/makefile  |  1 +
 AoC2022/02/solver.rs | 82 ++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/AoC2022/02/makefile b/AoC2022/02/makefile
index 73929a6..630e630 100644
--- a/AoC2022/02/makefile
+++ b/AoC2022/02/makefile
@@ -11,3 +11,4 @@
 run:
 	emacs -batch -l ert -l solver.el -f ert-run-tests-batch-and-exit
 	sbcl --load ~/.sbclrc --script solver.lisp
+	rustc solver.rs && ./solver
diff --git a/AoC2022/02/solver.rs b/AoC2022/02/solver.rs
index 1f9a394..2fd1e62 100644
--- a/AoC2022/02/solver.rs
+++ b/AoC2022/02/solver.rs
@@ -1,7 +1,7 @@
 use std::fs;
 use std::io::{self, BufRead};
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
 enum Hand {
     Rock,
     Paper,
@@ -25,28 +25,80 @@ fn weight(play: Hand) -> u32 {
     }
 }
 
+enum Conclusion {
+    Loose,
+    Draw,
+    Win,
+}
+
+fn strategy(play: &str) -> Conclusion {
+    match play {
+        "X" => Conclusion::Loose,
+        "Y" => Conclusion::Draw,
+        "Z" => Conclusion::Win,
+        &_ => panic!("Invalid input"),
+    }
+}
+fn wins(play: Hand) -> Hand {
+    match play {
+        Hand::Rock => Hand::Scissors,
+        Hand::Scissors => Hand::Paper,
+        Hand::Paper => Hand::Rock,
+    }
+}
+fn looses(play: Hand) -> Hand {
+    match play {
+        Hand::Scissors => Hand::Rock,
+        Hand::Paper => Hand::Scissors,
+        Hand::Rock => Hand::Paper,
+    }
+}
+
+fn pick_move(strategy: Conclusion, other: Hand) -> Hand {
+    match strategy {
+        Conclusion::Draw => other,
+        Conclusion::Win => looses(other),
+        Conclusion::Loose => wins(other),
+    }
+}
+
 fn fight(my: Hand, other: Hand) -> u32 {
     match (my, other) {
         (a, b) if a == b => 3,
-        (Hand::Rock, Hand::Scissors)
-        | (Hand::Scissors, Hand::Paper)
-        | (Hand::Paper, Hand::Rock) => 6,
-        _ => 0,
+        (a, b) => {
+            if wins(a) == b {
+                6
+            } else {
+                0
+            }
+        }
     }
 }
 
-fn main() -> std::io::Result<()> {
+fn fixed_plays(my: &str, _oponent: Hand) -> Hand {
+    translate(my)
+}
+
+fn reactive_plays(my: &str, oponent: Hand) -> Hand {
+    pick_move(strategy(my), oponent)
+}
+
+fn solver(strategy: &dyn Fn(&str, Hand) -> Hand) -> u32 {
     let file = fs::File::open("input").unwrap();
     let lines = io::BufReader::new(file).lines();
-    let mut score = 0;
-    for line in lines {
-        if let [ot, my] = line?.split_whitespace().collect::<Vec<_>>()[..] {
-            score += fight(translate(my), translate(ot)) + weight(translate(my));
+    lines.fold(0, |acc, line| {
+        if let [ot, my] = line.unwrap().split_whitespace().collect::<Vec<_>>()[..] {
+            let opo = translate(ot);
+            let my_hand = strategy(my, opo.clone());
+            acc + fight(my_hand.clone(), opo) + weight(my_hand)
         } else {
-            todo!()
-        };
-    }
+            panic!("Wrong line")
+        }
+    })
+}
 
-    println!("{}", score);
-    Ok(())
+fn main() {
+    assert_eq!(12535, solver(&fixed_plays));
+    assert_eq!(15457, solver(&reactive_plays));
+    println!("All test passed.")
 }
-- 
cgit v1.2.3