Skip to content

Commit c4df1ed

Browse files
committed
6th day (optimization)
1 parent db3a3c8 commit c4df1ed

File tree

1 file changed

+49
-79
lines changed

1 file changed

+49
-79
lines changed

src/bin/06.rs

+49-79
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,43 @@
11
advent_of_code::solution!(6);
22

3-
use advent_of_code::maneatingape::hash::*;
3+
use advent_of_code::maneatingape::grid::*;
44
use advent_of_code::maneatingape::point::*;
55

6-
type Direction = Point;
6+
struct Block {}
77

8-
struct MapSize {
9-
min_x: i32,
10-
max_x: i32,
11-
min_y: i32,
12-
max_y: i32,
8+
impl Block {
9+
const WALL: u8 = b'#';
10+
const GUARD: u8 = b'^';
1311
}
1412

15-
struct DataType {
16-
position: Point,
17-
direction: Direction,
18-
obstructions: FastSet<Point>,
19-
map_size: MapSize,
20-
}
13+
fn parse_data(input: &str) -> (Grid<u8>, Point) {
14+
let grid = Grid::parse(input);
15+
let start_position = grid.find(Block::GUARD).unwrap();
2116

22-
impl MapSize {
23-
fn contains(&self, point: &Point) -> bool {
24-
point.x >= self.min_x
25-
&& point.x <= self.max_x
26-
&& point.y >= self.min_y
27-
&& point.y <= self.max_y
28-
}
17+
(grid, start_position)
2918
}
3019

31-
fn parse_data(input: &str) -> DataType {
32-
let my_direction = UP;
33-
let mut my_position = Point::new(0, 0);
34-
let mut obstructions = FastSet::new();
35-
36-
let height = input.lines().count();
37-
let width = input.lines().next().unwrap().len();
38-
39-
for (y, line) in input.lines().enumerate() {
40-
for (x, v) in line.bytes().enumerate() {
41-
match v {
42-
b'#' => {
43-
obstructions.insert(Point::new(x as i32, y as i32));
44-
}
45-
b'^' => {
46-
my_position = Point::new(x as i32, y as i32);
47-
}
48-
_ => {}
49-
}
50-
}
51-
}
52-
53-
DataType {
54-
position: my_position,
55-
direction: my_direction,
56-
obstructions,
57-
map_size: MapSize {
58-
min_x: 0,
59-
max_x: width as i32 - 1,
60-
min_y: 0,
61-
max_y: height as i32 - 1,
62-
},
63-
}
64-
}
20+
fn visited_positions(grid: &Grid<u8>, start_position: Point) -> Vec<Point> {
21+
let mut result = vec![];
6522

66-
fn visited_positions(data: &DataType) -> FastSet<Point> {
67-
let mut my_position = data.position;
68-
let mut my_direction = data.direction;
23+
let mut my_position = start_position;
24+
let mut my_direction = UP;
6925

70-
let mut visit = FastSet::new();
26+
let mut visit = grid.same_size_with(false);
7127

7228
loop {
73-
visit.insert(my_position);
29+
if !visit[my_position] {
30+
result.push(my_position);
31+
};
32+
33+
visit[my_position] = true;
7434

7535
let next_position = my_position + my_direction;
76-
if !data.map_size.contains(&next_position) {
77-
return visit;
36+
if !grid.contains(next_position) {
37+
return result;
7838
}
7939

80-
if data.obstructions.contains(&next_position) {
40+
if grid[next_position] == Block::WALL {
8141
my_direction = my_direction.clockwise();
8242
} else {
8343
my_position = next_position;
@@ -86,37 +46,45 @@ fn visited_positions(data: &DataType) -> FastSet<Point> {
8646
}
8747

8848
pub fn part_one(input: &str) -> Option<u32> {
89-
let data: DataType = parse_data(input);
49+
let (grid, start_position) = parse_data(input);
9050

91-
let result = visited_positions(&data).len() as u32;
51+
let result = visited_positions(&grid, start_position).len() as u32;
9252

9353
Some(result)
9454
}
9555

9656
pub fn part_two(input: &str) -> Option<u32> {
97-
let data: DataType = parse_data(input);
57+
let (grid, start_position) = parse_data(input);
9858

99-
let result = visited_positions(&data)
59+
let result = visited_positions(&grid, start_position)
10060
.into_iter()
101-
.filter(|new_obstruction| new_obstruction != &data.position)
102-
.filter(|new_obstruction| !data.obstructions.contains(new_obstruction))
103-
.filter(|&new_obstruction| {
104-
let mut visit = FastSet::new();
61+
.filter_map(|new_obstruction| {
62+
let mut visit = grid.same_size_with([false, false, false, false]);
10563

106-
let mut my_position = data.position;
107-
let mut my_direction = data.direction;
64+
let mut my_position = start_position;
65+
let mut my_direction = UP;
10866

10967
loop {
110-
if !visit.insert((my_position, my_direction)) {
111-
break true;
68+
let visit_index = match my_direction {
69+
UP => 0,
70+
RIGHT => 1,
71+
DOWN => 2,
72+
LEFT => 3,
73+
_ => unreachable!(),
74+
};
75+
76+
if visit[my_position][visit_index] {
77+
break Some(true);
11278
}
11379

80+
visit[my_position][visit_index] = true;
81+
11482
let next_position = my_position + my_direction;
115-
if !data.map_size.contains(&next_position) {
116-
break false;
83+
if !grid.contains(next_position) {
84+
break None;
11785
}
11886

119-
if new_obstruction == next_position || data.obstructions.contains(&next_position) {
87+
if new_obstruction == next_position || grid[next_position] == Block::WALL {
12088
my_direction = my_direction.clockwise();
12189
} else {
12290
my_position = next_position;
@@ -134,13 +102,15 @@ mod tests {
134102

135103
#[test]
136104
fn test_part_one() {
137-
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
105+
let input = advent_of_code::template::read_file("examples", DAY);
106+
let result = part_one(&input);
138107
assert_eq!(result, Some(41));
139108
}
140109

141110
#[test]
142111
fn test_part_two() {
143-
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
112+
let input = advent_of_code::template::read_file("examples", DAY);
113+
let result = part_two(&input);
144114
assert_eq!(result, Some(6));
145115
}
146116
}

0 commit comments

Comments
 (0)