Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # ultranary_repeater.py
- def next_ultranary(q,rep=3):
- L=len(q);B=2;D=[0]*L
- def ok(a):
- c={}
- for x in a:
- c[x]=c.get(x,0)+1
- if c[x]>rep:return False
- return True
- def build(cnt,mins,rem):
- o=[]
- for i in range(rem):
- lo=mins[i];p=False
- for x in range(lo,B):
- if cnt.get(x,0)<rep:
- o.append(x);cnt[x]=cnt.get(x,0)+1;p=True;break
- if not p:return
- return o
- def bump():
- nonlocal B,D
- B+=1;D=[0]*(L-2)+[1,B-1] if L>=2 else [B-1]
- def inc():
- nonlocal B,D
- if all(x==B-1 for x in D):bump();return
- for i in range(L-1,-1,-1):
- c={};okp=1
- for x in D[:i]:
- c[x]=c.get(x,0)+1
- if c[x]>rep:okp=0;break
- if not okp:continue
- for nv in range(D[i]+1,B):
- c2=dict(c);c2[nv]=c2.get(nv,0)+1
- if c2[nv]>rep:continue
- rem=L-(i+1);mins=D[i+1:]
- s=build(dict(c2),mins,rem)
- if s is not None:
- D=D[:i]+[nv]+s;return
- for j in range(L-2,-1,-1):
- if D[j]<B-1:
- D[j]=B-1
- for k in range(j+1,L):D[k]=0
- return
- bump()
- D=[0]*L
- while 1:
- if tuple(D)==q:
- inc()
- while not ok(D):inc()
- return tuple(D)
- inc()
- while not ok(D):inc()
- def test(q):
- p = next_ultranary(q)
- print(q, "->", p)
- return p
- q = (0, 0, 0, 1, 1)
- for _ in range(100):
- q = test(q)
- print("\nDemo:")
- q = (1, 1, 1, 0, 0)
- test(q)
- q = (2, 2, 2, 0, 1)
- test(q)
Advertisement
Add Comment
Please, Sign In to add comment