def _reduce_path(path): if not len(path): return '' segments = [] cur_dir = None last = None segment = [] for cur in path: if last is not None: new_dir = a2num(cur) - a2num(last) if abs(new_dir) > 1: # jump sign = 1 if new_dir > 0 else -1 segments.append((segment + [last], cur_dir or 0)) segments.append(([ rotate_alphabet(last, sign), rotate_alphabet(cur, -sign) ], 'Jump')) segment = [] new_dir = None elif cur_dir is None or new_dir == cur_dir: # continue segment.append(last) elif new_dir == 0: # sloped to flat segments.append((segment, cur_dir)) segment = [last] elif cur_dir == 0: # go from flat to sloped segments.append((segment + [last], cur_dir)) segment = [] else: # V or ^ shape segments.append((segment, cur_dir)) segments.append(([last], 0)) segment = [] cur_dir = new_dir last = cur assert last is not None segments.append((segment + [last], cur_dir or 0)) result = [] # print('segments', segments) for i, (segment, dir) in enumerate(segments): assert dir in [-1, 1, 0, 'Jump'], dir if dir == 0: if i > 0 and i < len(segments) - 1 and segments[ i - 1][1] == segments[i + 1][1] and segments[ i - 1][1] != 'Jump': # 1,0,1 or -1,0,-1 pattern segment = segment[1:] if dir in [-1, 1]: if (i == 0 or segments[i - 1][1] != 'Jump') and ( i == len(segments) - 1 or segments[i + 1][1] != 'Jump'): # chain breaks if i == 0: result.append(segment[0]) if i == len(segments) - 1: result.append(segment[-1]) segment = [] result.extend(segment) # print('segment', segment, 'new result', result) # print('final result', result) return ''.join(result)
def checksum(x): words = x.split(' ') results = [] for word in words: if len(word) == 0: results.append('') elif len(word) == 1: results.append('-') else: assert len(word) > 1 orig = word[:-1] truesum = sum([a2num(l) + 1 for l in orig if is_alphabet(l)]) % 26 # print(truesum) if (a2num(word[-1]) + 1) % 26 == truesum: results.append(orig) else: results.append('-' * len(orig)) return ' '.join(results)
def corrupt(x, extra_index=0, extra_rotate=0): """ Corruption by adding amount to a single position of each word Amount/position both determined by sum of letters Everything is mod 27 instead of 26 to make things work out better """ if not len(x): return x total = sum([a2num(l, with_spaces=True) for l in x]) index = (total - 1 + extra_index) % len(x) new = rotate_alphabet(x[index], total + extra_rotate, with_spaces=True) return x[:index] + new + x[index + 1:]
def corrupt_final(x): """ Corruption by adding amount to a single position of each word Amount/position both determined by sum of letters Everything is mod 27 instead of 26 to make things work out better """ n = len(x) if not n: return x total = sum([a2num(l, with_spaces=True) for l in x]) index = (total + (n // 3)) % len(x) new = rotate_alphabet(x[index], total + (n // 8), with_spaces=True) return x[:index] + new + x[index + 1:]
def tournament(x): vals = [0 for _ in range(len(x))] def parent(i): if i == 0: return None else: pow2 = 1 while i % (pow2 * 2) == 0: pow2 *= 2 return i - pow2 for i, l in enumerate(x): j = parent(i) while j is not None: vals[j] += a2num(l, with_spaces=True) j = parent(j) return ''.join(rotate_alphabet(l, vals[i], with_spaces=True) for i, l in enumerate(x))
def fn(x): # print('x', x) s = ' ' offset = 0 i = 0 for char in x: if char == ' ': offset = len(s) s = s + s i = 0 else: ind = offset + (i % (len(s) - offset)) new_l = rotate_alphabet(s[ind], a2num(char, with_spaces=True), with_spaces=True).lower() # i = a2num(char, with_spaces=False) # print(x, i, len(s)) s = s[:ind] + new_l + s[ind + 1:] i += 1 # print(s) return s
def codebook(x): if ' ' not in x: return '' book, code = x.split(' ', 1) return ''.join( [book[a2num(l) % len(book)] if is_alphabet(l) else l for l in code])
new = rotate_alphabet(x[index], total + (n // 8), with_spaces=True) return x[:index] + new + x[index + 1:] if 0: startword = 'darn' wantdiff = 22 startword = 'damn' wantdiff = 5 indexdiff = 3 # search for good sums for offset in range(7): for addlength in range(14): total_length = offset + len(startword) + addlength for total_sum in range(offset + indexdiff, total_length * 22, total_length): remaining_sum = total_sum - sum([a2num(l, with_spaces=True) for l in startword]) if remaining_sum <= 0: continue if not total_sum % 27 == wantdiff: continue # now make sure a corruption exists for corrupt_amt in range(1, 26): corrupted_sum = total_sum + corrupt_amt for index in range(total_length): if (corrupted_sum - 1) % total_length != index: continue # print('corrupted sum', corrupted_sum % 27, (corrupt_amt) % 26) if corrupted_sum % 27 != (-corrupt_amt) % 27: continue print('works', offset, addlength, 'remain sum', remaining_sum, 'corrupt', corrupt_amt, 'index')
if 0: startword = 'darn' wantdiff = 22 startword = 'damn' wantdiff = 5 indexdiff = 3 # search for good sums for offset in range(7): for addlength in range(14): total_length = offset + len(startword) + addlength for total_sum in range(offset + indexdiff, total_length * 22, total_length): remaining_sum = total_sum - sum( [a2num(l, with_spaces=True) for l in startword]) if remaining_sum <= 0: continue if not total_sum % 27 == wantdiff: continue # now make sure a corruption exists for corrupt_amt in range(1, 26): corrupted_sum = total_sum + corrupt_amt for index in range(total_length): if (corrupted_sum - 1) % total_length != index: continue # print('corrupted sum', corrupted_sum % 27, (corrupt_amt) % 26) if corrupted_sum % 27 != (-corrupt_amt) % 27: continue print('works', offset, addlength, 'remain sum', remaining_sum, 'corrupt', corrupt_amt, 'index')