aboutsummaryrefslogtreecommitdiff
path: root/src/day12.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/day12.cpp')
-rw-r--r--src/day12.cpp78
1 files changed, 67 insertions, 11 deletions
diff --git a/src/day12.cpp b/src/day12.cpp
index 31a2739..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,18 +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() 148part1(const vector<string>& input)
108{ 149{
109 const auto input = read_file("data/day12.txt"); 150 auto sum = 0L;
151 for ( const auto& line: input ) {
152 auto parts = split(line, ' ');
153 auto springs = parts[0];
154 auto groups = read_ints(parts[1]);
110 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{
111 auto sum = 0L; 165 auto sum = 0L;
112 for ( const auto& line: input ) { 166 for ( const auto& line: input ) {
113 auto parts = split(line, ' '); 167 auto parts = split(line, ' ');
114 auto puzzle = parts[0]; 168 auto springs = parts[0] + "?" + parts[0] + "?" + parts[0] + "?" + parts[0] + "?" + parts[0];
115 auto nums = read_ints(parts[1]); 169 auto groups = read_ints(parts[1] + "," + parts[1] + "," + parts[1] + "," + parts[1] + "," + parts[1]);
116 170
117 sum += brute_force(puzzle, nums); 171 sum += count(springs, groups);
118 } 172 }
119 cout << sum << endl; 173 cout << sum << endl;
120} 174}
@@ -122,5 +176,7 @@ part1()
122int 176int
123main() 177main()
124{ 178{
125 part1(); 179 const auto input = read_file("data/day12.txt");
180 part1(input);
181 part2(input);
126} 182}