aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/day12.cpp73
1 files changed, 65 insertions, 8 deletions
diff --git a/src/day12.cpp b/src/day12.cpp
index b01b2fb..11bd80b 100644
--- a/src/day12.cpp
+++ b/src/day12.cpp
@@ -1,5 +1,6 @@
1#include <fstream> 1#include <fstream>
2#include <iostream> 2#include <iostream>
3#include <map>
3#include <sstream> 4#include <sstream>
4#include <string> 5#include <string>
5#include <vector> 6#include <vector>
@@ -69,9 +70,9 @@ count_groups(string_view str)
69} 70}
70 71
71long 72long
72brute_force(string_view puzzle, const vector<long>& nums) 73brute_force(string_view springs, const vector<long>& groups)
73{ 74{
74 long counts = count_if(puzzle.begin(), puzzle.end(), [](char chr) { return chr == '?'; }); 75 long counts = count_if(springs.begin(), springs.end(), [](char chr) { return chr == '?'; });
75 76
76 string test_pattern; 77 string test_pattern;
77 78
@@ -79,7 +80,7 @@ brute_force(string_view puzzle, const vector<long>& nums)
79 for ( size_t counter = 0; counter != (1U << size_t(counts)); ++counter ) { 80 for ( size_t counter = 0; counter != (1U << size_t(counts)); ++counter ) {
80 auto bit_pattern = counter; 81 auto bit_pattern = counter;
81 82
82 for ( char chr: puzzle ) { 83 for ( char chr: springs ) {
83 if ( chr == '?' ) { 84 if ( chr == '?' ) {
84 if ( (bit_pattern & 1U) != 0U ) { 85 if ( (bit_pattern & 1U) != 0U ) {
85 test_pattern += '.'; 86 test_pattern += '.';
@@ -93,7 +94,7 @@ brute_force(string_view puzzle, const vector<long>& nums)
93 test_pattern += chr; 94 test_pattern += chr;
94 } 95 }
95 } 96 }
96 if ( nums == count_groups(test_pattern) ) { 97 if ( groups == count_groups(test_pattern) ) {
97 arrangements++; 98 arrangements++;
98 } 99 }
99 100
@@ -103,16 +104,71 @@ brute_force(string_view puzzle, const vector<long>& nums)
103 return arrangements; 104 return arrangements;
104} 105}
105 106
107long
108count(const string& springs, const vector<long>& groups)
109{
110 map<tuple<string, vector<long>>, long> cache;
111
112 function<long(string, const vector<long>&)> count_rec = [&](string springs, const vector<long>& groups) -> long {
113 auto cached_value = cache.find(make_tuple(springs, groups));
114 if ( cached_value != cache.end() ) {
115 return cached_value->second;
116 }
117
118 springs.erase(0, springs.find_first_not_of('.'));
119
120 if ( springs.empty() ) {
121 return groups.empty() ? 1 : 0;
122 }
123
124 if ( groups.empty() ) {
125 return springs.find('#') == string_view::npos ? 1 : 0;
126 }
127
128 if ( springs[0] == '#' ) {
129 auto gidx = size_t(groups[0]);
130 if ( springs.length() < gidx || springs.substr(0, gidx).find('.') != string_view::npos || springs[gidx] == '#' ) {
131 return 0;
132 }
133
134 return count_rec(springs.substr(gidx + 1), { groups.begin() + 1, groups.end() });
135 }
136
137 auto value = count_rec(string("#") + springs.substr(1), groups) + count_rec(springs.substr(1), groups);
138
139 cache[make_tuple(springs, groups)] = value;
140
141 return value;
142 };
143
144 return count_rec(springs + ".", groups);
145}
146
106void 147void
107part1(const vector<string>& input) 148part1(const vector<string>& input)
108{ 149{
109 auto sum = 0L; 150 auto sum = 0L;
110 for ( const auto& line: input ) { 151 for ( const auto& line: input ) {
111 auto parts = split(line, ' '); 152 auto parts = split(line, ' ');
112 auto puzzle = parts[0]; 153 auto springs = parts[0];
113 auto nums = read_ints(parts[1]); 154 auto groups = read_ints(parts[1]);
155
156 sum += brute_force(springs, groups);
157 // sum += count(springs, groups);
158 }
159 cout << sum << endl;
160}
161
162void
163part2(const vector<string>& input)
164{
165 auto sum = 0L;
166 for ( const auto& line: input ) {
167 auto parts = split(line, ' ');
168 auto springs = parts[0] + "?" + parts[0] + "?" + parts[0] + "?" + parts[0] + "?" + parts[0];
169 auto groups = read_ints(parts[1] + "," + parts[1] + "," + parts[1] + "," + parts[1] + "," + parts[1]);
114 170
115 sum += brute_force(puzzle, nums); 171 sum += count(springs, groups);
116 } 172 }
117 cout << sum << endl; 173 cout << sum << endl;
118} 174}
@@ -122,4 +178,5 @@ main()
122{ 178{
123 const auto input = read_file("data/day12.txt"); 179 const auto input = read_file("data/day12.txt");
124 part1(input); 180 part1(input);
181 part2(input);
125} 182}