generated from luke-else/AdventOfCodeXXXX
feat: Completed day 9 part 1.. Part 2 just takes way too long to run
All checks were successful
Continuous integration / Check (push) Successful in 40s
Continuous integration / Test Suite (push) Successful in 41s
Continuous integration / Rustfmt (push) Successful in 28s
Continuous integration / Clippy (push) Successful in 42s
Continuous integration / build (push) Successful in 40s
All checks were successful
Continuous integration / Check (push) Successful in 40s
Continuous integration / Test Suite (push) Successful in 41s
Continuous integration / Rustfmt (push) Successful in 28s
Continuous integration / Clippy (push) Successful in 42s
Continuous integration / build (push) Successful in 40s
This commit is contained in:
496
input/day09
496
input/day09
@@ -0,0 +1,496 @@
|
||||
97924,50345
|
||||
97924,51571
|
||||
98267,51571
|
||||
98267,52762
|
||||
97672,52762
|
||||
97672,54006
|
||||
98033,54006
|
||||
98033,55223
|
||||
97930,55223
|
||||
97930,56355
|
||||
97187,56355
|
||||
97187,57620
|
||||
97455,57620
|
||||
97455,58755
|
||||
96898,58755
|
||||
96898,60029
|
||||
97081,60029
|
||||
97081,61275
|
||||
97045,61275
|
||||
97045,62296
|
||||
96120,62296
|
||||
96120,63411
|
||||
95626,63411
|
||||
95626,64658
|
||||
95567,64658
|
||||
95567,65962
|
||||
95623,65962
|
||||
95623,66827
|
||||
94448,66827
|
||||
94448,68020
|
||||
94185,68020
|
||||
94185,69214
|
||||
93900,69214
|
||||
93900,70281
|
||||
93316,70281
|
||||
93316,71397
|
||||
92837,71397
|
||||
92837,72352
|
||||
92049,72352
|
||||
92049,73659
|
||||
91911,73659
|
||||
91911,74892
|
||||
91598,74892
|
||||
91598,75591
|
||||
90405,75591
|
||||
90405,76766
|
||||
89983,76766
|
||||
89983,77931
|
||||
89520,77931
|
||||
89520,78545
|
||||
88292,78545
|
||||
88292,79538
|
||||
87598,79538
|
||||
87598,80413
|
||||
86755,80413
|
||||
86755,81391
|
||||
86038,81391
|
||||
86038,82481
|
||||
85435,82481
|
||||
85435,83432
|
||||
84666,83432
|
||||
84666,84001
|
||||
83514,84001
|
||||
83514,85275
|
||||
83050,85275
|
||||
83050,86053
|
||||
82104,86053
|
||||
82104,86679
|
||||
81032,86679
|
||||
81032,87054
|
||||
79771,87054
|
||||
79771,88208
|
||||
79137,88208
|
||||
79137,89041
|
||||
78237,89041
|
||||
78237,89353
|
||||
76971,89353
|
||||
76971,90543
|
||||
76303,90543
|
||||
76303,91193
|
||||
75265,91193
|
||||
75265,91236
|
||||
73875,91236
|
||||
73875,92568
|
||||
73227,92568
|
||||
73227,92557
|
||||
71841,92557
|
||||
71841,93088
|
||||
70751,93088
|
||||
70751,93718
|
||||
69706,93718
|
||||
69706,94302
|
||||
68634,94302
|
||||
68634,95167
|
||||
67665,95167
|
||||
67665,95074
|
||||
66325,95074
|
||||
66325,95758
|
||||
65273,95758
|
||||
65273,95986
|
||||
64064,95986
|
||||
64064,96370
|
||||
62907,96370
|
||||
62907,96471
|
||||
61675,96471
|
||||
61675,96573
|
||||
60454,96573
|
||||
60454,97441
|
||||
59393,97441
|
||||
59393,97281
|
||||
58122,97281
|
||||
58122,97594
|
||||
56940,97594
|
||||
56940,97532
|
||||
55705,97532
|
||||
55705,97315
|
||||
54467,97315
|
||||
54467,97784
|
||||
53292,97784
|
||||
53292,97610
|
||||
52070,97610
|
||||
52070,97786
|
||||
50866,97786
|
||||
50866,98242
|
||||
49652,98242
|
||||
49652,98030
|
||||
48436,98030
|
||||
48436,98037
|
||||
47216,98037
|
||||
47216,97990
|
||||
45997,97990
|
||||
45997,97488
|
||||
44824,97488
|
||||
44824,97993
|
||||
43535,97993
|
||||
43535,97477
|
||||
42375,97477
|
||||
42375,97150
|
||||
41197,97150
|
||||
41197,97360
|
||||
39910,97360
|
||||
39910,96634
|
||||
38823,96634
|
||||
38823,96666
|
||||
37557,96666
|
||||
37557,96488
|
||||
36334,96488
|
||||
36334,95918
|
||||
35228,95918
|
||||
35228,95121
|
||||
34212,95121
|
||||
34212,94577
|
||||
33123,94577
|
||||
33123,94857
|
||||
31705,94857
|
||||
31705,93771
|
||||
30841,93771
|
||||
30841,93738
|
||||
29520,93738
|
||||
29520,92937
|
||||
28552,92937
|
||||
28552,92599
|
||||
27355,92599
|
||||
27355,92067
|
||||
26252,92067
|
||||
26252,91311
|
||||
25278,91311
|
||||
25278,90840
|
||||
24133,90840
|
||||
24133,90199
|
||||
23088,90199
|
||||
23088,88851
|
||||
22540,88851
|
||||
22540,88832
|
||||
21051,88832
|
||||
21051,87608
|
||||
20452,87608
|
||||
20452,87102
|
||||
19299,87102
|
||||
19299,86330
|
||||
18353,86330
|
||||
18353,85553
|
||||
17409,85553
|
||||
17409,84855
|
||||
16386,84855
|
||||
16386,83659
|
||||
15852,83659
|
||||
15852,83143
|
||||
14625,83143
|
||||
14625,81803
|
||||
14283,81803
|
||||
14283,81266
|
||||
13043,81266
|
||||
13043,80286
|
||||
12304,80286
|
||||
12304,79007
|
||||
11961,79007
|
||||
11961,78307
|
||||
10862,78307
|
||||
10862,77157
|
||||
10375,77157
|
||||
10375,76323
|
||||
9424,76323
|
||||
9424,75099
|
||||
9076,75099
|
||||
9076,73909
|
||||
8704,73909
|
||||
8704,73119
|
||||
7629,73119
|
||||
7629,71799
|
||||
7523,71799
|
||||
7523,70975
|
||||
6447,70975
|
||||
6447,69897
|
||||
5858,69897
|
||||
5858,68675
|
||||
5600,68675
|
||||
5600,67341
|
||||
5660,67341
|
||||
5660,66365
|
||||
4812,66365
|
||||
4812,65200
|
||||
4459,65200
|
||||
4459,64020
|
||||
4157,64020
|
||||
4157,62919
|
||||
3584,62919
|
||||
3584,61586
|
||||
3884,61586
|
||||
3884,60595
|
||||
2797,60595
|
||||
2797,59348
|
||||
2787,59348
|
||||
2787,58082
|
||||
2955,58082
|
||||
2955,56942
|
||||
2390,56942
|
||||
2390,55696
|
||||
2543,55696
|
||||
2543,54506
|
||||
2266,54506
|
||||
2266,53302
|
||||
2065,53302
|
||||
2065,52073
|
||||
2310,52073
|
||||
2310,50861
|
||||
2471,50861
|
||||
2471,50321
|
||||
94552,50321
|
||||
94552,48440
|
||||
2091,48440
|
||||
2091,47247
|
||||
2499,47247
|
||||
2499,45975
|
||||
1750,45975
|
||||
1750,44746
|
||||
1790,44746
|
||||
1790,43644
|
||||
2817,43644
|
||||
2817,42335
|
||||
2272,42335
|
||||
2272,41178
|
||||
2747,41178
|
||||
2747,39918
|
||||
2675,39918
|
||||
2675,38910
|
||||
3727,38910
|
||||
3727,37719
|
||||
3942,37719
|
||||
3942,36385
|
||||
3684,36385
|
||||
3684,35253
|
||||
4159,35253
|
||||
4159,34244
|
||||
4967,34244
|
||||
4967,32829
|
||||
4645,32829
|
||||
4645,31939
|
||||
5715,31939
|
||||
5715,30641
|
||||
5772,30641
|
||||
5772,29771
|
||||
6797,29771
|
||||
6797,28353
|
||||
6662,28353
|
||||
6662,27683
|
||||
8016,27683
|
||||
8016,26189
|
||||
7820,26189
|
||||
7820,25275
|
||||
8682,25275
|
||||
8682,24304
|
||||
9430,24304
|
||||
9430,23426
|
||||
10305,23426
|
||||
10305,22541
|
||||
11149,22541
|
||||
11149,21158
|
||||
11311,21158
|
||||
11311,20566
|
||||
12536,20566
|
||||
12536,19309
|
||||
12910,19309
|
||||
12910,18275
|
||||
13579,18275
|
||||
13579,17372
|
||||
14405,17372
|
||||
14405,16451
|
||||
15212,16451
|
||||
15212,16154
|
||||
16639,16154
|
||||
16639,14608
|
||||
16840,14608
|
||||
16840,14147
|
||||
18075,14147
|
||||
18075,13608
|
||||
19212,13608
|
||||
19212,12928
|
||||
20214,12928
|
||||
20214,11846
|
||||
20904,11846
|
||||
20904,11174
|
||||
21918,11174
|
||||
21918,10743
|
||||
23094,10743
|
||||
23094,9637
|
||||
23814,9637
|
||||
23814,8950
|
||||
24822,8950
|
||||
24822,8144
|
||||
25765,8144
|
||||
25765,7608
|
||||
26869,7608
|
||||
26869,6967
|
||||
27915,6967
|
||||
27915,6471
|
||||
29036,6471
|
||||
29036,5965
|
||||
30150,5965
|
||||
30150,5315
|
||||
31204,5315
|
||||
31204,5542
|
||||
32611,5542
|
||||
32611,5091
|
||||
33734,5091
|
||||
33734,4100
|
||||
34679,4100
|
||||
34679,4289
|
||||
36019,4289
|
||||
36019,3710
|
||||
37115,3710
|
||||
37115,3331
|
||||
38274,3331
|
||||
38274,2798
|
||||
39404,2798
|
||||
39404,2844
|
||||
40663,2844
|
||||
40663,2936
|
||||
41914,2936
|
||||
41914,2855
|
||||
43125,2855
|
||||
43125,2289
|
||||
44272,2289
|
||||
44272,2471
|
||||
45512,2471
|
||||
45512,2554
|
||||
46730,2554
|
||||
46730,2366
|
||||
47928,2366
|
||||
47928,1748
|
||||
49125,1748
|
||||
49125,2381
|
||||
50343,2381
|
||||
50343,1681
|
||||
51573,1681
|
||||
51573,2173
|
||||
52771,2173
|
||||
52771,1917
|
||||
54010,1917
|
||||
54010,2346
|
||||
55193,2346
|
||||
55193,1968
|
||||
56469,1968
|
||||
56469,2224
|
||||
57671,2224
|
||||
57671,2462
|
||||
58874,2462
|
||||
58874,2875
|
||||
60039,2875
|
||||
60039,3188
|
||||
61219,3188
|
||||
61219,3530
|
||||
62390,3530
|
||||
62390,3672
|
||||
63618,3672
|
||||
63618,3901
|
||||
64829,3901
|
||||
64829,4864
|
||||
65792,4864
|
||||
65792,5525
|
||||
66837,5525
|
||||
66837,5472
|
||||
68159,5472
|
||||
68159,6112
|
||||
69209,6112
|
||||
69209,6929
|
||||
70166,6929
|
||||
70166,7451
|
||||
71252,7451
|
||||
71252,7552
|
||||
72564,7552
|
||||
72564,8010
|
||||
73703,8010
|
||||
73703,8995
|
||||
74537,8995
|
||||
74537,9644
|
||||
75559,9644
|
||||
75559,10487
|
||||
76451,10487
|
||||
76451,10811
|
||||
77697,10811
|
||||
77697,11508
|
||||
78693,11508
|
||||
78693,12208
|
||||
79691,12208
|
||||
79691,13360
|
||||
80317,13360
|
||||
80317,14116
|
||||
81256,14116
|
||||
81256,14472
|
||||
82566,14472
|
||||
82566,15209
|
||||
83551,15209
|
||||
83551,16126
|
||||
84365,16126
|
||||
84365,17393
|
||||
84800,17393
|
||||
84800,18024
|
||||
85908,18024
|
||||
85908,19134
|
||||
86483,19134
|
||||
86483,19631
|
||||
87796,19631
|
||||
87796,21067
|
||||
87939,21067
|
||||
87939,21616
|
||||
89242,21616
|
||||
89242,22794
|
||||
89694,22794
|
||||
89694,23663
|
||||
90594,23663
|
||||
90594,24868
|
||||
90974,24868
|
||||
90974,26021
|
||||
91413,26021
|
||||
91413,26925
|
||||
92287,26925
|
||||
92287,28097
|
||||
92676,28097
|
||||
92676,29149
|
||||
93292,29149
|
||||
93292,30350
|
||||
93590,30350
|
||||
93590,31557
|
||||
93844,31557
|
||||
93844,32548
|
||||
94619,32548
|
||||
94619,33610
|
||||
95252,33610
|
||||
95252,34795
|
||||
95551,34795
|
||||
95551,36023
|
||||
95698,36023
|
||||
95698,37160
|
||||
96125,37160
|
||||
96125,38352
|
||||
96359,38352
|
||||
96359,39381
|
||||
97306,39381
|
||||
97306,40749
|
||||
96718,40749
|
||||
96718,41836
|
||||
97519,41836
|
||||
97519,43042
|
||||
97708,43042
|
||||
97708,44278
|
||||
97660,44278
|
||||
97660,45480
|
||||
97870,45480
|
||||
97870,46724
|
||||
97536,46724
|
||||
97536,47910
|
||||
98058,47910
|
||||
98058,49129
|
||||
98032,49129
|
||||
98032,50345
|
||||
@@ -0,0 +1,8 @@
|
||||
7,1
|
||||
11,1
|
||||
11,7
|
||||
9,7
|
||||
9,5
|
||||
2,5
|
||||
2,3
|
||||
7,3
|
||||
@@ -0,0 +1,8 @@
|
||||
7,1
|
||||
11,1
|
||||
11,7
|
||||
9,7
|
||||
9,5
|
||||
2,5
|
||||
2,3
|
||||
7,3
|
||||
15
src/main.rs
15
src/main.rs
@@ -20,23 +20,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
Box::new(day06::Day06 {}),
|
||||
Box::new(day07::Day07 {}),
|
||||
Box::new(day08::Day08 {}),
|
||||
// Box::new(day09::Day09 {}),
|
||||
Box::new(day09::Day09 {}),
|
||||
// Box::new(day10::Day10 {}),
|
||||
// Box::new(day11::Day11 {}),
|
||||
// Box::new(day12::Day12 {}),
|
||||
// Box::new(day13::Day13 {}),
|
||||
// Box::new(day14::Day14 {}),
|
||||
// Box::new(day15::Day15 {}),
|
||||
// Box::new(day16::Day16 {}),
|
||||
// Box::new(day17::Day17 {}),
|
||||
// Box::new(day18::Day18 {}),
|
||||
// Box::new(day19::Day19 {}),
|
||||
// Box::new(day20::Day20 {}),
|
||||
// Box::new(day21::Day21 {}),
|
||||
// Box::new(day22::Day22 {}),
|
||||
// Box::new(day23::Day23 {}),
|
||||
// Box::new(day24::Day24 {}),
|
||||
// Box::new(day25::Day25 {}),
|
||||
];
|
||||
|
||||
// Vector to store every solution as a thread handle
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
use super::Solution;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct Day09 {}
|
||||
|
||||
impl Solution for Day09 {
|
||||
fn part1(
|
||||
&self,
|
||||
_input: &mut Vec<String>,
|
||||
input: &mut Vec<String>,
|
||||
) -> Result<Box<dyn std::fmt::Display>, Box<dyn std::error::Error>> {
|
||||
Ok(Box::new("Ready"))
|
||||
let points = self.parse_points(input)?;
|
||||
Ok(Box::new(self.max_rectangle_area(&points)))
|
||||
}
|
||||
|
||||
fn part2(
|
||||
&self,
|
||||
_input: &mut Vec<String>,
|
||||
input: &mut Vec<String>,
|
||||
) -> Result<Box<dyn std::fmt::Display>, Box<dyn std::error::Error>> {
|
||||
Ok(Box::new("Ready"))
|
||||
let red = self.parse_points(input)?;
|
||||
Ok(Box::new(self.largest_red_green_rectangle(&red)))
|
||||
}
|
||||
|
||||
fn get_day(&self) -> u8 {
|
||||
@@ -22,7 +26,281 @@ impl Solution for Day09 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Day09 {}
|
||||
impl Day09 {
|
||||
fn parse_points(&self, reader: &[String]) -> Result<Vec<Point>, Box<dyn std::error::Error>> {
|
||||
let mut pts = Vec::new();
|
||||
|
||||
for line in reader.iter() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let mut parts = trimmed.split(',');
|
||||
let x_str = parts.next().ok_or("Missing x")?.trim();
|
||||
let y_str = parts.next().ok_or("Missing y")?.trim();
|
||||
|
||||
let x = x_str.parse::<i32>()?;
|
||||
let y = y_str.parse::<i32>()?;
|
||||
pts.push(Point { x, y });
|
||||
}
|
||||
|
||||
Ok(pts)
|
||||
}
|
||||
|
||||
fn max_rectangle_area(&self, points: &[Point]) -> i64 {
|
||||
let n = points.len();
|
||||
let mut best = 0i64;
|
||||
|
||||
for i in 0..n {
|
||||
for j in (i + 1)..n {
|
||||
let a = points[i];
|
||||
let b = points[j];
|
||||
let area = self.rectangle_area(a, b);
|
||||
if area > best {
|
||||
best = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best
|
||||
}
|
||||
|
||||
fn build_edges(&self, red: &[Point]) -> Vec<Point> {
|
||||
let mut v = Vec::new();
|
||||
let n = red.len();
|
||||
for i in 0..n {
|
||||
let a = red[i];
|
||||
let b = red[(i + 1) % n];
|
||||
if a.x == b.x {
|
||||
let x = a.x;
|
||||
let y1 = a.y.min(b.y);
|
||||
let y2 = a.y.max(b.y);
|
||||
for y in y1..=y2 {
|
||||
v.push(Point { x, y });
|
||||
}
|
||||
} else if a.y == b.y {
|
||||
let y = a.y;
|
||||
let x1 = a.x.min(b.x);
|
||||
let x2 = a.x.max(b.x);
|
||||
for x in x1..=x2 {
|
||||
v.push(Point { x, y });
|
||||
}
|
||||
} else {
|
||||
panic!("Adjacent red points must be aligned.");
|
||||
}
|
||||
}
|
||||
v
|
||||
}
|
||||
|
||||
fn flood_fill_interior(
|
||||
&self,
|
||||
edges: &[Point],
|
||||
min_x: i32,
|
||||
min_y: i32,
|
||||
width: usize,
|
||||
height: usize,
|
||||
) -> BitGrid {
|
||||
let mut grid = BitGrid::new(min_x, min_y, width, height);
|
||||
for &p in edges {
|
||||
grid.set(p.x, p.y);
|
||||
}
|
||||
|
||||
// Flood-fill from outside
|
||||
let mut visited = BitGrid::new(min_x, min_y, width, height);
|
||||
|
||||
let mut q = VecDeque::new();
|
||||
let start = Point { x: min_x, y: min_y };
|
||||
q.push_back(start);
|
||||
visited.set(start.x, start.y);
|
||||
|
||||
let dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)];
|
||||
|
||||
while let Some(p) = q.pop_front() {
|
||||
for (dx, dy) in dirs {
|
||||
let np = Point {
|
||||
x: p.x + dx,
|
||||
y: p.y + dy,
|
||||
};
|
||||
if np.x < min_x
|
||||
|| np.x >= min_x + width as i32
|
||||
|| np.y < min_y
|
||||
|| np.y >= min_y + height as i32
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if grid.get(np.x, np.y) {
|
||||
// edge blocks movement
|
||||
continue;
|
||||
}
|
||||
if !visited.get(np.x, np.y) {
|
||||
visited.set(np.x, np.y);
|
||||
q.push_back(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build final valid = edges + interior
|
||||
let mut valid = BitGrid::new(min_x, min_y, width, height);
|
||||
for y in 0..height {
|
||||
for block in 0..valid.blocks_per_row {
|
||||
let outside = visited.rows[y][block];
|
||||
let edge = grid.rows[y][block];
|
||||
let interior = (!outside) & (!edge);
|
||||
valid.rows[y][block] = edge | interior;
|
||||
}
|
||||
}
|
||||
|
||||
valid
|
||||
}
|
||||
|
||||
fn rectangle_ok(&self, a: Point, b: Point, grid: &BitGrid) -> bool {
|
||||
let x1 = a.x.min(b.x);
|
||||
let x2 = a.x.max(b.x);
|
||||
let y1 = a.y.min(b.y);
|
||||
let y2 = a.y.max(b.y);
|
||||
|
||||
let start = (x1 - grid.min_x) as usize;
|
||||
let end = (x2 - grid.min_x) as usize;
|
||||
|
||||
let block_start = start / 64;
|
||||
let block_end = end / 64;
|
||||
|
||||
for y in y1..=y2 {
|
||||
let row_index = (y - grid.min_y) as usize;
|
||||
let row = &grid.rows[row_index];
|
||||
|
||||
for (blk, _) in row.iter().enumerate().take(block_end + 1).skip(block_start) {
|
||||
let left_bit = if blk == block_start { start % 64 } else { 0 };
|
||||
let right_bit = if blk == block_end { end % 64 } else { 63 };
|
||||
let mask = if left_bit == 0 && right_bit == 63 {
|
||||
!0u64
|
||||
} else {
|
||||
((1u64 << (right_bit + 1)) - 1) & !((1u64 << left_bit) - 1)
|
||||
};
|
||||
|
||||
let bits = row[blk];
|
||||
if (bits & mask) != mask {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn largest_red_green_rectangle(&self, red: &[Point]) -> i64 {
|
||||
// Determine bounding box (expand by 2 for flood-fill safety)
|
||||
let min_x = red.iter().map(|p| p.x).min().unwrap() - 2;
|
||||
let max_x = red.iter().map(|p| p.x).max().unwrap() + 2;
|
||||
let min_y = red.iter().map(|p| p.y).min().unwrap() - 2;
|
||||
let max_y = red.iter().map(|p| p.y).max().unwrap() + 2;
|
||||
|
||||
let width = (max_x - min_x + 1) as usize;
|
||||
let height = (max_y - min_y + 1) as usize;
|
||||
|
||||
let edges = self.build_edges(red);
|
||||
let valid = self.flood_fill_interior(&edges, min_x, min_y, width, height);
|
||||
|
||||
// Ensure red tiles are "valid"
|
||||
let mut valid = valid;
|
||||
for &p in red {
|
||||
valid.set(p.x, p.y);
|
||||
}
|
||||
|
||||
// Compute max rectangle
|
||||
let mut best = 0;
|
||||
for i in 0..red.len() {
|
||||
for j in (i + 1)..red.len() {
|
||||
let a = red[i];
|
||||
let b = red[j];
|
||||
if self.rectangle_ok(a, b, &valid) {
|
||||
let area = self.rectangle_area(a, b);
|
||||
if area > best {
|
||||
best = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best
|
||||
}
|
||||
|
||||
fn rectangle_area(&self, a: Point, b: Point) -> i64 {
|
||||
let width = ((a.x - b.x).abs() + 1) as i64;
|
||||
let height = ((a.y - b.y).abs() + 1) as i64;
|
||||
width * height
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct BitGrid {
|
||||
min_x: i32,
|
||||
min_y: i32,
|
||||
width: usize,
|
||||
height: usize,
|
||||
blocks_per_row: usize,
|
||||
rows: Vec<Vec<u64>>,
|
||||
}
|
||||
|
||||
impl BitGrid {
|
||||
fn new(min_x: i32, min_y: i32, width: usize, height: usize) -> Self {
|
||||
let blocks_per_row = width.div_ceil(64);
|
||||
let mut rows = Vec::with_capacity(height);
|
||||
for _ in 0..height {
|
||||
rows.push(vec![0u64; blocks_per_row]);
|
||||
}
|
||||
Self {
|
||||
min_x,
|
||||
min_y,
|
||||
width,
|
||||
height,
|
||||
blocks_per_row,
|
||||
rows,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn coord_to_block_bit(&self, x: i32, y: i32) -> Option<(usize, u64)> {
|
||||
let dx = x - self.min_x;
|
||||
let dy = y - self.min_y;
|
||||
if dx < 0 || dy < 0 {
|
||||
return None;
|
||||
}
|
||||
let ux = dx as usize;
|
||||
let uy = dy as usize;
|
||||
if ux >= self.width || uy >= self.height {
|
||||
return None;
|
||||
}
|
||||
let block = ux / 64;
|
||||
let bit = 1u64 << (ux % 64);
|
||||
Some((uy * self.blocks_per_row + block, bit))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set(&mut self, x: i32, y: i32) {
|
||||
if let Some((flat_index, bit)) = self.coord_to_block_bit(x, y) {
|
||||
let row = flat_index / self.blocks_per_row;
|
||||
let col = flat_index % self.blocks_per_row;
|
||||
self.rows[row][col] |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get(&self, x: i32, y: i32) -> bool {
|
||||
if let Some((flat_index, bit)) = self.coord_to_block_bit(x, y) {
|
||||
let row = flat_index / self.blocks_per_row;
|
||||
let col = flat_index % self.blocks_per_row;
|
||||
(self.rows[row][col] & bit) != 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Test from puzzle input
|
||||
#[cfg(test)]
|
||||
@@ -44,7 +322,7 @@ mod test {
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
assert_eq!(answer, "Ready");
|
||||
assert_eq!(answer, "50");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -61,6 +339,6 @@ mod test {
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
assert_eq!(answer, "Ready");
|
||||
assert_eq!(answer, "24");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user