-3

here's the code I'm testing:

def rule(n):
    rules_numbers = {128: 'xxx', 64: 'xx.', 32: 'x.x', 16: 'x..',
                     8: '.xx', 4: '.x.', 2: '..x', 1: '...'}
    rules = {'...': '.', '..x': '.', '.x.': '.', '.xx': '.', 'x..': '.', 'x.x': '.', 'xx.': '.', 'xxx': '.'}
    while n != 0:
        for r in rules_numbers:
            if n - r >= 0:
                rules[rules_numbers[r]] = 'x'
                n -= r
                break
    return rules


def cellular_automaton(string, pattern, n):
    if n == 0:
        return string
    rules = rule(pattern)
    ng = ""
    for j in range(len(string)):
        nxt = j + 1
        if j == len(string) - 1:
            nxt = 0
        ng += rules[string[j - 1] + string[j] + string[nxt]]
        j += 1
    return cellular_automaton(ng, pattern, n - 1)

Here are some sample inputs and the outputs that we should get if the code is correct:

print(cellular_automaton('.x.x.x.x.', 17, 2))
#>>> xxxxxxx..
print(cellular_automaton('.x.x.x.x.', 249, 3))
#>>> .x..x.x.x
print(cellular_automaton('...x....', 125, 1))
#>>> xx.xxxxx
print(cellular_automaton('...x....', 125, 2))
#>>> .xxx....
print(cellular_automaton('...x....', 125, 3))
#>>> .x.xxxxx
print(cellular_automaton('...x....', 125, 4))
#>>> xxxx...x
print(cellular_automaton('...x....', 125, 5))
#>>> ...xxx.x
print(cellular_automaton('...x....', 125, 6))
#>>> xx.x.xxx
print(cellular_automaton('...x....', 125, 7))
#>>> .xxxxx..
print(cellular_automaton('...x....', 125, 8))
#>>> .x...xxx
print(cellular_automaton('...x....', 125, 9))
#>>> xxxx.x.x
print(cellular_automaton('...x....', 125, 10))
#>>> ...xxxxx

Here is a video explaining the problem I tried to solve: https://youtu.be/M_pkidxeGMY

When I run this code using Python3 I get all the outputs right, when I do it using Python2 I get different results. Can you pleae explain to me what part of the code makes the difference? Thanks!

resluts from Python2:

..xxxxxxx
.x.xxxxxx
xxx..xxx
..x.x...
xx....xx
.x.xxx..
x....x.x
x.xxx...
....x.xx
.xxx...x
...x.xx.
xxx...x.
ohbabd
  • 13
  • 4

1 Answers1

3

Your rules() function produces different results because it relies on the dictionary iteration order. Dictionaries do not have an ordering, and iteration over the keys is implementation dependent. Python 3.6 switched implementations, and with that the iteration order changed too, for example.

For your first rule, number 17, I get the following results:

Python 2.7:

>>> sorted(rule(17).items())
[('...', 'x'), ('..x', 'x'), ('.x.', '.'), ('.xx', '.'), ('x..', '.'), ('x.x', '.'), ('xx.', '.'), ('xxx', '.')]

Python 3.6:

>>> sorted(rule(17).items())
[('...', 'x'), ('..x', '.'), ('.x.', '.'), ('.xx', '.'), ('x..', 'x'), ('x.x', '.'), ('xx.', '.'), ('xxx', '.')]

Note how '..x' is mapped to '.' in one, 'x' in the other.

You'll have to alter your rules function to produce a fixed order. You could sort the keys, for example:

for r in sorted(rules_numbers):

Now all Python versions produce the same output:

>>> sorted(rule(17).items())
[('...', 'x'), ('..x', '.'), ('.x.', '.'), ('.xx', '.'), ('x..', '.'), ('x.x', '.'), ('xx.', '.'), ('xxx', '.')]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343