#!/usr/bin/env python3 import math import string chars = string.digits + string.ascii_letters def to_base(num, base): if base > len(chars): raise ValueError(f"Base must be less than {len(chars)}") if abs(num) == 0: return str(num) else: negative = num < 0 num = abs(num) digits = [] while num: digits.append(chars[num % base]) num //= base return ('-' if negative else '') + ''.join(digits[::-1]) test_me = { "023": "a", "030": "b", "031": "c", "032": "d", "033": "e", "103": "f", "113": "g", "123": "h", "130": "i", "131": "j", "132": "k", "133": "l", "203": "m", "213": "n", "223": "o", "230": "p", "231": "q", "232": "r", "233": "s", "303": "t", "313": "u", "323": "v", "330": "w", "331": "x", "332": "y", "333": "z" } for i, code in enumerate(test_me.keys()): # the lowercase letter codes use a pattern that repeats every seven letters. # starting from 030Q (12D), the code increments by one three times, then increments by four four times. # firstly, increase the output by 16 for every 7 in the input. # then, if i % 7 is 0, 1, 2, or 3, add that number to the output. # otherwise, subtract 3 from i % 7, multiply the result by 4, and add that to the output. # finally, add 11, because that's where the lowercase chars start. out = i // 7 * 16 + max((i % 7 - 3) * 4, i % 7) + 11 check = int(code, 4) print(f"In: {i:03}\tOut: {out:03}\tCode: {to_base(out, 4).zfill(3)} {('GOOD' if check == out else 'FAIL')}") print("\n===================\n") for i, code in enumerate(test_me.keys()): # now to do the process in reverse - converting a letter code to an index. # first we subtract 11 to get the codes to start from zero. x = int(code, 4) - 11 # first, add 7 for every 16 in the input. # next, we can use (x + 10) % 16 to get the sequence '10, 11, 12, 13, 14, 2, 6'. # we can use min() to replace the 2 with a 5, and then mod the whole sequence by 10 to get 0 through 6 repeating. # now we just need to add the two together. out = x // 16 * 7 + (max((x + 10) % 16, 5) % 10) character = string.ascii_lowercase[out] if out < len(string.ascii_lowercase) else '?' print(f"In: {x:03}\tOut: {out:03}\tGoal: {i:03}\tChar: {character} {('GOOD' if character == test_me[code] else 'FAIL')}") exit(0) headings = { "QUAD": "₄", "SEPT": "₇", "GOAL7": "₇", "DEC": "₁₀", "GOAL": "₁₀", "ORIG": "₁₀", "SXTNS": "₁₀", "FOURS": "₁₀", "MOD16": "₁₀", "MOD7": "₇", "MOD8": "₈", "MOD4": "₄", "MAGIC": "" } out = "" for heading in headings: out += f"{heading:8}" print(out) print("=" * 8 * len(headings)) goal = 2 successes = 0 for key in test_me.keys(): # breaks on i in [31, 46, 47, 51, 61, 62, 63] # original_value = int(key, 4) # the code starts at 023₄, which is 11₁₀, so we subtract 11₁₀ as an initial offset x = original_value - 1 sixteens = (x // 16) eights = (x // 8) mod_sixteen = x % 16 mod_eight = x % 8 fours = (x // 4) mod_sixteen_mod_seven = mod_sixteen % 7 # magic = abs(-8 + ((mod_eight // mod_sixteen) * (16 * sixteens + 8 + sixteens))) magic = 8 letter_index = ((7 * sixteens) + (x % 8)) - ((1 - (mod_sixteen // 8)) * (2 + 3 * (fours % 2))) output = [ key, to_base(letter_index, 7), to_base(goal, 7), letter_index, goal, x, sixteens, fours, mod_sixteen, mod_sixteen_mod_seven, mod_eight, x % 4, magic ] colour_code = 91 if goal == letter_index: successes += 1 colour_code = 0 print(f'\033[{colour_code}m', end='') out = "" for i, suffix in enumerate(headings.values()): value = str(output[i]).zfill(3) + suffix out += f"{value:8}" print(out) goal += 1 print(f"Succeeded on {successes} of {goal} attempts ({math.floor(successes / float(goal) * 100)}%)") exit(0) outputs = { "decimals": [], "indices": [], "mod_fours": [], "divided_by_sixteens": [], "indices_plus_mod_fours": [], "actual_indices": [], "correctness_checks": [] } position = 0 for x, expected_value in test_me.items(): wacky = " [WACKY]" if x[1] != "3" else "" num = int(x, 4) - 11 index = (num // 4) mod_four = num % 4 divided_by_sixteen = ((num) // 16) # actual_index = index + mod_four + (3 * divided_by_sixteen) actual_index = (num // 4) + (num % 4) + (3 * ((num - 4) // 16)) + 3 # actual_index = (num // 16) * 7 + (num % 4) correctness_check = "GUD" if actual_index == position else "OOP" outputs["decimals"].append(f"{num:3d}") outputs["indices"].append(f"{index:3d}") outputs["mod_fours"].append(f"{mod_four:3d}") outputs["divided_by_sixteens"].append(f"{divided_by_sixteen:3d}") outputs["indices_plus_mod_fours"].append(f"{mod_four + index:3d}") outputs["actual_indices"].append(f"{actual_index:3d}") outputs["correctness_checks"].append(correctness_check) position += 1 # print(f"{i}Q = {num}D{wacky}: {index}") print(' '.join(test_me.keys())) print(' ' + ' '.join(test_me.values())) # ignored_outputs = [""] for key, numbers in outputs.items(): print(' '.join(numbers) + f" ({key})")