tyrion

bertos3.py

Jul 7th, 2012
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.30 KB | None | 0 0
  1. # -*- coding: utf8 -*-
  2. import collections
  3. import operator
  4. import array
  5.  
  6. # una namedtuple, scritta a mano perché dovevo aggiungere __add__ e avevo paura
  7. # che subclassando non avrebbe funzionato qualcosa.
  8. class Point(tuple):
  9.     __slots__ = ()
  10.  
  11.     def __new__(cls, x, y):
  12.         return tuple.__new__(cls, (x, y))
  13.  
  14.     def __repr__(self):
  15.         return "Point(x=%d, y=%d)" % self
  16.  
  17.     @property
  18.     def __dict__(self):
  19.         return collections.OrderedDict(('x', self[0]), ('y', self[1]))
  20.  
  21.     def __getnewargs__(self):
  22.         return tuple(self)
  23.  
  24.     def __add__(self, point):
  25.         return tuple.__new__(Point, (self[0]+point[0], self[1]+point[1]))
  26.  
  27.     x = property(operator.itemgetter(0), doc='Alias for field number 0')
  28.     y = property(operator.itemgetter(1), doc='Alias for field number 1')
  29.  
  30.  
  31. directions = dict((Point(x, y), weight) for weight, x, y in
  32.                 ((0.2, 1, 0), (0.2, -1, 0), (0.3, 0, -1), (0.3, 0, 1)))
  33.  
  34. def dfs(MAX_DEPTH=13):
  35.  
  36.     weights = array.array('d')
  37.     tot = [0] # trick in mancanza di nonlocal
  38.  
  39.     weights.append(1)
  40.  
  41.     def visit(path, u, depth):
  42.         if depth == MAX_DEPTH:
  43.             tot[0] += weights.pop()
  44.             return
  45.  
  46.         path.add(u)
  47.         for direction in directions:
  48.             v = u + direction
  49.             if v not in path:
  50.                 weights.append(weights[-1] * directions[direction])
  51.                 visit(path, v, depth+1)
  52.         path.remove(u)
  53.         if weights: weights.pop()
  54.  
  55.     visit(set(), Point(0, 0), 0)
  56.     return tot[0]
  57.  
  58.  
  59. # 0.0118839917111129954
  60. # soluzione(?): 0.98811600828887
  61.  
  62. import random
  63. import heapq
  64.  
  65.  
  66. # funzione utilizzata per farmi un'idea del risultato
  67. def test(times=1000000, depth=13):
  68.  
  69.     def simulate():
  70.         pos = Point(0, 0)
  71.         Q = [pos]
  72.         for _ in xrange(depth):
  73.             r = random.randrange(9)
  74.             if r < 2:
  75.                 pos += Point(+1, 0)
  76.             elif r < 4:
  77.                 pos += Point(-1, 0)
  78.             elif r < 7:
  79.                 pos += Point(0, -1)
  80.             else:
  81.                 pos += Point(0, +1)
  82.  
  83.             if pos in Q:
  84.                 return 0
  85.             heapq.heappush(Q, pos)
  86.         return 1
  87.  
  88.     return sum(simulate() for _ in xrange(times))
  89.  
  90.  
  91. if __name__ == '__main__':
  92.     print(1 - dfs())
Advertisement
Add Comment
Please, Sign In to add comment