Advertisement
Ian07_

isorule.py

Feb 14th, 2019 (edited)
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.30 KB | None | 0 0
  1. # isorule.py
  2. # A modification of partialrule.py which returns the isotropic rulespace for a pattern in a format suitable for infoboxes on the wiki.
  3. # This simply checks the number of generations you input to see if the pattern's evolution is the same, so it can be used for non-periodic patterns as well.
  4. # Shamelessly stolen from Rhombic (Feb 2018) by Ian07 (Jan 2019).
  5. # Now fixed for Python 3.x! (Oct 2020)
  6.  
  7. import golly as g
  8. from glife import validint
  9.  
  10. Hensel = [
  11.     ['0'],
  12.     ['1c', '1e'],
  13.     ['2a', '2c', '2e', '2i', '2k', '2n'],
  14.     ['3a', '3c', '3e', '3i', '3j', '3k', '3n', '3q', '3r', '3y'],
  15.     ['4a', '4c', '4e', '4i', '4j', '4k', '4n', '4q', '4r', '4t', '4w', '4y', '4z'],
  16.     ['5a', '5c', '5e', '5i', '5j', '5k', '5n', '5q', '5r', '5y'],
  17.     ['6a', '6c', '6e', '6i', '6k', '6n'],
  18.     ['7c', '7e'],
  19.     ['8']
  20. ]
  21.  
  22. # Python versions < 2.4 don't have "sorted" built-in
  23. try:
  24.     sorted
  25. except NameError:
  26.     def sorted(inlist):
  27.         outlist = list(inlist)
  28.         outlist.sort()
  29.         return outlist
  30.  
  31. # --------------------------------------------------------------------
  32.  
  33. def chunks(l, n):
  34.     for i in range(0, len(l), n):
  35.         yield l[i:i+n]
  36.  
  37. # --------------------------------------------------------------------
  38.  
  39. def rulestringopt(a):
  40.     result = ''
  41.     context = ''
  42.     lastnum = ''
  43.     lastcontext = ''
  44.     for i in a:
  45.         if i in 'BS':
  46.             context = i
  47.             result += i
  48.         elif i in '012345678':
  49.             if (i == lastnum) and (lastcontext == context):
  50.                 pass
  51.             else:
  52.                 lastcontext = context
  53.                 lastnum = i
  54.                 result += i
  55.         else:
  56.             result += i
  57.     result = str.replace(result, '4aceijknqrtwyz', '4')
  58.     result = str.replace(result, '3aceijknqry', '3')
  59.     result = str.replace(result, '5aceijknqry', '5')
  60.     result = str.replace(result, '2aceikn', '2')
  61.     result = str.replace(result, '6aceikn', '6')
  62.     result = str.replace(result, '1ce', '1')
  63.     result = str.replace(result, '7ce', '7')
  64.     return result
  65.  
  66. clist = []
  67. rule = g.getrule().split(':')[0]
  68.  
  69. fuzzer = rule + '9'
  70. oldrule = rule
  71. rule = ''
  72. context = ''
  73. deletefrom = []
  74. for i in fuzzer:
  75.     if i == '-':
  76.         deletefrom = [x[1] for x in Hensel[int(context)]]
  77.     elif i in '0123456789/S':
  78.         if deletefrom:
  79.             rule += ''.join(deletefrom)
  80.             deletefrom = []
  81.         context = i
  82.     if len(deletefrom) == 0:
  83.         rule += i
  84.     elif i in deletefrom:
  85.         deletefrom.remove(i)
  86. rule = rule.strip('9')
  87.  
  88. if not (rule[0] == 'B' and '/S' in rule):
  89.     g.exit('Please set Golly to a Life-like rule.')
  90.  
  91. if g.empty():
  92.     g.exit('The pattern is empty.')
  93.  
  94. s = g.getstring('Enter the period:', '', 'Rules calculator')
  95. if not validint(s):
  96.     g.exit('Bad number: %s' % s)
  97.  
  98. numsteps = int(s)
  99. if numsteps < 1:
  100.     g.exit('Period must be at least 1.')
  101.  
  102. g.select(g.getrect())
  103. g.copy()
  104. s = int(s)
  105.  
  106. for i in range(0,s):
  107.     g.run(1)
  108.     clist.append(list(chunks(g.getcells(g.getrect()), 2)))
  109.     mcc = min(clist[i])
  110.     clist[i] = [[x[0] - mcc[0], x[1] - mcc[1]] for x in clist[i]]
  111.  
  112. g.show('Processing...')
  113.  
  114. ruleArr = rule.split('/')
  115. ruleArr[0] = ruleArr[0].lstrip('B')
  116. ruleArr[1] = ruleArr[1].lstrip('S')
  117.  
  118. b_need = []
  119. b_OK = []
  120. s_need = []
  121. s_OK = []
  122.  
  123. context = ''
  124. fuzzed = ruleArr[0] + '9'
  125. for i in fuzzed:
  126.     if i in '0123456789':
  127.         if len(context) == 1:
  128.             b_need += Hensel[int(context)]
  129.             b_OK += Hensel[int(context)]
  130.         context = i
  131.     elif context != '':
  132.         b_need.append(context[0] + i)
  133.         b_OK.append(context[0] + i)
  134.         context += context[0]
  135. context = ''
  136. fuzzed = ruleArr[1] + '9'
  137. for i in fuzzed:
  138.     if i in '0123456789':
  139.         if len(context) == 1:
  140.             s_need += Hensel[int(context)]
  141.             s_OK += Hensel[int(context)]
  142.         context = i
  143.     elif context != '':
  144.         s_need.append(context[0] + i)
  145.         s_OK.append(context[0] + i)
  146.         context += context[0]
  147.  
  148. for i in [iter2 for iter1 in Hensel for iter2 in iter1]:
  149.     if not i in b_OK:
  150.         b_OK.append(i)
  151.         execfor = 1
  152.         # B0 and nontotalistic rulestrings are mutually exclusive
  153.         try:
  154.             g.setrule(rulestringopt('B' + ''.join(b_OK) + '/S' + ruleArr[1]))
  155.         except:
  156.             b_OK.remove(i)
  157.             execfor = 0
  158.         for j in range(0, s * execfor):
  159.             g.run(1)
  160.             try:
  161.                 dlist = list(chunks(g.getcells(g.getrect()), 2))
  162.                 mcc = min(dlist)
  163.                 dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
  164.                 if not(clist[j] == dlist):
  165.                     b_OK.remove(i)
  166.                     break
  167.             except:
  168.                 b_OK.remove(i)
  169.                 break
  170.         g.new('')
  171.         g.paste(0, 0, 'or')
  172.         g.select(g.getrect())
  173.         b_OK.sort()
  174.  
  175.     if not i in s_OK:
  176.         s_OK.append(i)
  177.         execfor = 1
  178.         # B0 and nontotalistic rulestrings are mutually exclusive
  179.         try:
  180.             g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_OK)))
  181.         except:
  182.             s_OK.remove(i)
  183.             execfor = 0
  184.         for j in range(0, s * execfor):
  185.             g.run(1)
  186.             try:
  187.                 dlist = list(chunks(g.getcells(g.getrect()), 2))
  188.                 mcc = min(dlist)
  189.                 dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
  190.                 if not(clist[j] == dlist):
  191.                     s_OK.remove(i)
  192.                     break
  193.             except:
  194.                 s_OK.remove(i)
  195.                 break
  196.         g.new('')
  197.         g.paste(0, 0, 'or')
  198.         g.select(g.getrect())
  199.         s_OK.sort()
  200.  
  201.     if i in b_need:
  202.         b_need.remove(i)
  203.         g.setrule(rulestringopt('B' + ''.join(b_need) + '/S' + ruleArr[1]))
  204.         for j in range(0, s):
  205.             g.run(1)
  206.             try:
  207.                 dlist = list(chunks(g.getcells(g.getrect()), 2))
  208.                 mcc = min(dlist)
  209.                 dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
  210.                 if not(clist[j] == dlist):
  211.                     b_need.append(i)
  212.                     break
  213.             except:
  214.                 b_need.append(i)
  215.                 break
  216.         g.new('')
  217.         g.paste(0, 0, 'or')
  218.         g.select(g.getrect())
  219.         b_need.sort()
  220.  
  221.     if i in s_need:
  222.         s_need.remove(i)
  223.         g.setrule(rulestringopt('B' + ruleArr[0] + '/S' + ''.join(s_need)))
  224.         for j in range(0, s):
  225.             g.run(1)
  226.             try:
  227.                 dlist = list(chunks(g.getcells(g.getrect()), 2))
  228.                 mcc = min(dlist)
  229.                 dlist = [[x[0] - mcc[0], x[1] - mcc[1]] for x in dlist]
  230.                 if not(clist[j] == dlist):
  231.                     s_need.append(i)
  232.                     break
  233.             except:
  234.                 s_need.append(i)
  235.                 break
  236.         g.new('')
  237.         g.paste(0, 0, 'or')
  238.         g.select(g.getrect())
  239.         s_need.sort()
  240.  
  241. g.setrule('B' + ''.join(sorted(b_need)) + '/S' + ''.join(sorted(s_need)))
  242. rulemin = g.getrule()
  243.  
  244. g.setrule('B' + ''.join(sorted(b_OK)) + '/S' + ''.join(sorted(s_OK)))
  245. rulemax = g.getrule()
  246.  
  247. ruleres = '|isorulemin       = ' + rulemin + '|isorulemax       = ' + rulemax
  248. g.show(ruleres)
  249. g.setclipstr(ruleres)
  250. g.setrule(oldrule)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement