import math, random, pylab
class Location(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def move(self, xc, yc):
return Location(self.x+float(xc), self.y+float(yc))
def getCoords(self):
return self.x, self.y
def getDist(self, other):
ox, oy = other.getCoords()
xDist = self.x - ox
yDist = self.y - oy
return math.sqrt(xDist**2 + yDist**2)
class CompassPt(object):
possibles = ('N', 'S', 'E', 'W')
def __init__(self, pt):
if pt in self.possibles: self.pt = pt
else: raise ValueError('in CompassPt.__init__')
def move(self, dist):
if self.pt == 'N': return (0, dist)
elif self.pt == 'S': return (0, -dist)
elif self.pt == 'E': return (dist, 0)
elif self.pt == 'W': return (-dist, 0)
else: raise ValueError('in CompassPt.move')
class Field(object):
def __init__(self, drunk, loc):
self.drunk = drunk
self.loc = loc
def move(self, cp, dist):
oldLoc = self.loc
xc, yc = cp.move(dist)
self.loc = oldLoc.move(xc, yc)
def getLoc(self):
return self.loc
def getDrunk(self):
return self.drunk
class Drunk(object):
def __init__(self, name):
self.name = name
def move(self, field, time = 1):
if field.getDrunk() != self:
raise ValueError('Drunk.move called with drunk not in field')
for i in range(time):
pt = CompassPt(random.choice(CompassPt.possibles))
field.move(pt, 1)
def performTrial(time, f):
start = f.getLoc()
distances = [0.0]
for t in range(1, time + 1):
f.getDrunk().move(f)
newLoc = f.getLoc()
distance = newLoc.getDist(start)
distances.append(distance)
return distances
drunk = Drunk('Homer Simpson')
for i in range(3):
f = Field(drunk, Location(0, 0))
distances = performTrial(500, f)
pylab.plot(distances)
pylab.title('Homer\'s Random Walk')
pylab.xlabel('Time')
pylab.ylabel('Distance from Origin')
def performSim(time, numTrials):
distLists = []
for trial in range(numTrials):
d = Drunk('Drunk' + str(trial))
f = Field(d, Location(0, 0))
distances = performTrial(time, f)
distLists.append(distances)
return distLists
def ansQuest(maxTime, numTrials):
means = []
distLists = performSim(maxTime, numTrials)
for t in range(maxTime + 1):
tot = 0.0
for distL in distLists:
tot += distL[t]
means.append(tot/len(distLists))
pylab.figure()
pylab.plot(means)
pylab.ylabel('distance')
pylab.xlabel('time')
pylab.title('Average Distance vs. Time (' + str(len(distLists)) + ' trials)')
ansQuest(500, 300)
pylab.show()
aW1wb3J0IG1hdGgsIHJhbmRvbSwgcHlsYWIKCmNsYXNzIExvY2F0aW9uKG9iamVjdCk6CiAgZGVmIF9faW5pdF9fKHNlbGYsIHgsIHkpOgogICAgc2VsZi54ID0gZmxvYXQoeCkKICAgIHNlbGYueSA9IGZsb2F0KHkpCiAgICAKICBkZWYgbW92ZShzZWxmLCB4YywgeWMpOgogICAgcmV0dXJuIExvY2F0aW9uKHNlbGYueCtmbG9hdCh4YyksIHNlbGYueStmbG9hdCh5YykpCgogIGRlZiBnZXRDb29yZHMoc2VsZik6CiAgICByZXR1cm4gc2VsZi54LCBzZWxmLnkKCiAgZGVmIGdldERpc3Qoc2VsZiwgb3RoZXIpOgogICAgb3gsIG95ID0gb3RoZXIuZ2V0Q29vcmRzKCkKICAgIHhEaXN0ID0gc2VsZi54IC0gb3gKICAgIHlEaXN0ID0gc2VsZi55IC0gb3kKICAgIHJldHVybiBtYXRoLnNxcnQoeERpc3QqKjIgKyB5RGlzdCoqMikKCgpjbGFzcyBDb21wYXNzUHQob2JqZWN0KToKICBwb3NzaWJsZXMgPSAoJ04nLCAnUycsICdFJywgJ1cnKQogIAogIGRlZiBfX2luaXRfXyhzZWxmLCBwdCk6CiAgICBpZiBwdCBpbiBzZWxmLnBvc3NpYmxlczogc2VsZi5wdCA9IHB0CiAgICBlbHNlOiByYWlzZSBWYWx1ZUVycm9yKCdpbiBDb21wYXNzUHQuX19pbml0X18nKQogICAgCiAgZGVmIG1vdmUoc2VsZiwgZGlzdCk6CiAgICBpZiBzZWxmLnB0ID09ICdOJzogcmV0dXJuICgwLCBkaXN0KQogICAgZWxpZiBzZWxmLnB0ID09ICdTJzogcmV0dXJuICgwLCAtZGlzdCkKICAgIGVsaWYgc2VsZi5wdCA9PSAnRSc6IHJldHVybiAoZGlzdCwgMCkKICAgIGVsaWYgc2VsZi5wdCA9PSAnVyc6IHJldHVybiAoLWRpc3QsIDApCiAgICBlbHNlOiByYWlzZSBWYWx1ZUVycm9yKCdpbiBDb21wYXNzUHQubW92ZScpCgogICAgCmNsYXNzIEZpZWxkKG9iamVjdCk6CiAgICAKICBkZWYgX19pbml0X18oc2VsZiwgZHJ1bmssIGxvYyk6CiAgICBzZWxmLmRydW5rID0gZHJ1bmsKICAgIHNlbGYubG9jID0gbG9jCiAgICAKICBkZWYgbW92ZShzZWxmLCBjcCwgZGlzdCk6CiAgICBvbGRMb2MgPSBzZWxmLmxvYwogICAgeGMsIHljID0gY3AubW92ZShkaXN0KQogICAgc2VsZi5sb2MgPSBvbGRMb2MubW92ZSh4YywgeWMpCiAgICAKICBkZWYgZ2V0TG9jKHNlbGYpOgogICAgcmV0dXJuIHNlbGYubG9jCgogIGRlZiBnZXREcnVuayhzZWxmKToKICAgIHJldHVybiBzZWxmLmRydW5rCgpjbGFzcyBEcnVuayhvYmplY3QpOgogIGRlZiBfX2luaXRfXyhzZWxmLCBuYW1lKToKICAgIHNlbGYubmFtZSA9IG5hbWUKICAgIAogIGRlZiBtb3ZlKHNlbGYsIGZpZWxkLCB0aW1lID0gMSk6CiAgICBpZiBmaWVsZC5nZXREcnVuaygpICE9IHNlbGY6CiAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ0RydW5rLm1vdmUgY2FsbGVkIHdpdGggZHJ1bmsgbm90IGluIGZpZWxkJykKICAgIGZvciBpIGluIHJhbmdlKHRpbWUpOgogICAgICBwdCA9IENvbXBhc3NQdChyYW5kb20uY2hvaWNlKENvbXBhc3NQdC5wb3NzaWJsZXMpKQogICAgICBmaWVsZC5tb3ZlKHB0LCAxKQogICAgICAKZGVmIHBlcmZvcm1UcmlhbCh0aW1lLCBmKToKICBzdGFydCA9IGYuZ2V0TG9jKCkKICBkaXN0YW5jZXMgPSBbMC4wXQogIGZvciB0IGluIHJhbmdlKDEsIHRpbWUgKyAxKToKICAgIGYuZ2V0RHJ1bmsoKS5tb3ZlKGYpCiAgICBuZXdMb2MgPSBmLmdldExvYygpCiAgICBkaXN0YW5jZSA9IG5ld0xvYy5nZXREaXN0KHN0YXJ0KQogICAgZGlzdGFuY2VzLmFwcGVuZChkaXN0YW5jZSkKICByZXR1cm4gZGlzdGFuY2VzCgpkcnVuayA9IERydW5rKCdIb21lciBTaW1wc29uJykKCmZvciBpIGluIHJhbmdlKDMpOgogIGYgPSBGaWVsZChkcnVuaywgTG9jYXRpb24oMCwgMCkpCiAgZGlzdGFuY2VzID0gcGVyZm9ybVRyaWFsKDUwMCwgZikKICBweWxhYi5wbG90KGRpc3RhbmNlcykKICAKcHlsYWIudGl0bGUoJ0hvbWVyXCdzIFJhbmRvbSBXYWxrJykKcHlsYWIueGxhYmVsKCdUaW1lJykKcHlsYWIueWxhYmVsKCdEaXN0YW5jZSBmcm9tIE9yaWdpbicpCgpkZWYgcGVyZm9ybVNpbSh0aW1lLCBudW1UcmlhbHMpOgogIGRpc3RMaXN0cyA9IFtdCiAgZm9yIHRyaWFsIGluIHJhbmdlKG51bVRyaWFscyk6CiAgICBkID0gRHJ1bmsoJ0RydW5rJyArIHN0cih0cmlhbCkpCiAgICBmID0gRmllbGQoZCwgTG9jYXRpb24oMCwgMCkpCiAgICBkaXN0YW5jZXMgPSBwZXJmb3JtVHJpYWwodGltZSwgZikKICAgIGRpc3RMaXN0cy5hcHBlbmQoZGlzdGFuY2VzKQogIHJldHVybiBkaXN0TGlzdHMKCmRlZiBhbnNRdWVzdChtYXhUaW1lLCBudW1UcmlhbHMpOgogIG1lYW5zID0gW10KICBkaXN0TGlzdHMgPSBwZXJmb3JtU2ltKG1heFRpbWUsIG51bVRyaWFscykKICBmb3IgdCBpbiByYW5nZShtYXhUaW1lICsgMSk6CiAgICB0b3QgPSAwLjAKICAgIGZvciBkaXN0TCBpbiBkaXN0TGlzdHM6CiAgICAgIHRvdCArPSBkaXN0TFt0XQogICAgbWVhbnMuYXBwZW5kKHRvdC9sZW4oZGlzdExpc3RzKSkKICBweWxhYi5maWd1cmUoKQogIHB5bGFiLnBsb3QobWVhbnMpCiAgcHlsYWIueWxhYmVsKCdkaXN0YW5jZScpCiAgcHlsYWIueGxhYmVsKCd0aW1lJykKICBweWxhYi50aXRsZSgnQXZlcmFnZSBEaXN0YW5jZSB2cy4gVGltZSAoJyArIHN0cihsZW4oZGlzdExpc3RzKSkgKyAnIHRyaWFscyknKQogIAphbnNRdWVzdCg1MDAsIDMwMCkKcHlsYWIuc2hvdygpCg==