forked from wandering007/ProjectEuler
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP98_Anagramic_squares.cpp
More file actions
152 lines (142 loc) · 4.38 KB
/
Copy pathP98_Anagramic_squares.cpp
File metadata and controls
152 lines (142 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include<iostream>
#include<fstream>
#include<string>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<set>
#include<list>
#include<algorithm>
#include<math.h>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iomanip>
#define MAXN 1000000
#define MOD 10000000000
#define LL long long
#define eps 1e-8
#define inf 0x3f3f3f3f
using namespace std;
int main(int argc, char** args)
{
clock_t start = clock();
//load words from file into vector words
fstream input("p098_words.txt");
string word;
//create a map from a sorted string to its anagrams
map< string, vector<string> > anagrams;
map< string, vector<string> >::iterator it;
while(input.good())
{
getline(input, word, '"'); //unused, '"' and ','
getline(input, word, '"'); //word
string sortedWord = word;
sort(sortedWord.begin(), sortedWord.end());
it= anagrams.find(sortedWord);
//check if key exists already
if( it != anagrams.end() )
{
//if so add this word to existing vector
(it->second).push_back(word);
}
else
{
//if not create new vector with this word
vector<string> wordlist;
wordlist.push_back(word);
anagrams[sortedWord] = wordlist;
}
}
//remove non-anagrams from map
it = anagrams.begin();
while(it != anagrams.end())
{
if( (it->second).size() == 1)
anagrams.erase(it);
it++;
}
//find our biggest square
int maxsquare = 0;
//iterate through the anagram vectors in our map (by key)
for(it = anagrams.begin(); it != anagrams.end(); it++)
{
vector<string> anagramlist = it->second;
//find range of squares we need to check
double num = pow(10.0, (it->first).size() - 1);
int lowerbound = ceil(sqrt(num));
int upperbound = floor(sqrt(num * 10 - 1));
//pick the first word to map the square onto
for(unsigned int j = 0; j < anagramlist.size() - 1; j++)
{
string word = anagramlist[j];
//iterate through the range of squares
for(int mysqr = upperbound; mysqr >= lowerbound; mysqr--)
{
//sqrnum is our square to test
int sqrnum = mysqr * mysqr;
//get vector of digits in square
vector<int> digits(word.size(), 0);
int digitindex = word.size() - 1;
int copysqrnum = sqrnum;
while(copysqrnum)
{
digits[digitindex]= copysqrnum % 10;
copysqrnum /= 10;
digitindex--;
}
//define mapping from word to the digits in the square
bool validmapping = true;
vector<int> chartonum(26, -1);
bool vis[10] = {};
for(unsigned int k = 0; k < word.size(); k++)
{
int letterindex = (int)(word[k] - 'A');
if(chartonum[letterindex] == -1)
{
chartonum[letterindex] = digits[k];
if(vis[digits[k]])
{
//check if two letters have the same number (if so mapping is invalid)
validmapping = false;
break;
}
vis[digits[k]] = true;
}
else if(digits[k] != chartonum[letterindex])
{
//same letter but different number, invalid mapping
validmapping = false;
break;
}
}
if(!validmapping)
//bad mapping, try the next square number
continue;
//now try mapping on all words to the right of this word
for(unsigned int k = j + 1; k < anagramlist.size(); k++)
{
string otherword = anagramlist[k];
if(chartonum[otherword[0] - 'A'] == 0)
//leading zero is not allowed
continue;
//calculate what number the other word translates to
int othersum = 0;
for(unsigned int m = 0; m < otherword.size(); m++)
othersum = 10 * othersum + chartonum[otherword[m] - 'A'];
//if the number is a perfect square we found a valid combo
int sqrtothersum = sqrt(othersum + 1);
//found a valid pair
if(sqrtothersum * sqrtothersum == othersum)
maxsquare = max(maxsquare, max(sqrnum, othersum));
}
}
}
}
cout << "Max square: " << maxsquare << endl;
cout << "Elapsed time: " << (double)(clock() - start) / CLOCKS_PER_SEC << " seconds." << endl;
return 0;
}