Skip to content

Commit 465e2a3

Browse files
committed
2018 day 11
1 parent 9145f98 commit 465e2a3

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

crates/year2018/src/day11.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use utils::prelude::*;
2+
3+
/// Locating the optimal square subregion.
4+
///
5+
/// See <https://en.wikipedia.org/wiki/Summed-area_table>, which allows computing the sum of any
6+
/// square in constant time with only 4 lookups.
7+
#[derive(Clone, Debug)]
8+
pub struct Day11 {
9+
summed_area_table: Vec<i32>,
10+
}
11+
12+
impl Day11 {
13+
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
14+
let serial_num = parser::number_range(0..=9999).parse_complete(input)?;
15+
16+
let mut table = vec![0i32; 301 * 301];
17+
for y in 1..301 {
18+
for x in 1..301 {
19+
let rack_id = x + 10;
20+
let power_level = ((rack_id * y + serial_num) * rack_id) / 100 % 10 - 5;
21+
let index = (y * 301 + x) as usize;
22+
table[index] =
23+
power_level + table[index - 1] + table[index - 301] - table[index - 302];
24+
}
25+
}
26+
27+
Ok(Self {
28+
summed_area_table: table,
29+
})
30+
}
31+
32+
#[must_use]
33+
pub fn part1(&self) -> String {
34+
let (_, x, y) = self.largest_total_power(3);
35+
format!("{x},{y}")
36+
}
37+
38+
#[must_use]
39+
pub fn part2(&self) -> String {
40+
let (size, (_, x, y)) = (1..=300)
41+
.map(|s| (s, self.largest_total_power(s)))
42+
.max_by_key(|&(_, (total, _, _))| total)
43+
.unwrap();
44+
format!("{x},{y},{size}")
45+
}
46+
47+
fn largest_total_power(&self, size: usize) -> (i32, u32, u32) {
48+
let (mut max_total, mut max_x, mut max_y) = (i32::MIN, 0, 0);
49+
for y in 0..301 - size {
50+
for x in 0..301 - size {
51+
let index = y * 301 + x;
52+
let total = self.summed_area_table[index]
53+
+ self.summed_area_table[index + 302 * size]
54+
- self.summed_area_table[index + size]
55+
- self.summed_area_table[index + 301 * size];
56+
if total > max_total {
57+
max_total = total;
58+
max_x = x as u32 + 1;
59+
max_y = y as u32 + 1;
60+
}
61+
}
62+
}
63+
(max_total, max_x, max_y)
64+
}
65+
}
66+
67+
examples!(Day11 -> (&'static str, &'static str) [
68+
{input: "18", part1: "33,45", part2: "90,269,16"},
69+
{input: "42", part1: "21,61", part2: "232,251,12"},
70+
]);

crates/year2018/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ utils::year!(2018 => year2018, ${
1212
8 => day08::Day08,
1313
9 => day09::Day09,
1414
10 => day10::Day10,
15+
11 => day11::Day11,
1516
});

0 commit comments

Comments
 (0)