SHARE
TWEET

isorule.py

Ian07_ Feb 14th, 2019 96 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
  6. import golly as g
  7. from glife import validint
  8. from string import replace
  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 = replace(result, '4aceijknqrtwyz', '4')
  58.     result = replace(result, '3aceijknqry', '3')
  59.     result = replace(result, '5aceijknqry', '5')
  60.     result = replace(result, '2aceikn', '2')
  61.     result = replace(result, '6aceikn', '6')
  62.     result = replace(result, '1ce', '1')
  63.     result = 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)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top