Advertisement
Guest User

Untitled

a guest
Dec 16th, 2016
803
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.99 KB | None | 0 0
  1. import itertools
  2. import time
  3.  
  4. # takes a state and checks if any chips are burned
  5. def violate(vio_list):
  6.     # gen-chip pair
  7.     pairs = map(lambda x: vio_list[1:][x:x+2], range(0,len(vio_list[1:]),2))
  8.  
  9.     # floors of generators
  10.     gens = vio_list[1::2]
  11.  
  12.     # check if any gen-chip pair is not on same floor, if true check if any gen is on the same floor as chip
  13.     for p in pairs:
  14.         if p[0] != p[1]:
  15.             if p[1] in gens:
  16.                 return True
  17.     return False
  18.  
  19. # takes a state and checks if already visited given that all pairs are interchangeable
  20. # [0,1,1,0,0] == [0,0,0,1,1]
  21. def vis_state(vis_l):
  22.     global visited_states
  23.  
  24.     # gen-chip pair
  25.     pairs = map(lambda x: vis_l[1:][x:x+2], range(0,len(vis_l[1:]),2))
  26.  
  27.     # add floor to every pair
  28.     state = map(lambda x: (vis_l[0], x), pairs)
  29.  
  30.     # create unique state by adding floor to every pair and then sort by pair
  31.     # [0,1,1,0,0] = [0,0,0,1,1] = [(0,[0,0]),(0,[1,1])]
  32.     sorted_by_second = sorted(state, key=lambda tup: tup[1])
  33.     l = [sorted_by_second]
  34.  
  35.     # check if the unique state already been visited, if not store in global visited_states
  36.     if l in visited_states:
  37.         return True
  38.     else:
  39.         visited_states.append(l)
  40.         return False
  41.  
  42.  
  43. def day11():
  44.     global visited_states
  45.     t0 = time.time()
  46.  
  47.     # visited is queue to loop
  48.     # ([elevator, generator1, chip1, generator2, chip2...], graph-start), where value represents floor of item
  49.     visited = [([0, 1, 0, 2, 0], 0)]  # test
  50.     #visited = [([0, 0, 0, 0, 1, 0, 1, 2, 2, 2, 2], 0)]  # 1
  51.     #visited = [([0, 0, 0, 0, 1, 0, 1, 2, 2, 2, 2, 0, 0, 0, 0], 0)]  # 2
  52.     loops = 0
  53.     for lk in visited:
  54.         # current state
  55.         l = lk[0]
  56.         curr_floor = l[0]
  57.  
  58.         # where in graph
  59.         curr_try = lk[1]
  60.  
  61.         # what items are on same floor as elevator
  62.         at_e_level = [i for i, x in enumerate(l) if x == curr_floor][1:]
  63.  
  64.         # possible moves based on items at_e_level, move either any combo of two or only one
  65.         possible_moves = list(itertools.combinations(at_e_level, 2)) + at_e_level
  66.  
  67.         # if curr floor is 0 or 3 only one direction is allowed, otherwise up and down
  68.         if curr_floor == 0:
  69.             dirs = [1]
  70.         elif curr_floor == 3:
  71.             dirs = [-1]
  72.         else:
  73.             dirs = [-1, 1]
  74.  
  75.         # copy old state that every move will be based on
  76.         old_l = l[:]
  77.  
  78.         # do all possible moves in all possible directions
  79.         for d in dirs:
  80.             for each in possible_moves:
  81.                 loops += 1
  82.  
  83.                 # copy old state and move from there
  84.                 test_l = old_l[:]
  85.  
  86.                 # move elevator
  87.                 test_l[0] = curr_floor+d
  88.  
  89.                 # bring two items in elevator
  90.                 if type(each) == tuple:
  91.                     test_l[each[0]] = curr_floor + d
  92.                     test_l[each[1]] = curr_floor + d
  93.                 # bring one item in elevator
  94.                 else:
  95.                     test_l[each] = curr_floor + d
  96.  
  97.                 # check if new state already been visited
  98.                 if vis_state(test_l) is True:
  99.                     continue
  100.  
  101.                 # if not burning chip, put in q with number in graph
  102.                 if violate(test_l) is False:
  103.                     visited.append((test_l, curr_try+1))
  104.  
  105.                 # check if everything in list is on third floor, then print where in graph (moves)
  106.                 if sum(test_l) == len(test_l)*3:
  107.                     print 'current state:', test_l
  108.                     print 'moves:', curr_try+1
  109.                     print 'elapsed time:', time.time()-t0
  110.                     print 'allowed states visited:', len(visited)
  111.                     print 'unique states visited:', len(visited_states)
  112.                     print 'total visits:', loops
  113.                     return
  114.  
  115.  
  116. def main():
  117.     global visited_states
  118.     visited_states = []
  119.     day11()
  120.  
  121.  
  122. if __name__ == '__main__':
  123.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement