#[path = "../lib.rs"] mod lib; fn parse(line: &str) -> (Vec<(u32, usize, usize)>, Vec, Vec) { let mut numbers = vec![]; let mut symbols = vec![]; let mut gears = vec![]; let mut number = 0; let mut number_len = 0; for (x, c) in line.chars().enumerate() { if let Some(i) = c.to_digit(10) { number = number * 10 + i; number_len += 1; } else { if number > 0 { numbers.push((number, x - number_len, x)); number = 0; number_len = 0; } if c != '.' { symbols.push(x); } if c == '*' { gears.push(x); } } } if number > 0 { let x = line.len(); numbers.push((number, x - number_len, x)); } return (numbers, symbols, gears); } fn part1(numbers: &Vec<(u32, usize, usize)>, symbols: Vec<&Vec>) -> u32 { let mut sum = 0; for (number, start, end) in numbers.iter() { let s = if *start > 1 { *start - 1 } else { *start }; for x in (s)..(*end + 1) { if symbols.iter().any(|s| s.contains(&x)) { sum += number; break; } } } return sum; } fn part2(gears: &Vec, numbers: Vec<&Vec<(u32, usize, usize)>>) -> u32 { let mut sum = 0; for gear in gears.iter() { let mut neighbors = vec![]; for n in numbers.iter() { for (number, start, end) in n.iter() { if *gear + 1 >= *start && *gear < *end + 1 { neighbors.push(*number); } } } if neighbors.len() == 2 { sum += neighbors.iter().product::(); } } return sum; } fn main() { let mut sum1 = 0; let mut sum2 = 0; let mut prev_symbols; let mut curr_symbols = vec![]; let mut next_symbols = vec![]; let mut prev_numbers; let mut curr_numbers = vec![]; let mut next_numbers = vec![]; let mut curr_gears; let mut next_gears = vec![]; for line in lib::iter_input() { (prev_symbols, prev_numbers) = (curr_symbols, curr_numbers); (curr_symbols, curr_numbers, curr_gears) = (next_symbols, next_numbers, next_gears); (next_numbers, next_symbols, next_gears) = parse(&line); sum1 += part1(&curr_numbers, vec![&prev_symbols, &curr_symbols, &next_symbols]); sum2 += part2(&curr_gears, vec![&prev_numbers, &curr_numbers, &next_numbers]); } sum1 += part1(&next_numbers, vec![&curr_symbols, &next_symbols]); sum2 += part2(&next_gears, vec![&curr_numbers, &next_numbers]); println!("part1: {}", sum1); println!("part2: {}", sum2); }