|
1 | | -use std::io::Result; |
| 1 | +use aoc_rust_common::Solution; |
| 2 | +use std::fmt::Display; |
2 | 3 |
|
3 | | -const SERIAL_NUMBER: i32 = 6392; |
4 | | -const GRID_SIZE: i32 = 300; |
5 | | - |
6 | | -struct Grid { |
7 | | - power: Vec<Vec<i32>>, |
8 | | -} |
9 | | - |
10 | | -impl Grid { |
11 | | - fn new(size: i32) -> Grid { |
12 | | - Grid { |
13 | | - power: vec![vec![0; size as usize]; size as usize], |
14 | | - } |
15 | | - } |
16 | | - |
17 | | - fn set(&mut self, x: i32, y: i32, power: i32) { |
18 | | - self.power[x as usize - 1][y as usize - 1] = power; |
19 | | - } |
20 | | - |
21 | | - fn get(&self, x: i32, y: i32) -> Option<i32> { |
22 | | - let (x, y) = (x - 1, y - 1); |
23 | | - if (0..GRID_SIZE).contains(&x) && (0..GRID_SIZE).contains(&y) { |
24 | | - Some(self.power[x as usize][y as usize]) |
25 | | - } else { |
26 | | - None |
27 | | - } |
28 | | - } |
| 4 | +pub struct Day11; |
29 | 5 |
|
30 | | - fn square_power(&self, size: i32, top_left_x: i32, top_left_y: i32) -> i32 { |
31 | | - let mut power = 0; |
32 | | - for x in top_left_x..top_left_x + size { |
33 | | - for y in top_left_y..top_left_y + size { |
34 | | - power += self.get(x, y).unwrap_or(0); |
35 | | - } |
36 | | - } |
37 | | - power |
38 | | - } |
39 | | -} |
| 6 | +const GRID_SIZE: i32 = 300; |
40 | 7 |
|
41 | | -fn fuel_cell_power(x: i32, y: i32) -> i32 { |
| 8 | +fn get_power(x: i32, y: i32, serial_number: i32) -> i32 { |
42 | 9 | let rack_id = x + 10; |
43 | 10 | let mut power = rack_id * y; |
44 | | - power += SERIAL_NUMBER; |
| 11 | + power += serial_number; |
45 | 12 | power *= rack_id; |
46 | | - power = (power / 100) % 10; |
47 | | - power -= 5; |
48 | | - power |
| 13 | + (power / 100) % 10 - 5 |
49 | 14 | } |
50 | 15 |
|
51 | | -fn part1(grid: &Grid) -> Result<(i32, i32)> { |
52 | | - let (mut max_x, mut max_y, mut max_power) = (1, 1, grid.square_power(3, 1, 1)); |
53 | | - for x in 1..=GRID_SIZE { |
54 | | - for y in 1..=GRID_SIZE { |
55 | | - let power = grid.square_power(3, x, y); |
56 | | - if power > max_power { |
57 | | - max_x = x; |
58 | | - max_y = y; |
59 | | - max_power = power; |
60 | | - } |
| 16 | +fn build_summed_area_table(serial_number: i32) -> Vec<Vec<i32>> { |
| 17 | + let mut sat = vec![vec![0; (GRID_SIZE + 1) as usize]; (GRID_SIZE + 1) as usize]; |
| 18 | + for y in 1..=GRID_SIZE { |
| 19 | + for x in 1..=GRID_SIZE { |
| 20 | + let power = get_power(x, y, serial_number); |
| 21 | + sat[y as usize][x as usize] = power + sat[y as usize - 1][x as usize] + sat[y as usize][x as usize - 1] - sat[y as usize - 1][x as usize - 1]; |
61 | 22 | } |
62 | 23 | } |
| 24 | + sat |
| 25 | +} |
63 | 26 |
|
64 | | - Ok((max_x, max_y)) |
| 27 | +fn get_square_power(sat: &[Vec<i32>], x: i32, y: i32, size: i32) -> i32 { |
| 28 | + let (x1, y1, x2, y2) = (x - 1, y - 1, x + size - 1, y + size - 1); |
| 29 | + sat[y2 as usize][x2 as usize] - sat[y1 as usize][x2 as usize] - sat[y2 as usize][x1 as usize] + sat[y1 as usize][x1 as usize] |
65 | 30 | } |
66 | 31 |
|
67 | | -fn part2(grid: &Grid) -> Result<(i32, i32, i32)> { |
68 | | - let (mut max_size, mut max_x, mut max_y, mut max_power) = (1, 1, 1, grid.square_power(1, 1, 1)); |
| 32 | +impl Solution for Day11 { |
| 33 | + fn year(&self) -> u32 { 2018 } |
| 34 | + fn day(&self) -> u32 { 11 } |
69 | 35 |
|
70 | | - for size in 1..=GRID_SIZE { |
71 | | - for x in 1..=GRID_SIZE { |
72 | | - for y in 1..=GRID_SIZE { |
73 | | - println!("size: {}, x: {}, y: {}", size, x, y); |
74 | | - let power = grid.square_power(size, x, y); |
| 36 | + fn part1(&self, input: &str) -> Box<dyn Display> { |
| 37 | + let serial_number: i32 = input.trim().parse().unwrap(); |
| 38 | + let sat = build_summed_area_table(serial_number); |
| 39 | + let mut max_power = i32::MIN; |
| 40 | + let mut max_coord = (0, 0); |
| 41 | + for y in 1..=GRID_SIZE - 2 { |
| 42 | + for x in 1..=GRID_SIZE - 2 { |
| 43 | + let power = get_square_power(&sat, x, y, 3); |
75 | 44 | if power > max_power { |
76 | | - max_size = size; |
77 | | - max_x = x; |
78 | | - max_y = y; |
79 | 45 | max_power = power; |
80 | | - } |
81 | | - if y + size > GRID_SIZE { |
82 | | - break; |
| 46 | + max_coord = (x, y); |
83 | 47 | } |
84 | 48 | } |
85 | | - if x + size > GRID_SIZE { |
86 | | - break; |
87 | | - } |
88 | 49 | } |
| 50 | + Box::new(format!("{},{}", max_coord.0, max_coord.1)) |
89 | 51 | } |
90 | | - Ok((max_x, max_y, max_size)) |
91 | | -} |
92 | | - |
93 | | -#[cfg(test)] |
94 | | -mod tests { |
95 | | - use super::*; |
96 | 52 |
|
97 | | - #[test] |
98 | | - #[ignore] |
99 | | - fn test_first() { |
100 | | - let mut grid = Grid::new(GRID_SIZE); |
101 | | - for x in 1..=GRID_SIZE { |
102 | | - for y in 1..=GRID_SIZE { |
103 | | - grid.set(x, y, fuel_cell_power(x, y)); |
| 53 | + fn part2(&self, input: &str) -> Box<dyn Display> { |
| 54 | + let serial_number: i32 = input.trim().parse().unwrap(); |
| 55 | + let sat = build_summed_area_table(serial_number); |
| 56 | + let mut max_power = i32::MIN; |
| 57 | + let mut max_details = (0, 0, 0); |
| 58 | + for size in 1..=GRID_SIZE { |
| 59 | + for y in 1..=GRID_SIZE - size + 1 { |
| 60 | + for x in 1..=GRID_SIZE - size + 1 { |
| 61 | + let power = get_square_power(&sat, x, y, size); |
| 62 | + if power > max_power { |
| 63 | + max_power = power; |
| 64 | + max_details = (x, y, size); |
| 65 | + } |
| 66 | + } |
104 | 67 | } |
105 | 68 | } |
106 | | - |
107 | | - let (x, y) = part1(&grid).unwrap(); |
108 | | - println!("most powerful 3x3 square: {},{}", x, y); |
109 | | - let (x, y, size) = part2(&grid).unwrap(); |
110 | | - println!("most powerful 3x3 square with size: {},{},{}", x, y, size); |
| 69 | + Box::new(format!("{},{},{}", max_details.0, max_details.1, max_details.2)) |
111 | 70 | } |
112 | 71 | } |
0 commit comments