
def get_encrypted_msg():
    with open("../txt/EulerProblem059.txt", "r") as f:
        msg = [int(d) for d in f.read().split(',')]
        return msg


def get_words():
    with open("../txt/EulerProblem042.txt", "r") as f:
        words = [w.strip('"') for w in f.read().split(",")]
        return set(words)


def generate_keys():
    alphabet = list(map(chr, range(97, 123)))
    return [(ord(a), ord(b), ord(c))
            for a in alphabet
            for b in alphabet
            for c in alphabet]


def to_string(msg):
    return "".join(map(chr, msg))


def to_ascii(msg):
    return list(map(ord, msg))


def decrypt_msg(key, msg):
    return [d ^ key[i % len(key)] for i, d in enumerate(msg)]


def clean_word(word):
    return word.strip('').strip(",").strip(".").strip("!").strip("?").upper()


def test_key(key, msg, word_list):
    msg = to_string(decrypt_msg(key, msg))
    word_count = 0
    words = msg.split(" ")
    for word in words:
        if clean_word(word) in word_list:
            word_count += 1
    return word_count / len(words)


def euler_059():
    msg = get_encrypted_msg()
    word_list = get_words()
    keys = generate_keys()
    ss = [(test_key(key, msg, word_list), key) for key in keys]
    s = sorted(ss, reverse=True)[0]
    key = s[1]
    s = sum(decrypt_msg(key, msg))
    return s


if __name__ == "__main__":
    print("e059.py: " + str(euler_059()))
    assert(euler_059() == 107359)
