Guest User

Untitled

a guest
Jul 11th, 2018
566
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.11 KB | None | 0 0
  1. from collections import defaultdict
  2. import random
  3.  
  4.  
  5. def colored_row(row):
  6.     blue_color = "\033[94m"
  7.     green_color = "\033[92m"
  8.     yellow_color = "\033[93m"
  9.     red_color = "\033[91m"
  10.     end_color = "\033[0m"
  11.     colored_number = {0: blue_color + "0" + end_color,
  12.                       1: green_color + "1" + end_color,
  13.                       2: yellow_color + "2" + end_color,
  14.                       3: red_color + "3" + end_color}
  15.     return [colored_number.get(c, c) for c in row]
  16.    
  17. class Board():
  18.  
  19.     def __init__(self, columns, clicks=0, prevs=[]):
  20.         self.columns = columns
  21.         self.clicks = clicks
  22.         self.prevs = prevs
  23.  
  24.         self.win = len(columns) == 0
  25.    
  26.     def _equal(self, cell1, cell2):
  27.         col1, row1 = cell1
  28.         col2, row2 = cell2
  29.         if col2 >= 0 and row2 >=0 and col2 < len(self.columns) and row2 < len(self.columns[col2]) and self.columns[col1][row1] == self.columns[col2][row2]:
  30.             return True
  31.         return False
  32.  
  33.     def _get_group(self, group, check):
  34.         new = set()
  35.         vec = [(0, 1), (0, -1), (-1, 0), (1, 0)]
  36.         for cell in check:
  37.             for r, c in vec:
  38.                 cell2 = (cell[0] + c, cell[1] + r)
  39.                 if cell2 not in group and self._equal(cell, cell2):
  40.                     new.add(cell2)
  41.        
  42.         group.update(new)
  43.         if new:
  44.             return self._get_group(group, new)
  45.         else:
  46.             return group                    
  47.    
  48.     def _get_iter_groups(self):
  49.         groups = []
  50.         checked = set()
  51.         for col, column in enumerate(self.columns):
  52.             for row in range(len(column)):
  53.                 cell = (col, row)
  54.                 if cell not in checked:
  55.                     new_group = self._get_group({cell}, {cell})
  56.                     checked.update(new_group)
  57.                     yield new_group
  58.  
  59.     def iter_next_boards(self):
  60.         for group in self._get_iter_groups():
  61.             if len(group) == 1: continue
  62.             columns = tuple(tuple(cell for r, cell in enumerate(column) if (c, r) not in group) for c, column in enumerate(self.columns))
  63.             columns = tuple(c for c in columns if c)
  64.             prevs = self.prevs + [self]
  65.             yield Board(columns, self.clicks + 1, prevs)
  66.    
  67.    
  68.     def super_print(self):
  69.         for b in self.prevs:
  70.             max_c = max(len(c) for c in b.columns)
  71.             filled_cols = []
  72.             for col in b.columns:
  73.                 fill_col = list(col) + [" "]*(max_c - len(col))
  74.                 fill_col.reverse()
  75.                 filled_cols.append(fill_col)
  76.             for row in zip(*filled_cols):
  77.                 print " ".join(map(str, colored_row(row)))
  78.             print "-"*50
  79.  
  80.  
  81. def posible(b):
  82.     counter = defaultdict(int)
  83.     for col in b.columns:
  84.         for cell in col:
  85.             counter[cell]+=1
  86.     return not any(v==1 for v in counter.values())
  87.  
  88. # Azul = 0
  89. # Verde = 1
  90. # Amarillo = 2
  91. # Rojo = 3
  92. def get_board():
  93.     game = ["100113123333021",
  94.             "033130023203023",
  95.             "201333303320102",
  96.             "300202232102021",
  97.             "333322112303022",
  98.             "000232202321133",
  99.             "201123202211202",
  100.             "311301111033022",
  101.             "233022111321322"]
  102.     game = zip(*[map(int, r) for r in game])
  103.     return Board(game)
  104.  
  105. BOARDS_BY_LEVEL = 1500
  106.  
  107. def bfs_win():
  108.     clicks = 0
  109.     prev = [get_board()]
  110.     while prev:
  111.         print "{} clicks, {} boards".format(clicks, len(prev))
  112.         if any(b.columns == tuple(tuple()) for b in prev):
  113.             gan = [b for b in prev if b.columns == tuple(tuple())][0]
  114.             gan.super_print()
  115.             print "WIN", clicks
  116.             break
  117.         clicks += 1
  118.         new_currs = []
  119.         cols = set()
  120.         for p in prev:
  121.             for b in p.iter_next_boards():
  122.                 if posible(b) and b.columns not in cols:
  123.                     new_currs.append(b)
  124.                     cols.add(b.columns)
  125.         prev = sorted(new_currs, key=lambda x: sum(len(c) for c in x.columns))[:BOARDS_BY_LEVEL]
  126.  
  127. if __name__ == "__main__":
  128.     bfs_win()
Advertisement
Add Comment
Please, Sign In to add comment