-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcipher.py
More file actions
88 lines (70 loc) · 2.57 KB
/
cipher.py
File metadata and controls
88 lines (70 loc) · 2.57 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
#!/usr/bin/env python3
# ICPC South Central USA 2014 #6793
punct_ords = [(33, 48), (58, 65), (91, 97), (123, 127)]
punctuation = ''
for tup in punct_ords:
for i in range(tup[0], tup[1]):
punctuation += chr(i)
def find_rotation(ciphertext, threat_list, nonthreat_list):
max_score = {'rot': 0,
'score': 0,
'info': None}
for shift in range(26):
decipher_text = decipher(ciphertext, shift)
results = match_words(decipher_text, threat_list, nonthreat_list)
score = results['threats'] + results['nonthreats']
if score > max_score['score']:
max_score['rot'] = shift
max_score['score'] = score
max_score['info'] = results
return max_score
def match_words(text, threat_list, nonthreat_list):
threats = 0
nonthreats = 0
words = 0
for punct in punctuation:
while punct in text:
text = text.replace(punct, ' ')
text = text.lower().replace(' ', ' ')
for word in text.split(' '):
if word.isalpha():
words += 1
if word in threat_list:
threats += 1
elif word in nonthreat_list:
nonthreats += 1
return {'threats': threats,
'nonthreats': nonthreats,
'words': words}
def decipher(ciphertext, shift):
deciphered_str = ''
for char in ciphertext:
if char.isalpha():
offset = 65 if char.isupper() else 97
deciphered_str += chr((ord(char) - offset - shift) % 26 + offset)
else:
deciphered_str += char
return deciphered_str
def handle_testcase():
nonthreat_amt = int(input())
nonthreat_list = []
for _ in range(nonthreat_amt):
nonthreat_list.append(input())
threat_amt = int(input())
threat_list = []
for _ in range(threat_amt):
threat_list.append(input())
ciphertext = input()
result = find_rotation(ciphertext, threat_list, nonthreat_list)
if result['score'] == 0:
print('Unable to decipher')
else:
match_percent = round(result['score'] / result['info']['words'] * 100)
threat_percent = round(result['info']['threats'] / result['info']['words'] * 100)
print(decipher(ciphertext, result['rot']))
print('Shift: {}, Match: {}%, Threat: {}%'.format(result['rot'],
match_percent,
threat_percent))
test_cases = int(input())
for _ in range(test_cases):
handle_testcase()