]> aoc.elinar.fr Git - aoc_2023/commitdiff
Day07 - réparation de la partie 1
authoralex <null>
Thu, 7 Dec 2023 11:32:01 +0000 (12:32 +0100)
committeralex <null>
Thu, 7 Dec 2023 13:11:10 +0000 (14:11 +0100)
src/day07.rs

index 834fcc993bada1a45b329ad691d6828acba7548c..e659cee3ffb49a1ab8fd7b73e5e886305ec6531c 100644 (file)
@@ -19,7 +19,8 @@ pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
     Ok(())
 }
 
-static CARDS: &str = "J123456789TQKA";
+static CARDS: &str = "123456789TJQKA";
+static CARDS_JOKERS: &str = "J123456789TQKA";
 
 #[derive(Debug, PartialEq, PartialOrd)]
 enum HandType {
@@ -37,22 +38,23 @@ struct Hand {
     cards: [char ; 5],
     bid: u32,
     hand_type: HandType,
+    with_jokers: bool,
 }
 
 impl Hand {
-    pub fn new(cards: &str, bid: u32) -> Self {
+    pub fn new(cards: &str, bid: u32, with_jokers: bool) -> Self {
         let mut hand_cards: [ char ; 5 ] = [ '\0' ; 5];
         cards.chars().enumerate()
             .for_each(|(i,c)| hand_cards[i] = c);
         Self {
             cards: hand_cards,
             bid,
-            hand_type: Self::find_type(hand_cards),
+            hand_type: Self::find_type(hand_cards, with_jokers),
+            with_jokers,
         }
-
     }
 
-    pub fn find_type(cards: [char; 5]) -> HandType {
+    pub fn find_type(cards: [char; 5], with_jokers: bool) -> HandType {
         let mut map: HashMap<_, u32> = CARDS.chars()
             .map(|c| (c, 0_u32))
             .collect();
@@ -67,18 +69,31 @@ impl Hand {
 
         // on ne conserve que le type de cartes de la main et leur nombre
         // d'occurrence
-        // attention: si 5 jokers, on les garde
-        let mut occurrence = map.into_iter()
+        if with_jokers {
+            // on ne conserve que les cartes qui ne sont pas des jokers
+            // attention: si 5 jokers, on les garde
+            map = map.into_iter()
             .filter(|(k,v)| (v > &0 && k != &'J') || (k == &'J' && v == &5))
+            .collect();
+        } else {
+            map = map.into_iter()
+            .filter(|(k,v)| v > &0)
+            .collect();
+        }
+
+        let mut occurrence = map.into_iter()
             .map(|(_,v)| v)
             .collect::<Vec<_>>();
 
-        // trie des occurences par ordre décroissant
-        occurrence.sort_by(|a, b| b.cmp(&a));
-        // les J sont associées aux cartes ayant le plus d'occurrence
-        // sauf si toutes les cartes sont des J
-        if occurrence[0] < 5 {
-            occurrence[0] += jokers;
+        if with_jokers {
+            // trie des occurences par ordre décroissant
+            occurrence.sort_by(|a, b| b.cmp(&a));
+
+            // les J sont associées aux cartes ayant le plus d'occurrence
+            // sauf si toutes les cartes sont des J
+            if occurrence[0] < 5 {
+                occurrence[0] += jokers;
+            }
         }
 
         match occurrence.len() {
@@ -113,24 +128,26 @@ impl PartialOrd for Hand {
             while self.cards[i] == other.cards[i] {
                 i += 1;
             }
-            let self_pos = CARDS.chars().position(|c| c == self.cards[i]).unwrap();
-            let other_pos = CARDS.chars().position(|c| c == other.cards[i]).unwrap();
+            let cards = match self.with_jokers && other.with_jokers {
+                true => CARDS_JOKERS,
+                false => CARDS,
+            };
+            let self_pos = cards.chars().position(|c| c == self.cards[i]).unwrap();
+            let other_pos = cards.chars().position(|c| c == other.cards[i]).unwrap();
             return Some(self_pos.cmp(&other_pos));
         }
         self.hand_type.partial_cmp(&other.hand_type)
     }
 }
 
-fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
-    println!("Running day07 - part 1");
-
+fn solve(input: &str, with_jokers: bool) -> u32 {
     let mut hands: Vec<Hand> = Vec::new();
 
     input.lines()
         .filter(|l| !l.is_empty())
         .for_each(|l| {
             let (cards, bid) = l.split_once(' ').unwrap();
-            hands.push(Hand::new(cards, bid.parse().unwrap()));
+            hands.push(Hand::new(cards, bid.parse().unwrap(), with_jokers));
         });
 
     hands.sort_by(|a, b| {
@@ -144,12 +161,19 @@ fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
         })
         .sum();
 
+    res
+}
+
+fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
+    println!("Running day07 - part 1");
+    let res = solve(input, false);
     Ok(res)
 }
 
 fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
     println!("Running day07 - part 2");
-    run_part1(input)
+    let res = solve(input, true);
+    Ok(res)
 }
 
 #[cfg(test)]