From: alex <> Date: Sat, 6 Dec 2025 09:30:06 +0000 (+0100) Subject: day06: part2 X-Git-Url: https://aoc.elinar.fr/?a=commitdiff_plain;h=6316bd3fe671417979014a472b147b707a42feb6;p=aoc_2025 day06: part2 --- diff --git a/src/day06.rs b/src/day06.rs index 3f3fbac..42a3748 100644 --- a/src/day06.rs +++ b/src/day06.rs @@ -2,18 +2,21 @@ use std::error::Error; struct Puzzle { operands: Vec>, - operators: Vec, + 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::new(); - let mut operators: Vec = 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> = 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::().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> { 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()); + } }