Module 18: Preventing Duplicates

This commit is contained in:
David Doblas Jiménez 2021-09-09 15:47:12 +02:00
parent 8f3a5fa69a
commit e7a24670b0

49
a.c
View File

@ -2,6 +2,7 @@
#include <string> // support for strings
#include <vector> // support for vectors
#include <unordered_map> // support for hash-tables
#include <unordered_set>
#include <assert.h>
#include <fstream> // support for reading files
using namespace std;
@ -19,6 +20,20 @@ string ToUpper(string s) {
return s2;
}
// --------------------------------------------------------------------------------
typedef unordered_set<string> StringSet; // A set will avoid duplicates
// Returns 'true' if string 's' exists in set already.
bool ExistsInSet(const StringSet& set, const string& s) {
auto it = set.find(s);
return it != set.end();
}
void AddToSet(StringSet& set, const string& s) {
assert(!ExistsInSet(set, s));
set.insert(s);
}
// --------------------------------------------------------------------------------
//-Point
struct Point {
@ -97,7 +112,6 @@ public:
} else {
return true;
}
//return word_map_.count(s) > 0; // True if word exists
}
void ComputeStats() {
assert(counts_.empty());
@ -122,16 +136,13 @@ public:
void CreatePatternHash(Word* w) {
int len = w->len();
int num_patterns = 1 << len; // create 2^len patterns
// cout << "PATTERN HASH on " << w->word << "\n";
for (int i=0; i<num_patterns; i++) {
// cout << " " << i << "\n";
string temp = w->word;
for (int j=0; j<len; j++) {
if ((i >> j) & 1) { // get every bit and check if it's 1
temp[j] = '-';
}
}
// cout << " " << temp << "\n";
word_map_[temp].push_back(w);
}
}
@ -296,7 +307,6 @@ struct Grid {
}
if (!in_bounds(p)) return;
Point startp = p;
// cout << "SPAN START: " << p << "\n";
int len = 0;
bool keep_going = false;
@ -304,7 +314,6 @@ struct Grid {
keep_going = NextStopAtWrap(p, vert);
len++;
} while (keep_going && !is_block(p));
//cout << "END OF SPAN!!! len=" << len << "\n";
spans.push_back(Span(startp, len, vert));
}
}
@ -320,7 +329,6 @@ struct Grid {
while (f.is_open() && !f.eof()) { // check for the file
string line;
getline(f, line);
// cout << line << "\n";
if (!line.empty() && line[0] != '#') {
lines.push_back(line);
}
@ -382,10 +390,6 @@ class Solver {
private:
void Loop(Grid grid, int depth) { // full copy of the grid to allow recursion
depth++;
// if (depth > 3) {
// cout << "Aborting loop because depth=" << depth << "\n";
// return;
// }
Slots empty_slots; // these are the ones we want to work on
Slots partial_slots;
Slots full_slots;
@ -403,18 +407,23 @@ class Solver {
int num_empty = empty_slots.size();
int num_partial = partial_slots.size();
int num_full = full_slots.size();
// cout << "empty = " << num_empty << "\n";
// cout << "partial = " << num_partial << "\n";
// cout << "full = " << num_full << "\n";
// need to check that all words so far are valid!
for (const Slot& s : full_slots) {
// cout << "CHECKING " << s.pattern << " if it is a word\n";
if (!lib.IsWord(s.pattern)) {
// cout << " --> NOT! ABORT\n";
return;
}
}
// need to check that all words are unique! no duplicates allowed.
StringSet set;
for (const Slot& s : full_slots) {
if (ExistsInSet(set, s.pattern)) {
return;
}
AddToSet(set, s.pattern);
}
if (num_partial == 0 && num_empty == 0) {
cout << "SOLUTION!!\n";
grid.Print();
@ -424,20 +433,12 @@ class Solver {
CommitSlot(grid, partial_slots[0], depth);
}
void CommitSlot(Grid& grid, const Slot& slot, int depth) {
// cout << "COMMIT slot " << slot << "\n";
// cout << "Possible word choices for this slot are:\n";
const Words* words = lib.FindWord(slot.pattern);
if (words) {
for (const Word* w : *words) {
// cout << " Committing '" << w->word << "'!\n";
grid.WriteString(slot.span, w->word);
// cout << "New grid is:\n";
// grid.Print();
Loop(grid, depth); // Recursion
}
} else {
// cout << "NO MATCHES to pattern\n";
}
}
};