1
- #include < algorithm>
2
- #include < fstream>
3
- #include < iostream>
4
- #include < ranges>
5
- #include < string>
6
- #include < unordered_map>
7
- #include < unordered_set>
8
- #include < vector>
9
-
10
- struct Point {
11
- Point (const int row = 0 , const int col = 0 ) : row(row), col(col) {}
12
- int row;
13
- int col;
14
- bool operator == (const Point & p) const {
15
- return p.row == row && p.col == col;
16
- }
17
- bool operator < (const Point & p) const {
18
- return p.row < row || (p.row == row && p.col < col);
19
- }
20
- };
21
-
22
- struct Hasher {
23
- std::size_t operator () (const Point & p) const {
24
- return p.row ;
25
- }
26
- };
27
-
28
- const std::vector<Point > moves {
29
- Point (1 ,0 ),
30
- Point (0 ,-1 ),
31
- Point (-1 ,0 ),
32
- Point (0 ,1 ),
33
- };
34
-
35
- const bool in_map (const Point & p, const std::vector<std::string>& map) {
36
- return !(p.col >= map[0 ].size () || p.col < 0 || p.row >= map.size () || p.row < 0 );
37
- }
38
-
39
- bool explore (Point current,
40
- int idx,
41
- std::vector<std::string>& map,
42
- std::unordered_map<Point , std::array<bool , 4 >, Hasher> visited_edges,
43
- std::unordered_set<Point , Hasher>& obs,
44
- const bool obstacle_placed) {
45
- while (in_map (current, map)) {
46
- if (!visited_edges.contains (current)) {
47
- visited_edges[current] = {{false , false , false , false }};
48
- }
49
- if (visited_edges[current][idx] && obstacle_placed) {
50
- return true ;
51
- }
52
- const auto next = Point (current.row + moves[idx].row , current.col + moves[idx].col );
53
- if (!in_map (next, map)) return false ;
54
- if (map[next.row ][next.col ] == ' #' ) {
55
- idx += 1 ;
56
- idx %= 4 ;
57
- } else {
58
- if (!obstacle_placed && !visited_edges.contains (next)) {
59
- const auto c = map[next.row ][next.col ];
60
- map[next.row ][next.col ] = ' #' ;
61
- if (explore (current, (idx+1 )%4 , map, visited_edges, obs, true )) {
62
- obs.insert (next);
63
- }
64
- map[next.row ][next.col ] = c;
65
- }
66
- visited_edges[current][idx] = true ;
67
- current = next;
68
- }
69
- }
70
- return false ;
71
- }
72
-
73
- int main (int argc, char * argv[]) {
74
- std::string input = " ../input/day_06_input" ;
75
- if (argc > 1 ) {
76
- input = argv[1 ];
77
- }
78
-
79
- std::ifstream file (input);
80
- std::string line;
81
- std::vector<std::string> map;
82
- Point start;
83
- while (std::getline (file, line)) {
84
- map.push_back (line);
85
- for (const auto [idx, c] : std::views::enumerate (line)) {
86
- if (c == ' ^' ) {
87
- start.row = map.size ()-1 ;
88
- start.col = idx;
89
- }
90
- }
91
- }
92
- std::unordered_map<Point , std::array<bool , 4 >, Hasher> visited_edges;
93
- std::unordered_set<Point , Hasher> obs;
94
- explore (start, 2 , map, visited_edges, obs, false );
95
- std::cout << obs.size () << ' \n ' ;
96
- return 0 ;
1
+ #include < algorithm>
2
+ #include < fstream>
3
+ #include < iostream>
4
+ #include < ranges>
5
+ #include < string>
6
+ #include < unordered_map>
7
+ #include < unordered_set>
8
+ #include < vector>
9
+
10
+ struct Point {
11
+ Point (const int row = 0 , const int col = 0 ) : row(row), col(col) {}
12
+ int row;
13
+ int col;
14
+ bool operator == (const Point & p) const {
15
+ return p.row == row && p.col == col;
16
+ }
17
+ bool operator < (const Point & p) const {
18
+ return p.row < row || (p.row == row && p.col < col);
19
+ }
20
+ };
21
+
22
+ struct Hasher {
23
+ std::size_t operator () (const Point & p) const {
24
+ return p.row ;
25
+ }
26
+ };
27
+
28
+ const std::vector<Point > moves {
29
+ Point (1 ,0 ),
30
+ Point (0 ,-1 ),
31
+ Point (-1 ,0 ),
32
+ Point (0 ,1 ),
33
+ };
34
+
35
+ const bool in_map (const Point & p, const std::vector<std::string>& map) {
36
+ return !(p.col >= map[0 ].size () || p.col < 0 || p.row >= map.size () || p.row < 0 );
37
+ }
38
+
39
+ bool explore (Point current,
40
+ int idx,
41
+ std::vector<std::string>& map,
42
+ std::unordered_map<Point , std::array<bool , 4 >, Hasher> visited_edges,
43
+ std::unordered_set<Point , Hasher>& obs,
44
+ const bool obstacle_placed) {
45
+ while (in_map (current, map)) {
46
+ if (!visited_edges.contains (current)) {
47
+ visited_edges[current] = {{false , false , false , false }};
48
+ }
49
+ if (visited_edges[current][idx] && obstacle_placed) {
50
+ return true ;
51
+ }
52
+ const auto next = Point (current.row + moves[idx].row , current.col + moves[idx].col );
53
+ if (!in_map (next, map)) return false ;
54
+ if (map[next.row ][next.col ] == ' #' ) {
55
+ idx += 1 ;
56
+ idx %= 4 ;
57
+ } else {
58
+ if (!obstacle_placed && !visited_edges.contains (next)) {
59
+ const auto c = map[next.row ][next.col ];
60
+ map[next.row ][next.col ] = ' #' ;
61
+ if (explore (current, (idx+1 )%4 , map, visited_edges, obs, true )) {
62
+ obs.insert (next);
63
+ }
64
+ map[next.row ][next.col ] = c;
65
+ }
66
+ visited_edges[current][idx] = true ;
67
+ current = next;
68
+ }
69
+ }
70
+ return false ;
71
+ }
72
+
73
+ int main (int argc, char * argv[]) {
74
+ std::string input = " ../input/day_06_input" ;
75
+ if (argc > 1 ) {
76
+ input = argv[1 ];
77
+ }
78
+
79
+ std::ifstream file (input);
80
+ std::string line;
81
+ std::vector<std::string> map;
82
+ Point start;
83
+ while (std::getline (file, line)) {
84
+ map.push_back (line);
85
+ for (const auto [idx, c] : std::views::enumerate (line)) {
86
+ if (c == ' ^' ) {
87
+ start.row = map.size ()-1 ;
88
+ start.col = idx;
89
+ }
90
+ }
91
+ }
92
+ std::unordered_map<Point , std::array<bool , 4 >, Hasher> visited_edges;
93
+ std::unordered_set<Point , Hasher> obs;
94
+ explore (start, 2 , map, visited_edges, obs, false );
95
+ std::cout << obs.size () << ' \n ' ;
96
+ return 0 ;
97
97
}
0 commit comments