Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from collections import namedtuple, Counter
- from itertools import permutations
- from random import random
- Bullet = namedtuple("Bullet", ("time", "speed"))
- def ctime(bullet1, bullet2):
- """ time bullet1 will collide with bullet2, or None if no collision."""
- # swap bullets so that bullet2 is fired second
- if bullet2.time < bullet1.time: bullet1,bullet2 = bullet2,bullet1
- if bullet2.speed <= bullet1.speed: return None
- # where is bullet1 when bullet2 is fired?
- b1startPos = (bullet2.time - bullet1.time)*bullet1.speed
- # how long will it take bullet2 to catch up?
- catchUpTime = b1startPos/(bullet2.speed - bullet1.speed)
- return catchUpTime + bullet2.time
- def sim(bullets):
- """Input: list of bullets. Output: list of surviving bullets."""
- while True:
- n = len(bullets)
- ctimes = [ctime(bullets[i],bullets[i+1]) for i in xrange(n-1)]
- collisions = [(i,c) for (i,c) in enumerate(ctimes) if c != None]
- if not collisions: return bullets
- nextCollision = min(collisions, key=lambda (i,c): c)
- indexNextCollision = nextCollision[0]
- bullets = bullets[:indexNextCollision]+bullets[indexNextCollision+2:]
- return bullets
- def monte(n, trials):
- """ returns number of times (out of trials) that all bullets died."""
- deaths = 0
- for i in xrange(trials):
- bullets = [Bullet(i,random()) for i in xrange(n)]
- if len(sim(bullets)) == 0: deaths += 1
- return deaths
- def simulatePermutations(n):
- """ returns Counter of how many bullets survived in each of n! trials,
- each trial being one permutation of n randomly chosen speeds. """
- speeds = [random() for i in xrange(n)]
- def results():
- for speedperm in permutations(speeds):
- bullets = [Bullet(i,s) for (i,s) in enumerate(speedperm)]
- yield sim(bullets)
- return Counter(map(len, results()))
Advertisement
Add Comment
Please, Sign In to add comment