summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2022-08-28 14:18:14 +0200
committerReiner Herrmann <reiner@reiner-h.de>2022-08-28 14:18:14 +0200
commit06773c99cb5a614a54d80482e4e5fdd59b010e54 (patch)
treedd78e0a402a165c3b195309b39dd572ec65c3dd4 /src
parent18f4224927c44c472c6c519bc37cb65c8b352863 (diff)
day6
Diffstat (limited to 'src')
-rw-r--r--src/bin/day6.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/bin/day6.rs b/src/bin/day6.rs
new file mode 100644
index 0000000..67896e4
--- /dev/null
+++ b/src/bin/day6.rs
@@ -0,0 +1,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);
+ }
+}