use regex::Regex; fn main() { let input = advent::read_lines(6); println!("6a: {}", count_lit(&input)); println!("6b: {}", total_brightness(&input)); } enum Operation { Toggle, TurnOn, TurnOff, } struct Instruction { op: Operation, from: (usize, usize), to: (usize, usize), } fn parse_instructions(input: &[String]) -> Vec { let re = Regex::new(r"^([a-z ]+) (\d+),(\d+) through (\d+),(\d+)$").unwrap(); let mut instructions = Vec::new(); for line in input { let cap = re.captures(line).unwrap(); let op = match &cap[1] { "turn on" => Operation::TurnOn, "turn off" => Operation::TurnOff, "toggle" => Operation::Toggle, err => panic!("unsupported operation: {}", err), }; let x1 = cap[2].parse::().unwrap(); let y1 = cap[3].parse::().unwrap(); let x2 = cap[4].parse::().unwrap(); let y2 = cap[5].parse::().unwrap(); instructions.push(Instruction { op, from: (x1,y1), to: (x2,y2) }); } instructions } fn decorations(input: &[String]) -> [[bool; 1000]; 1000] { let instructions = parse_instructions(input); let mut grid = [[false; 1000]; 1000]; for Instruction { op, from, to } in instructions { for grid_x in grid.iter_mut().take(to.0 + 1).skip(from.0) { for grid_x_y in grid_x.iter_mut().take(to.1 + 1).skip(from.1) { *grid_x_y = match op { Operation::Toggle => !*grid_x_y, Operation::TurnOn => true, Operation::TurnOff => false, }; } } } grid } fn decorations2(input: &[String]) -> Vec<[i32; 1000]> { let instructions = parse_instructions(input); let mut grid = Vec::new(); for _ in 0..1000 { grid.push([0; 1000]); } for Instruction { op, from, to } in instructions { for grid_x in grid.iter_mut().take(to.0 + 1).skip(from.0) { for grid_x_y in grid_x.iter_mut().take(to.1 + 1).skip(from.1) { *grid_x_y = match op { Operation::Toggle => *grid_x_y + 2, Operation::TurnOn => *grid_x_y + 1, Operation::TurnOff => std::cmp::max(0, *grid_x_y - 1), }; } } } grid } fn count_lit(input: &[String]) -> usize { decorations(input).iter() .flatten() .filter(|&x| *x) .count() } fn total_brightness(input: &[String]) -> i32 { decorations2(input).iter() .flatten() .sum() } #[cfg(test)] mod tests { use super::*; #[test] fn test() { assert_eq!(count_lit(&["turn on 0,0 through 999,999".to_string()]), 1000 * 1000); assert_eq!(total_brightness(&["turn on 0,0 through 0,0".to_string()]), 1); assert_eq!(total_brightness(&["toggle 0,0 through 999,999".to_string()]), 2000000); } }