205 lines
7.5 KiB
Python
Executable File
205 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import LP
|
|
import sys
|
|
import itertools
|
|
|
|
|
|
def load_sequence_file(fname):
|
|
with open(LP.path.data(fname), 'r') as f:
|
|
return [int(x) for x in f.readlines()]
|
|
|
|
|
|
PRIMES = load_sequence_file('seq_primes_1000')
|
|
PRIMES_3301 = load_sequence_file('seq_primes_3301')
|
|
NOT_PRIMES = load_sequence_file('seq_not_primes')
|
|
FIBONACCI = load_sequence_file('seq_fibonacci')
|
|
LUCAS = load_sequence_file('seq_lucas_numbers')
|
|
MOEBIUS = load_sequence_file('seq_moebius')
|
|
|
|
|
|
def print_all_solved():
|
|
def plain(slvr, inpt):
|
|
pass
|
|
|
|
def invert(slvr, inpt):
|
|
inpt.invert()
|
|
|
|
def solution_welcome(slvr, inpt):
|
|
slvr.KEY_DATA = [23, 10, 1, 10, 9, 10, 16, 26] # DIVINITY
|
|
slvr.INTERRUPT = 'ᚠ'
|
|
slvr.INTERRUPT_POS = [4, 5, 6, 7, 10, 11, 14, 18, 20, 21, 25]
|
|
|
|
def solution_koan_1(slvr, inpt):
|
|
slvr.KEY_DATA = [26] # Y
|
|
inpt.invert()
|
|
|
|
def solution_jpg107_167(slvr, inpt): # FIRFUMFERENFE
|
|
slvr.KEY_DATA = [0, 10, 4, 0, 1, 19, 0, 18, 4, 18, 9, 0, 18]
|
|
slvr.INTERRUPT = 'ᚠ'
|
|
slvr.INTERRUPT_POS = [2, 3]
|
|
|
|
def solution_p56_end(slvr, inpt):
|
|
slvr.FN = lambda i, r: r - (PRIMES[i] - 1)
|
|
slvr.INTERRUPT = 'ᚠ'
|
|
slvr.INTERRUPT_POS = [4]
|
|
|
|
def solve(fname, fn_solution, solver=LP.VigenereSolver):
|
|
slvr = solver()
|
|
inpt = LP.RuneTextFile(LP.path.page(fname))
|
|
fn_solution(slvr, inpt)
|
|
print(f'pages/{fname}.txt')
|
|
print()
|
|
io = LP.IOWriter()
|
|
# io.QUIET = True # or use -v/-q while calling
|
|
io.run(slvr.run(inpt)[0])
|
|
print()
|
|
|
|
solve('0_warning', invert)
|
|
solve('0_welcome', solution_welcome)
|
|
solve('0_wisdom', plain)
|
|
solve('0_koan_1', solution_koan_1)
|
|
solve('0_loss_of_divinity', plain)
|
|
solve('jpg107-167', solution_jpg107_167)
|
|
solve('jpg229', plain)
|
|
solve('p56_an_end', solution_p56_end, solver=LP.SequenceSolver)
|
|
solve('p57_parable', plain)
|
|
|
|
|
|
def play_around():
|
|
vowels = [LP.RUNES.index(x) for x in 'ᚢᚩᛁᛇᛖᛟᚪᚫᛡᛠ']
|
|
for uuu in LP.FILES_UNSOLVED:
|
|
inpt = LP.RuneTextFile(LP.path.page(uuu))
|
|
print(uuu)
|
|
print('word count:', sum(1 for _ in inpt.enum_words()))
|
|
a = [1 if x in vowels else 0 for x in inpt.index_no_white]
|
|
b = [a[i:i + 5] for i in range(0, len(a), 5)]
|
|
c = [int(''.join(str(y) for y in x), 2) for x in b]
|
|
# print('-'.join(str(x) for x in c))
|
|
# print(LP.RuneText(c).text)
|
|
# print(''.join('ABCDEFGHIJKLMNOPQRSTUVWXYZ___...'[x] for x in c))
|
|
|
|
|
|
def try_totient_on_unsolved():
|
|
slvr = LP.SequenceSolver()
|
|
# slvr.INTERRUPT = 'ᛝ'
|
|
# slvr.INTERRUPT_POS = [1]
|
|
# for uuu in ['15-22']:
|
|
for uuu in LP.FILES_UNSOLVED:
|
|
print()
|
|
print(uuu)
|
|
inpt = LP.RuneTextFile(LP.path.page(uuu), limit=25).data_clean
|
|
# alldata = [x for x in inpt if x.index != 29] + [LP.Rune(i=29)] * 1
|
|
|
|
def ec(r, i):
|
|
p1, p2 = LP.utils.elliptic_curve(i, 149, 263, 3299)
|
|
if p1 is None:
|
|
return r.index
|
|
return r.index + p1 % 29
|
|
|
|
for z in range(29):
|
|
# slvr.FN = lambda i, r: r - PRIMES[i] + z
|
|
# slvr.FN = lambda i, r: LP.Rune(i=((r.prime + alldata[i + 1].prime) + z) % 60 // 2)
|
|
# slvr.FN = lambda i, r: LP.Rune(i=(r.prime - PRIMES[FIBONACCI[i]] + z) % 29)
|
|
# slvr.FN = lambda i, r: LP.Rune(i=(r.prime ** i + z) % 29)
|
|
slvr.FN = lambda i, r: LP.Rune(i=(ec(r, i) + z) % 29)
|
|
print(slvr.run(inpt)[0].text)
|
|
|
|
|
|
def find_oeis(irp=0, invert=False, offset=0, allow_fails=1, min_match=2):
|
|
def trim_orig_oeis(minlen=15, trim=40):
|
|
# download and unzip: https://oeis.org/stripped.gz
|
|
with open(LP.path.db('oeis_orig'), 'r') as f_in:
|
|
with open(LP.path.db('oeis'), 'w') as f_out:
|
|
for line in f_in.readlines():
|
|
if line[0] == '#':
|
|
continue
|
|
name, *vals = line.split(',')
|
|
vals = [str(int(x) % 29) for x in vals if x.strip()][:trim]
|
|
if len(vals) < minlen:
|
|
continue
|
|
f_out.write(name + ',' + ','.join(vals) + '\n')
|
|
|
|
# trim_orig_oeis() # create db if not present already
|
|
with open(LP.path.db('oeis'), 'r') as f:
|
|
seqs = []
|
|
for line in f.readlines():
|
|
vals = line.split(',')
|
|
seqs.append((vals[0], list(map(int, vals[1:]))))
|
|
|
|
words = [set()] * 13
|
|
words[1] = set(x for x in LP.RUNES)
|
|
for i in range(2, 13): # since 12 is the longest word
|
|
with open(LP.path.data(f'dictionary_{i}'), 'r') as f:
|
|
words[i] = set(x.strip() for x in f.readlines())
|
|
|
|
for uuu, wlen in {
|
|
'p0-2': [8, 5, 4, 3, 3, 11, 5, 4, 3, 3],
|
|
'p3-7': [2, 11, 3, 4, 7, 7, 7, 4, 6],
|
|
'p8-14': [4, 8, 3, 2, 3, 9, 4, 3, 4, 2, 2],
|
|
'p15-22': [4, 5, 4, 2, 5, 4, 5, 6, 5, 6, 3, 3],
|
|
'p23-26': [2, 6, 3, 4, 8, 3, 3, 7, 5, 5],
|
|
'p27-32': [3, 12, 4, 7, 2, 3, 3, 2, 1, 3, 4],
|
|
'p33-39': [2, 8, 2, 9, 6, 3, 3, 5, 3, 2],
|
|
'p40-53': [3, 5, 5, 4, 3, 5, 4, 2, 12, 3, 3, 2],
|
|
'p54-55': [1, 8, 8, 3, 6, 2, 5, 3, 2, 3, 5, 7],
|
|
# 'p56_an_end': [2, 3, 5, 2, 4, 3, 4, 6, 1, 4, 3, 6, 2],
|
|
}.items():
|
|
splits = [(0, 0, 0)]
|
|
for x in wlen:
|
|
splits.append((splits[-1][1], splits[-1][1] + x))
|
|
splits = splits[1:]
|
|
print()
|
|
print(uuu)
|
|
data = LP.RuneTextFile(LP.path.page(uuu), limit=120).index_no_white
|
|
if invert:
|
|
data = [28 - x for x in data]
|
|
irps = [i for i, x in enumerate(data[:splits[-1][1]]) if x == irp]
|
|
irps.reverse() # insert -1 starting with the last
|
|
|
|
min_len = sum(wlen[:2]) # must match at least n words
|
|
data_len = len(data)
|
|
for oeis, vals in seqs: # 390k
|
|
vals = vals[offset:]
|
|
if len(vals) < min_len:
|
|
continue
|
|
cases = [x for x in irps if x < len(vals)]
|
|
for i in range(len(cases) + 1):
|
|
for comb in itertools.combinations(cases, i): # 2^3
|
|
res = vals[:]
|
|
for z in comb:
|
|
res.insert(z, -1) # insert interrupts
|
|
shortest = min(data_len, len(res))
|
|
|
|
for s in range(29):
|
|
failed = 0
|
|
full = []
|
|
clen = 0
|
|
for a, b in splits:
|
|
if b > shortest:
|
|
break
|
|
nums = [x if y == -1 else (x - y - s) % 29
|
|
for x, y in zip(data[a:b], res[a:b])]
|
|
word = ''.join(LP.RUNES[x] for x in nums)
|
|
if word in words[len(nums)]:
|
|
clen += len(nums)
|
|
else:
|
|
failed += 1
|
|
if failed > allow_fails:
|
|
break
|
|
full.append(LP.RuneText(nums).text)
|
|
|
|
if failed > allow_fails or clen < min_match:
|
|
continue # too many failed
|
|
print(oeis.split()[0], 'shift:', s, 'irps:', comb)
|
|
print(' ', ' '.join(full))
|
|
|
|
|
|
if '-s' in sys.argv: # print [s]olved
|
|
print_all_solved()
|
|
else:
|
|
play_around()
|
|
# try_totient_on_unsolved()
|
|
# for i in range(0, 4):
|
|
# print('offset:', i)
|
|
# find_oeis(irp=0, invert=False, offset=i, allow_fails=1, min_match=10)
|