presenting… 30

a birthday meeting

may 30

carina

gifted python code

carina · mass tech

2021-06-29

so i was visiting the duluth reu as i do most years and carina asked me about her project related to arXiv:1606.09643 and arXiv:2104.03890. of course i still have the program that i wrote for her, even though i don't remember what it does.

from typing import List, Tuple
import sys
import itertools
from functools import lru_cache

Perm = Tuple[int, ...]

@lru_cache()
def inverse(perm : Perm) -> Perm:
    n = len(perm)
    ret : List[int] = [0] * n
    for i in range(n):
        ret[perm[i]-1] = i+1
    return tuple(ret)

@lru_cache()
def carina_pop_original(perm : Perm) -> Perm:
    ret : List[int] = []
    n = len(perm)
    i = 0
    while i < n:
        j = i
        while j+1 < n and perm[j] > perm[j+1]:
            j += 1
        ret += list(perm[i:j+1][::-1])
        i = j + 1
    return tuple(ret)

@lru_cache()
def carina_pop(perm : Perm) -> Perm:
    return inverse(carina_pop_original(inverse(perm)))

# --------

@lru_cache()
def carina_swap(perm : Perm) -> Perm:
    n = len(perm)
    for x in range(1, n): # x = 1, 2, ..., n-1
        j = perm.index(x)
        i = perm.index(x+1)
        def blocks(k : int) -> bool:
            return (
                    (perm[k] < x and k % 2 == 0)
                    or
                    (perm[k] > x+1 and k % 2 == 1)
                    )
        if j >= i+2 and any(blocks(k) for k in range(i+1,j)):
            ret = list(perm)
            ret[i] = x
            ret[j] = x+1
            return tuple(ret)
    return perm

@lru_cache()
def carina_pi_down_original(perm: Perm):
    while (x := carina_swap(perm)) != perm:
        perm = x
    return perm

@lru_cache()
def carina_pi_down(perm: Perm):
    return carina_pi_down_original(perm)

@lru_cache()
def carina_func(perm: Perm):
    return carina_pi_down(carina_pop(perm))

def is_identity(perm: Perm):
    return all(perm[i] == i+1 for i in range(len(perm)))

def check(perm: Perm):
    x = perm
    for _ in range(0, len(perm)-2):
        x = carina_func(x)
    return is_identity(carina_func(x)) and not is_identity(x)

for perm in itertools.permutations(range(1, int(sys.argv[1])+1)):
    if perm != carina_pi_down(perm):
        continue
    x = perm
    count = 0
    while not is_identity(x):
        x = carina_func(x)
        count += 1
    print(count, perm)