-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathP850.cpp
129 lines (113 loc) · 3.02 KB
/
P850.cpp
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
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#include <sstream>
#include <map>
#include <ctype.h>
#define MAX_LINE_LENGTH 100
unsigned int readUInt() {
unsigned int ret = 0;
char w[MAX_LINE_LENGTH];
std::cin.getline(w, MAX_LINE_LENGTH);
for(int i = 0; isprint(w[i]); ++i) {
if(w[i] >= '0' && w[i] <= '9')
ret = ret * 10 + (w[i]-'0');
}
//std::cerr << ret << " words:" << std::endl;
return ret;
}
bool readLine(std::vector<std::string> &lines, bool *lettersRequired) {
char w[MAX_LINE_LENGTH];
std::cin.getline(w, MAX_LINE_LENGTH);
int length = 0;
while(isprint(w[length])) {
if(w[length] >= 'a' && w[length] <= 'z')
lettersRequired[w[length]-'a'] = true; // Mark letter required for decryption.
++length;
}
if(length == 0)
return false;
w[length] = '\0';
std::string ws(w);
lines.push_back(ws);
return true;
}
bool tryDecode(std::string encrypted, int *mapping, bool const * const lettersRequired) {
std::string key = "the quick brown fox jumps over the lazy dog";
if(encrypted.size() != key.size())
return false;
// Reset mapping:
bool lettersMapped[26];
for(int i = 0; i < 26; ++i) {
mapping[i] = -1;
lettersMapped[i] = false;
}
// Perform attempt at decryption:
for(unsigned int i = 0; i < encrypted.size(); ++i) {
char s = encrypted[i];
char k = key[i];
if((s == ' ') != (k == ' '))
return false; // Space mismatch.
if(k == ' ')
continue; // space.
if(lettersMapped[k-'a'] || mapping[s-'a'] != -1) { // must match:
if(mapping[s-'a'] != k-'a') // Includes mapping[s-'a'] == -1
return false; // Other char mapped
}
else {
lettersMapped[k-'a'] = true;
mapping[s-'a'] = k-'a';
}
}
// Ensure the decryption is sufficient:
for(int i = 0; i < 26; ++i) {
if(lettersRequired[i] && !lettersMapped[i])
return false;
}
return true;
}
int main() {
int mapping[26];
bool lettersRequired[26];
unsigned int NUMBER_OF_CASES = readUInt();
// Read dictionary:
for(unsigned int i = 0; i < NUMBER_OF_CASES; ++i) {
if(i != 0)
std::cout << std::endl;
for(int i = 0; i < 26; ++i) {
lettersRequired[i] = false;
}
std::vector<std::string> lines;
readLine(lines, lettersRequired);
while(readLine(lines, lettersRequired))
;
// Try all lines:
bool ok = false;
for(std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it) {
const std::string &s = *it;
if(tryDecode(s, mapping, lettersRequired)) {
ok = true;
break;
}
}
// Output:
if(!ok) {
std::cout << "No solution." << std::endl;
}
else {
// Output decrypted:
for(std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it) {
const std::string &s = *it;
for(unsigned int i = 0; i < s.size(); ++i) {
if(s[i] == ' ')
std::cout << ' ';
else
std::cout << (char)(mapping[s[i]-'a']+'a');
}
std::cout << std::endl;
}
}
}
return 0;
}