]> aoc.elinar.fr Git - aoc_2025/commitdiff
day06: part2
authoralex <>
Sat, 6 Dec 2025 09:30:06 +0000 (10:30 +0100)
committeralex <>
Sat, 6 Dec 2025 09:30:06 +0000 (10:30 +0100)
src/day06.rs

index 3f3fbac64ba7e1dcccf7beb9a11b0d6005c38fd6..42a374808a8b149c605b12ba4fd6d0ddc2d1e3bc 100644 (file)
@@ -2,18 +2,21 @@ use std::error::Error;
 
 struct Puzzle {
     operands: Vec<Vec<u64>>,
-    operators: Vec<char>,
+    operators: Vec<(char, usize)>, // store the idx of the operator (for part2)
+    value_col: Vec<(u64, usize)>,
 }
 
 impl Puzzle {
     fn new(input: &str) -> Self {
-        let mut operands: Vec<Vec<u64>> = Vec::new();
-        let mut operators: Vec<char> = Vec::new();
+        let mut operands = Vec::new();
+        let mut operators = Vec::new();
         let mut it = input.lines().peekable();
         while let Some(line) = it.next() {
             if it.peek().is_none() { // last line
-                operators = line.split_whitespace()
-                    .map(|word| word.chars().next().unwrap())
+                operators = line.chars()
+                    .enumerate()
+                    .filter(|(_, c)| *c != ' ')
+                    .map(|(i, c)| (c, i))
                     .collect();
             } else {
                 line.split_whitespace()
@@ -26,11 +29,29 @@ impl Puzzle {
                     });
             }
         }
-        Puzzle { operands, operators }
+
+        // extract the value in columns with the index of the left-most digit
+        let mut value_col = Vec::new();
+        let chars: Vec<Vec<char>> = input.lines()
+            .map(|line| {
+                line.chars().collect()
+            })
+            .collect();
+        for i in 0..chars[0].len() {
+            let mut value = String::new();
+            for j in 0..(chars.len()-1) { // do not read the last line (the operators)
+                value.push(chars[j][i]);
+            }
+            if !value.trim().is_empty() {
+                value_col.push((value.trim().parse::<u64>().unwrap(), i));
+            }
+        }
+
+        Puzzle { operands, operators, value_col }
     }
 
     fn part1(&self) -> u64 {
-        self.operators.iter().enumerate().map(|(i, op)| {
+        self.operators.iter().map(|(c, _)| c).enumerate().map(|(i, op)| {
             let res: u64 = match op {
                 '+' => self.operands[i].iter().sum(),
                 '*' => self.operands[i].iter().product(),
@@ -40,11 +61,46 @@ impl Puzzle {
         })
         .sum()
     }
+
+    // in this part, read the operands in column
+    //  [
+    //    123 -> 1, 2, 3
+    //     45 -> 0, 4, 5
+    //      6 -> 0, 0, 6
+    //  ]
+    //  -> [ 1, 24, 356 ]
+    fn part2(&self) -> u64 {
+        // consume the operators and operands in reverse order (from right to left)
+        // so we can rely on the idx of the operator
+        let mut res: u64 = 0;
+        let mut it_operator = self.operators.iter().rev();
+        let mut it_operand = self.value_col.iter().rev().peekable();
+        while let Some(op) = it_operator.next() {
+            let mut tmp: u64 = match op.0 {
+                '+' => 0,
+                '*' => 1,
+                _ => unreachable!(),
+            };
+            while let Some(value) = it_operand.next() {
+                match op.0 {
+                    '+' => { tmp += value.0; },
+                    '*' => { tmp *= value.0; },
+                    _ => unreachable!(),
+                };
+                if it_operand.peek().is_some() && it_operand.peek().unwrap().1 < op.1 {
+                    break;
+                }
+            }
+            res += tmp;
+        }
+        res
+    }
 }
 
 pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
     let p = Puzzle::new(input);
     println!("part1: {}", p.part1());
+    println!("part2: {}", p.part2());
     Ok(())
 }
 
@@ -63,4 +119,8 @@ mod tests {
     fn test_part1() {
         assert_eq!(4277556, Puzzle::new(TEST_INPUT).part1());
     }
+    #[test]
+    fn test_part2() {
+        assert_eq!(3263827, Puzzle::new(TEST_INPUT).part2());
+    }
 }