Advertisement
Guest User

Untitled

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