Advertisement
Guest User

Untitled

a guest
Jul 2nd, 2015
316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.53 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. '''
  3. Passengers: Peasant, grain, rooster, and fox
  4. Space: Korea, Boat, Japan
  5. What?:
  6.  All the passengers are immigrating from Korea to Japan
  7.  Only a peasant can control the boat.
  8.  Boat can carry only two passengers.
  9.  Fox eats Rooster.
  10.  Rooster eats grain.
  11.  Peasant saves everyone.
  12.  How can all the passengers arrive Japan?
  13.  
  14. Step 1. {Pick passengers to be carried to Japan}
  15.  In otherwords, pick two passengers whom will be left in land
  16.  (either Korea or in Japan), who won't eat another.
  17.  
  18.  def is_good_chemistry(p1, p2):
  19.    return not p1.eats(p2) and not p2.eats(p3)
  20.  
  21.  The relation between n passengers = n*(n - 1) / 2
  22.  If the good chemistry can't be found between the passengers then it's over
  23.  
  24. Step 2. {Leave a passenger to Japan and decide whether you will carry sbd back}
  25.  if is_good_chemistry(p1, p2) == True:
  26.    leave the passenger
  27.  
  28. Step 3. if Japan.passengers.len == population: end!
  29. '''
  30. from sets import Set
  31. import random
  32. from itertools import *
  33.  
  34. class Passenger(object):
  35.   """ Anything that gets on board on the boat.
  36.  Assumed that there could be multiple captains """
  37.   newid = count().next
  38.   def __init__(self, species, food=None, is_captain=False):
  39.     self.id = Passenger.newid()
  40.     self.species = species
  41.     self.food = food
  42.     self.is_captain = is_captain
  43.  
  44.   def eat(self, other):
  45.     return self.food == other.species
  46.  
  47.   def __eq__(self, other):
  48.     return self.id == other.id
  49.  
  50.   def __hash__(self):
  51.     return self.id.__hash__()
  52.  
  53.   def __str__(self):
  54.     return "I am %s" % self.species
  55.  
  56. class Space(object):
  57.   """docstring for """
  58.   def __init__(self, name, residents=[]):
  59.     self.name = name
  60.     self.residents = residents
  61.     self.captains = self.update_captains()
  62.  
  63.   def num_residents(self):
  64.     return len(self.residents)
  65.  
  66.   ## e.g. send_off([traveller1, traveller2])
  67.   def send_off(self, passengers):
  68.     ''' Remove the passengers who left for the other land.
  69.    It means that the number of captains in the land is changed. '''
  70.     self.residents = list(Set(self.residents) - Set(passengers))
  71.     self.captains = self.update_captains()
  72.  
  73.   ## e.g. welcome([sailing_captain, traveller])
  74.   def welcome(self, passengers):
  75.     ''' Append newcomers '''
  76.     self.residents += passengers
  77.     self.captains = self.update_captains()
  78.  
  79.   def update_captains(self):
  80.     return [r for r in self.residents if r.is_captain]
  81.  
  82.   def pick_a_captain(self):
  83.     ''' Pick a captain randomly '''
  84.     return random.choice(self.captains)
  85.  
  86.   def print_resident_species(self):
  87.     ''' Simply print out every species in the land.
  88.    For debug purpose '''
  89.     for r in self.residents:
  90.       print r.species
  91.  
  92.   def get_resident_species(self):
  93.     ''' e.g. Returns "fox, grain,"
  94.    "fox, grain, peasant" '''
  95.     species = [r.species for r in self.residents]
  96.     return ', '.join(species)
  97.  
  98.   def __str__(self):
  99.     return self.name + ": " + self.get_resident_species()
  100.  
  101.  
  102. ''' Stand-alone functions '''
  103. def get_captains(residents):
  104.   return [r for r in residents if r.is_captain]
  105.  
  106. def is_peaceful_pair(pair):
  107.   ''' e.g. is_peaceful_pair([fox, rooster]) => False '''
  108.   p1 = pair[0]
  109.   p2 = pair[1]
  110.   return not p1.eat(p2) and not p2.eat(p1)
  111.  
  112. def is_peaceful(residents):
  113.   ''' e.g. is_peaceful([fox, rooster, grain]) => False '''
  114.   for pair in list(permutations(residents, r=2)):
  115.     if not is_peaceful_pair(pair):
  116.       return False
  117.   return True
  118.  
  119. def select_traveller(from_):
  120.   for t in from_.residents:
  121.       ## Figure out if the rest of the residents will get along
  122.       if is_peaceful(list(Set(from_.residents) - Set([t]))):
  123.         from_.send_off([t])
  124.         return t
  125.   return None
  126.  
  127. def get_sailing_captain(from_):
  128.   sailing_captain = from_.pick_a_captain()
  129.   from_.send_off([sailing_captain])
  130.   return sailing_captain
  131.  
  132. ## e.g. travel_to_destination(korea, japan)
  133. ## If succeeds, return passengers. If not, return None(stop the simulation)
  134. def travel_to_destination(from_, to):
  135.   '''
  136.  Randomly pick one traveller and figures out whether the rest will be safe.
  137.  Loop until find one and if not, this simulation should end.
  138.  '''
  139.   if len(from_.captains) == 0:
  140.     ## No captain, no simulation
  141.     print "There is no captain who can sail a boat :("
  142.     return None
  143.   sailing_captain = get_sailing_captain(from_)
  144.  
  145.   ## Shuffle the residents list so that you always get a random traveller
  146.   random.shuffle(from_.residents)
  147.   traveller = select_traveller(from_)
  148.   if traveller != None:
  149.     passengers = [sailing_captain, traveller]
  150.     to.welcome(passengers)
  151.     return passengers
  152.   else:
  153.     return None
  154.  
  155. ## e.g. travel_back(japan, korea):
  156. ##
  157. def travel_back(from_, to):
  158.   sailing_captain = get_sailing_captain(from_)
  159.   ## Shuffle the residents list so that you always get a random traveller
  160.   if is_peaceful(from_.residents):
  161.     to.welcome([sailing_captain])
  162.     return [sailing_captain]
  163.   else:
  164.     ## Added(random.shuffle....) according to hamstergene's advice on
  165.     ## http://stackoverflow.com/questions/31156337/mysterious-infinite-loop-in-python-2-7-9-on-mac-os-x-10-10-3
  166.     random.shuffle(from_.residents)
  167.     traveller = select_traveller(from_)
  168.     passengers = [sailing_captain, traveller]
  169.     to.welcome(passengers)
  170.     return passengers
  171.  
  172. def get_passenger_name(passengers):
  173.   return tuple(p.species for p in passengers)
  174.  
  175. def print_land_info(lands):
  176.   for l in lands:
  177.     print l
  178.  
  179. peasant2 = Passenger('human', is_captain=True)
  180. peasant3 = Passenger('human', is_captain=True)
  181. peasant = Passenger('human', is_captain=True)
  182. fox2 = Passenger('fox', 'rooster')
  183. fox = Passenger('fox', 'rooster')
  184. rooster = Passenger('rooster', 'grain')
  185. rooster2 = Passenger('rooster', 'grain')
  186. grain = Passenger('grain')
  187. grain2 = Passenger('grain')
  188.  
  189.  
  190. korea = Space('Korea', [peasant, fox, rooster, grain])
  191. japan = Space('Japan')
  192.  
  193. for r in korea.residents:
  194.   print hash(r)
  195.  
  196. POPULATION = korea.num_residents()
  197. CAPTAIN = get_captains(korea.residents)
  198. i = 1
  199. while True:
  200.   print "Loop", i
  201.   passengers = travel_to_destination(korea, japan)
  202.   if passengers == None:
  203.     print "The journey can't be continued"
  204.     break
  205.   if japan.num_residents() == POPULATION:
  206.     print "Everyone has crossed the river safely!"
  207.     print_land_info([korea, japan])
  208.     break
  209.   else:
  210.     print "Korea ---> Japan", get_passenger_name(passengers)
  211.     print_land_info([korea, japan])
  212.     passengers = travel_back(japan, korea)
  213.     print "Japan ---> Korea", get_passenger_name(passengers)
  214.     print_land_info([korea, japan])
  215.     print "========================"
  216.   i += 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement