aboutsummaryrefslogtreecommitdiff
path: root/2024/src
diff options
context:
space:
mode:
Diffstat (limited to '2024/src')
-rw-r--r--2024/src/day12.cpp93
1 files changed, 69 insertions, 24 deletions
diff --git a/2024/src/day12.cpp b/2024/src/day12.cpp
index 6a23730..018797f 100644
--- a/2024/src/day12.cpp
+++ b/2024/src/day12.cpp
@@ -8,7 +8,9 @@
8#include <vector> 8#include <vector>
9using namespace std; 9using namespace std;
10 10
11using pos_type = tuple<size_t, size_t>; 11using pos_type = tuple<size_t, size_t>;
12using area_type = set<pos_type>;
13using areas_type = vector<area_type>;
12 14
13map<pos_type, char> 15map<pos_type, char>
14read_file(string_view filename) 16read_file(string_view filename)
@@ -33,69 +35,112 @@ neighbors(pos_type pos)
33 return { { x - 1, y }, { x, y - 1 }, { x + 1, y }, { x, y + 1 } }; 35 return { { x - 1, y }, { x, y - 1 }, { x + 1, y }, { x, y + 1 } };
34} 36}
35 37
36void 38areas_type
37part1(const map<pos_type, char>& data) 39areas(map<pos_type, char> data)
38{ 40{
39 auto data_copy = data; 41 auto find_area = [&](pos_type start) {
40
41 auto flood_fill = [&](pos_type start) {
42 set<pos_type> area; 42 set<pos_type> area;
43 queue<pos_type> queue; 43 queue<pos_type> queue;
44 queue.push(start); 44 queue.push(start);
45 45
46 const auto digit = data.at(start);
47
46 while ( !queue.empty() ) { 48 while ( !queue.empty() ) {
47 auto pos = queue.front(); 49 auto pos = queue.front();
48 queue.pop(); 50 queue.pop();
49 51
50 if ( !data_copy.contains(pos) ) { 52 if ( !data.contains(pos) ) {
51 continue; 53 continue;
52 } 54 }
53 55
54 auto digit = data_copy.at(pos);
55
56 for ( const auto& neighbor: neighbors(pos) ) { 56 for ( const auto& neighbor: neighbors(pos) ) {
57 if ( !data_copy.contains(neighbor) ) { 57 if ( !data.contains(neighbor) ) {
58 continue; 58 continue;
59 } 59 }
60 if ( data_copy.at(neighbor) != digit ) { 60 if ( data.at(neighbor) != digit ) {
61 continue; 61 continue;
62 } 62 }
63 queue.push(neighbor); 63 queue.push(neighbor);
64 } 64 }
65 65
66 area.insert(pos); 66 area.insert(pos);
67 data_copy.erase(pos); 67 data.erase(pos);
68 } 68 }
69 return area; 69 return area;
70 }; 70 };
71 71
72 auto count_edges = [](const set<pos_type>& area) -> size_t { 72 areas_type areas;
73 size_t sum = 0; 73 while ( !data.empty() ) {
74 auto area = find_area(data.begin()->first);
75 areas.push_back(area);
76 }
77 return areas;
78}
74 79
75 for ( const auto& pos: area ) { 80size_t
76 for ( const auto& neighbor: neighbors(pos) ) { 81count_edges(const set<pos_type>& area)
77 if ( !area.contains(neighbor) ) { 82{
78 ++sum; 83 size_t sum = 0;
79 } 84 for ( const auto& pos: area ) {
85 for ( const auto& neighbor: neighbors(pos) ) {
86 if ( !area.contains(neighbor) ) {
87 ++sum;
80 } 88 }
81 } 89 }
90 }
91 return sum;
92}
82 93
83 return sum; 94size_t
84 }; 95count_common_sides(const set<pos_type>& area)
96{
97 size_t count = 0;
98 for ( const auto& [x, y]: area ) {
99 if ( area.contains({ x - 1, y }) ) {
100 for ( const auto y2: { y - 1, y + 1 } ) {
101 if ( !area.contains({ x, y2 }) && !area.contains({ x - 1, y2 }) ) {
102 ++count;
103 }
104 }
105 }
106 if ( area.contains({ x, y - 1 }) ) {
107 for ( const auto x2: { x - 1, x + 1 } ) {
108 if ( !area.contains({ x2, y }) && !area.contains({ x2, y - 1 }) ) {
109 ++count;
110 }
111 }
112 }
113 }
114 return count;
115}
85 116
117void
118part1(const map<pos_type, char>& data)
119{
86 size_t sum = 0; 120 size_t sum = 0;
87 while ( !data_copy.empty() ) { 121 for ( const auto& area: areas(data) ) {
88 auto area = flood_fill(data_copy.begin()->first);
89 auto edges = count_edges(area); 122 auto edges = count_edges(area);
90
91 sum += area.size() * edges; 123 sum += area.size() * edges;
92 } 124 }
93 cout << sum << endl; 125 cout << sum << endl;
94} 126}
95 127
128void
129part2(const map<pos_type, char>& data)
130{
131 size_t sum = 0;
132 for ( const auto& area: areas(data) ) {
133 auto edges = count_edges(area);
134 auto common_sides = count_common_sides(area);
135 sum += area.size() * (edges - common_sides);
136 }
137 cout << sum << endl;
138}
139
96int 140int
97main() 141main()
98{ 142{
99 auto data = read_file("data/day12.txt"); 143 auto data = read_file("data/day12.txt");
100 part1(data); 144 part1(data);
145 part2(data);
101} 146}