Browse Source

Completed day 11

Tyler Hallada 4 years ago
parent
commit
6190b9742c
4 changed files with 204 additions and 4 deletions
  1. 2 0
      Cargo.lock
  2. 1 0
      inputs/11.txt
  3. 190 0
      src/day11.rs
  4. 11 4
      src/main.rs

+ 2 - 0
Cargo.lock

@@ -1,3 +1,5 @@
1
+# This file is automatically @generated by Cargo.
2
+# It is not intended for manual editing.
1 3
 [[package]]
2 4
 name = "advent-of-code-2018"
3 5
 version = "0.1.0"

+ 1 - 0
inputs/11.txt

@@ -0,0 +1 @@
1
+8979

+ 190 - 0
src/day11.rs

@@ -0,0 +1,190 @@
1
+use std::error::Error;
2
+use std::fmt;
3
+use std::fs;
4
+use std::result;
5
+
6
+type Result<T> = result::Result<T, Box<Error>>;
7
+
8
+const INPUT: &str = "inputs/11.txt";
9
+const GRID_SIZE: usize = 300;
10
+
11
+#[derive(Clone)]
12
+struct Cells([[Option<i8>; GRID_SIZE]; GRID_SIZE]);
13
+
14
+impl fmt::Display for Cells {
15
+    #[allow(clippy::write_with_newline)]
16
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17
+        for x in 0..GRID_SIZE {
18
+            for y in 0..GRID_SIZE {
19
+                match self.0[x][y] {
20
+                    Some(power) => write!(f, "{}", power)?,
21
+                    None => write!(f, ".")?,
22
+                }
23
+            }
24
+            write!(f, "\n")?;
25
+        }
26
+        Ok(())
27
+    }
28
+}
29
+
30
+impl fmt::Debug for Cells {
31
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32
+        writeln!(f, "Cells {{\n{}\n}}", self)?;
33
+        Ok(())
34
+    }
35
+}
36
+
37
+#[derive(Debug, Clone)]
38
+struct Grid {
39
+    serial_number: usize,
40
+    cells: Cells,
41
+}
42
+
43
+#[derive(Debug, PartialEq, Clone)]
44
+pub struct Coordinate {
45
+    pub x: usize,
46
+    pub y: usize,
47
+}
48
+
49
+#[derive(Debug, PartialEq, Clone)]
50
+pub struct Subsection {
51
+    pub coord: Coordinate,
52
+    pub size: usize,
53
+}
54
+
55
+impl Grid {
56
+    fn new(serial_number: usize) -> Grid {
57
+        Grid {
58
+            serial_number,
59
+            cells: Cells([[None; GRID_SIZE]; GRID_SIZE]),
60
+        }
61
+    }
62
+
63
+    fn power_at_cell(&self, coord: &Coordinate) -> i8 {
64
+        let rack_id = coord.x + 10;
65
+        let mut power_level = rack_id * coord.y;
66
+        power_level += self.serial_number;
67
+        power_level *= rack_id;
68
+        power_level = power_level / 100 % 10;
69
+        power_level as i8 - 5
70
+    }
71
+
72
+    fn power_of_subsection(&mut self, subsection: &Subsection) -> i32 {
73
+        let mut power_level: i32 = 0;
74
+        let Subsection { coord, size } = subsection;
75
+        for x in coord.x..coord.x + size {
76
+            for y in coord.y..coord.y + size {
77
+                power_level += i32::from(match self.cells.0[x][y] {
78
+                    Some(power) => power,
79
+                    None => {
80
+                        let power = self.power_at_cell(&Coordinate { x, y });
81
+                        self.cells.0[x][y] = Some(power);
82
+                        power
83
+                    }
84
+                });
85
+            }
86
+        }
87
+        power_level
88
+    }
89
+
90
+    fn highest_power_subsection(&mut self, size: usize) -> (Subsection, i32) {
91
+        let mut highest_power_subsection = Subsection {
92
+            coord: Coordinate { x: 0, y: 0 },
93
+            size,
94
+        };
95
+        let mut highest_power_level = self.power_of_subsection(&highest_power_subsection);
96
+        for x in 0..GRID_SIZE - size {
97
+            for y in 0..GRID_SIZE - size {
98
+                let subsection = Subsection {
99
+                    coord: Coordinate { x, y },
100
+                    size,
101
+                };
102
+                if subsection == highest_power_subsection {
103
+                    continue;
104
+                };
105
+                let power = self.power_of_subsection(&subsection);
106
+                if power > highest_power_level {
107
+                    highest_power_subsection = subsection;
108
+                    highest_power_level = power;
109
+                }
110
+            }
111
+        }
112
+        (highest_power_subsection, highest_power_level)
113
+    }
114
+}
115
+
116
+fn read_serial_number_file(filename: &str) -> Result<usize> {
117
+    let serial_number = fs::read_to_string(filename)?;
118
+    Ok(serial_number.trim().parse()?)
119
+}
120
+
121
+pub fn solve_part1() -> Result<Subsection> {
122
+    let serial_number = read_serial_number_file(INPUT)?;
123
+    let mut grid = Grid::new(serial_number);
124
+    Ok(grid.highest_power_subsection(3).0)
125
+}
126
+
127
+pub fn solve_part2() -> Result<Subsection> {
128
+    let serial_number = read_serial_number_file(INPUT)?;
129
+    let mut grid = Grid::new(serial_number);
130
+    let (mut highest_power_subsection, mut highest_power_level) = grid.highest_power_subsection(1);
131
+
132
+    for size in 2..=GRID_SIZE {
133
+        let (subsection, power) = grid.highest_power_subsection(size);
134
+        if power > highest_power_level {
135
+            highest_power_subsection = subsection;
136
+            highest_power_level = power;
137
+        }
138
+    }
139
+    Ok(highest_power_subsection)
140
+}
141
+
142
+#[cfg(test)]
143
+mod tests {
144
+    use super::*;
145
+
146
+    #[test]
147
+    fn creates_new_empty_grid() {
148
+        let grid = Grid::new(18);
149
+        assert_eq!(grid.serial_number, 18);
150
+    }
151
+
152
+    #[test]
153
+    fn returns_power_at_cell() {
154
+        let grid = Grid::new(8);
155
+        assert_eq!(grid.power_at_cell(&Coordinate { x: 3, y: 5 }), 4);
156
+        let grid = Grid::new(57);
157
+        assert_eq!(grid.power_at_cell(&Coordinate { x: 122, y: 79 }), -5);
158
+        let grid = Grid::new(39);
159
+        assert_eq!(grid.power_at_cell(&Coordinate { x: 217, y: 196 }), 0);
160
+        let grid = Grid::new(71);
161
+        assert_eq!(grid.power_at_cell(&Coordinate { x: 101, y: 153 }), 4);
162
+    }
163
+
164
+    #[test]
165
+    fn returns_power_of_subsection() {
166
+        let mut grid = Grid::new(18);
167
+        assert_eq!(
168
+            grid.power_of_subsection(&Subsection {
169
+                coord: Coordinate { x: 33, y: 45 },
170
+                size: 3
171
+            }),
172
+            29
173
+        );
174
+    }
175
+
176
+    #[test]
177
+    fn returns_highest_power_subsection() {
178
+        let mut grid = Grid::new(18);
179
+        assert_eq!(
180
+            grid.highest_power_subsection(3),
181
+            (
182
+                Subsection {
183
+                    coord: Coordinate { x: 33, y: 45 },
184
+                    size: 3
185
+                },
186
+                29
187
+            )
188
+        );
189
+    }
190
+}

+ 11 - 4
src/main.rs

@@ -13,6 +13,7 @@ mod day7;
13 13
 mod day8;
14 14
 mod day9;
15 15
 mod day10;
16
+mod day11;
16 17
 
17 18
 fn main() {
18 19
     // println!("Day 1:");
@@ -42,8 +43,14 @@ fn main() {
42 43
     // println!("Day 9:");
43 44
     // println!("{}", day9::solve_part1().unwrap());
44 45
     // println!("{}", day9::solve_part2().unwrap());
45
-    println!("Day 10:");
46
-    let parts = day10::solve_parts().unwrap();
47
-    println!("{}", parts.0);
48
-    println!("{}", parts.1);
46
+    // println!("Day 10:");
47
+    // let parts = day10::solve_parts().unwrap();
48
+    // println!("{}", parts.0);
49
+    // println!("{}", parts.1);
50
+    println!("Day 11:");
51
+    let part1 = day11::solve_part1().unwrap();
52
+    println!("{},{}", part1.coord.x, part1.coord.y);
53
+    let part2 = day11::solve_part2().unwrap();
54
+    println!("{},{},{}", part2.coord.x, part2.coord.y, part2.size);
55
+    // println!("{}", parts.1);
49 56
 }