Advertisement
JoelSjogren

roll.py

Aug 12th, 2016
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.13 KB | None | 0 0
  1. # There is a simple connection between natural numbers and DFAs on a singleton
  2. # alphabet. The importance of this connection is easily illustrated in modular
  3. # arithmetic.
  4.  
  5. # Def: A roll is a pair of natural numbers, the second one of which is nonzero.
  6.  
  7. # (Thus a roll is a fraction, but we won't make this connection.)
  8.  
  9. # To every roll [p, q] we associate a DFA which goes through p states and then
  10. # goes into a loop of length q. Addition and multiplication of rolls, as well
  11. # as of their states, is easily defined. The states of this DFA are
  12. # conventionally taken to be the natural range [0, p+q).
  13.  
  14. # Good picture: https://pixabay.com/p-147631/?no_redirect
  15.  
  16. # (Actually, the theory of rolls should require no prior theory of natural
  17. # numbers if a roll is defined more like a DFA directly, but that's a more
  18. # beautiful story.)
  19.  
  20. # Here's some arithmetic aided by rolls.
  21.  
  22. """ Compute what state the DFA of b will be in after natural input a. """
  23. def nat_mod_roll(a, b):
  24.     flat, loop = b
  25.     return a if a < flat else (a - flat) % loop + flat
  26.  
  27. """
  28. Compute the smallest roll whose DFA states can index the states that the DFA
  29. of b ends up in after any input a^i.
  30. """
  31. def roll_of_powers(a, b):
  32.     powers = [1]
  33.     while True:
  34.         c = nat_mod_roll(a*powers[-1], b)
  35.         if c in powers:
  36.             return powers.index(c), len(powers) - powers.index(c)
  37.         powers.append(c)
  38.  
  39. """ Compute what state the DFA of b will be in after tower input a. """
  40. def tower_mod_roll(a, b):
  41.     if len(a) == 0:
  42.         return nat_mod_roll(1, b)
  43.     return nat_mod_roll(a[0]**tower_mod_roll(a[1:], roll_of_powers(a[0], b)), b)
  44.  
  45. def mod(a, b):
  46.     if isinstance(a, int): a = a,
  47.     if isinstance(b, int): b = 0, b
  48.     return tower_mod_roll(a, b)
  49.  
  50. def test():
  51.     arg_a = [2, 10], [100, 1000, 10000], [104, 2], [2, 3]
  52.     arg_b = 100, 100000, 5, 112
  53.     expect = 24, 0, 1, 8
  54.     for a, b, good in zip(arg_a, arg_b, expect):
  55.         c = mod(a, b)
  56.         print("mod({}, {}) = {} -- ".format(a, b, c), end="")
  57.         print("OK" if c == good else "FAIL (expected {})".format(good))
  58.  
  59. if __name__ == "__main__":
  60.     test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement