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))
Beispiel #6
0
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')
Beispiel #9
0
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')