1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
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<Instruction> {
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::<usize>().unwrap();
let y1 = cap[3].parse::<usize>().unwrap();
let x2 = cap[4].parse::<usize>().unwrap();
let y2 = cap[5].parse::<usize>().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);
}
}
|