Guest User

Untitled

a guest
Nov 23rd, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.80 KB | None | 0 0
  1. import random
  2. # E(H) = E(T) = 2
  3.  
  4. # E(HT) = E(TH) = 4
  5. # E(HH) = E(TT) = 6
  6.  
  7. # E(HHT) = E(TTH) = 8 (E(HH) + 1/2 + 1/2(1 + E(HHT) - E(HH))
  8. # E(THH) = E(HTT) = 8 (E(TH) + 1/2 + 1/2(1 + E(THH) - E(T))
  9. # E(HTH) = E(THT) = 10 (E(HT) + 1/2 + 1/2(1 + E(HTH)))
  10. # E(HHH) = E(TTT) = 14 (E(HH) + 1/2 + 1/2(1 + E(HHH)))
  11.  
  12. # E(HHHH) = E(TTTT) = 30 (E(HHH) + 1/2 + 1/2(1 + E(HHHH)))
  13. # E(HHHT) = E(TTTH) = 16 (E(HHH) + 1/2 + 1/2(1 + E(HHHT) - E(HHH)))
  14. # E(HHTH) = E(TTHT) = 18 (E(HHT) + 1/2 + 1/2(1 + E(HHTH)))
  15. # E(HHTT) = E(TTHH) = 16 (E(HHT) + 1/2 + 1/2(1 + E(HHTT) - E(H)))
  16. # E(x) = E(x[:-1]) + 1/2 + 1/2(1 + E(x) - E(x[:max(xrange(len(x) - 1, -1, -1), key=lambda i:x[:i] == (x[:-1] + chr(ord(x[-1]) ^ ord('T') ^ ord('H')))[len(x) - i:])]))
  17.  
  18. def E_topdown(x, cache={'': 0}):
  19. global g_cache
  20. g_cache = cache
  21. if x in cache:
  22. return cache[x]
  23. ret = 2 * E_topdown(x[:-1]) + 2 - E_topdown(x[:max(xrange(len(x) - 1, -1, -1), key=lambda i:x[:i] == (x[:-1] + chr(ord(x[-1]) ^ ord('T') ^ ord('H')))[len(x) - i:])])
  24. cache[x] = ret
  25. return ret
  26.  
  27. def E_bottomup(x):
  28. table = [0]
  29. for i in xrange(1, len(x) + 1):
  30. x_prefix = x[:i]
  31. x_flip_tail = x_prefix[:-1] + chr(ord(x_prefix[-1]) ^ ord('T') ^ ord('H'))
  32. match_offset = next(offset for offset in range(len(x_prefix) - 1, -1, -1) if x_prefix[:offset] == x_flip_tail[len(x_prefix) - offset:])
  33. table.append(2 * table[-1] + 2 - table[match_offset])
  34. return table[len(x)]
  35.  
  36. def toss(s):
  37. cnt = 0
  38. ary = [None] * len(s)
  39. while True:
  40. ary = ary[1:] + [random.choice('HT')]
  41. cnt += 1
  42. if ary == list(s):
  43. return cnt
  44.  
  45. for _ in xrange(100):
  46. s = ''.join(random.choice('HT') for _ in xrange(5))
  47. N = 10000
  48. print sum(toss(s) for i in xrange(N)) / float(N)
  49. print E_topdown(s)
  50. assert E_topdown(s) == E_bottomup(s)
Add Comment
Please, Sign In to add comment