Skip to content

Commit fdf793f

Browse files
committed
2018 day 3
1 parent 9715fe3 commit fdf793f

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

crates/year2018/src/day03.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use utils::prelude::*;
2+
3+
/// Identifying the region that isn't overlapped.
4+
#[derive(Clone, Debug)]
5+
pub struct Day03 {
6+
part1: u32,
7+
part2: u32,
8+
}
9+
10+
#[derive(Debug)]
11+
struct Claim {
12+
id: u32,
13+
y: usize,
14+
height: usize,
15+
idx: usize,
16+
mask0: u32,
17+
mask1: u32,
18+
}
19+
20+
impl Day03 {
21+
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
22+
let coordinate = parser::number_range(0usize..=991);
23+
let dimension = parser::number_range(1usize..=31);
24+
25+
let claims: Vec<Claim> = parser::u32()
26+
.with_prefix(b'#')
27+
.with_suffix(" @ ")
28+
.then(coordinate.with_suffix(b','))
29+
.then(coordinate.with_suffix(": "))
30+
.then(dimension.with_suffix(b'x'))
31+
.then(dimension)
32+
.map_res(|(id, x, y, width, height)| {
33+
if x + width > 1000 || y + height > 1000 {
34+
Err("claim out of bounds")
35+
} else {
36+
let mask = ((1u64 << width) - 1) << (x % 32);
37+
38+
Ok(Claim {
39+
id,
40+
y,
41+
height,
42+
idx: (x / 32),
43+
mask0: mask as u32,
44+
mask1: (mask >> 32) as u32,
45+
})
46+
}
47+
})
48+
.parse_lines(input)?;
49+
50+
let mut grid = [[0u32; 32]; 1000];
51+
let mut overlaps = [[0u32; 32]; 1000];
52+
for claim in &claims {
53+
// This is enforced by the max accepted coordinate. 991 div 32 = 30
54+
assert!(claim.idx + 1 < 32);
55+
56+
for y in claim.y..claim.y + claim.height {
57+
overlaps[y][claim.idx] |= grid[y][claim.idx] & claim.mask0;
58+
grid[y][claim.idx] |= claim.mask0;
59+
60+
overlaps[y][claim.idx + 1] |= grid[y][claim.idx + 1] & claim.mask1;
61+
grid[y][claim.idx + 1] |= claim.mask1;
62+
}
63+
}
64+
65+
Ok(Self {
66+
part1: overlaps.as_flattened().iter().map(|x| x.count_ones()).sum(),
67+
part2: claims
68+
.iter()
69+
.find(|claim| {
70+
overlaps[claim.y..claim.y + claim.height].iter().all(|o| {
71+
o[claim.idx] & claim.mask0 == 0 && o[claim.idx + 1] & claim.mask1 == 0
72+
})
73+
})
74+
.ok_or_else(|| InputError::new(input, 0, "all claims overlap"))?
75+
.id,
76+
})
77+
}
78+
79+
#[must_use]
80+
pub fn part1(&self) -> u32 {
81+
self.part1
82+
}
83+
84+
#[must_use]
85+
pub fn part2(&self) -> u32 {
86+
self.part2
87+
}
88+
}
89+
90+
examples!(Day03 -> (u32, u32) [
91+
{input: "#1 @ 1,3: 4x4\n#2 @ 3,1: 4x4\n#3 @ 5,5: 2x2", part1: 4},
92+
]);

crates/year2018/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
utils::year!(2018 => year2018, ${
55
1 => day01::Day01,
66
2 => day02::Day02,
7+
3 => day03::Day03,
78
});

0 commit comments

Comments
 (0)