oleh_korkh

Labyrinth

Feb 8th, 2018 (edited)
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.72 KB | None | 0 0
  1. class Labyrinth:
  2.     def __init__(self, configuration):
  3.         self.configuration = [x.strip() for x in configuration]
  4.         self.walls = []
  5.         self.entry = None
  6.         self.exits = []
  7.         for y, row in enumerate(self.configuration):
  8.             for x, ch in enumerate(row):
  9.                 if ch == '#':
  10.                     self.walls.append((x, y))
  11.                 elif ch == '@':
  12.                     self.entry = (x, y)
  13.                 elif ch == '$':
  14.                     self.exits.append((x, y))
  15.         self.height = len(self.configuration)
  16.         self.width = len(self.configuration[0])
  17.         self.walls.append(self.entry)
  18.         self.path = []
  19.         self.pathes = []
  20.  
  21.     def get_directions(self, position, ignore=None):
  22.         if ignore is None:
  23.             ignore = []
  24.  
  25.         x, y = position
  26.         directions = []
  27.         if x > 0 and (x-1, y) not in self.walls and (x-1, y) not in ignore:
  28.             directions.append((x-1, y))
  29.         if y > 0 and (x, y-1) not in self.walls and (x, y-1) not in ignore:
  30.             directions.append((x, y-1))
  31.         if x < self.width-1 and (x+1, y) not in self.walls and (x+1, y) not in ignore:
  32.             directions.append((x+1, y))
  33.         if y < self.height-1 and (x, y+1) not in self.walls and (x, y+1) not in ignore:
  34.             directions.append((x, y+1))
  35.         return directions
  36.  
  37.     def has_exit(self, path):
  38.         for exit in self.exits:
  39.             if exit in path:
  40.                 return exit
  41.  
  42.     def move(self, start, ignore=None):
  43.         if ignore is None:
  44.             ignore = []
  45.  
  46.         if start not in ignore:
  47.             ignore = ignore + [start]
  48.             directions = self.get_directions(start, ignore)
  49.             if directions:
  50.                 exit = self.has_exit(directions)
  51.                 if exit:
  52.                     return [start, exit]
  53.  
  54.                 # print('>>', directions)
  55.                 result = []
  56.                 # print('|', start, '->', directions)
  57.                 for direction in directions:
  58.                     path = self.move(direction, ignore)
  59.                     # print(':', direction, '->', path)
  60.                     if path:
  61.                         if len(directions) == 1:
  62.                             return [start] + path
  63.                         else:
  64.                             result.append([start]+path)
  65.                 # print('|', result)
  66.                 return result or None
  67.             else:
  68.                 return [start]
  69.  
  70.     def decode_path(self, seq, initial=None):
  71.         initial = initial or []
  72.         result = initial[:]
  73.         for x in seq:
  74.             if type(x) is not list:
  75.                 result.append(x)
  76.             else:
  77.                 self.pathes.append(self.decode_path(x, initial=result))
  78.         return result
  79.  
  80.     def build_path(self):
  81.         import pprint
  82.         self.path = labyrinth.move(self.entry)
  83.         # pprint.pprint(self.path)
  84.         print('---')
  85.         self.decode_path(self.path)
  86.  
  87.     def draw_all(self):
  88.         [
  89.             self.draw(x)
  90.             for x in sorted(self.pathes, key=lambda t:len(t))
  91.             if self.has_exit(x)]
  92.  
  93.     def draw(self, path):
  94.         print('Path length:', len(path))
  95.         for x in range(len(self.configuration[0])):
  96.             print('%1x' % x, end='')
  97.         print()
  98.  
  99.         for y, row in enumerate(self.configuration):
  100.             for x, ch in enumerate(row):
  101.                 print('*' if (x, y) in path else ch, end='')
  102.             print(' %d' % y)
  103.  
  104.  
  105. with open('input.txt', 'r') as f:
  106.     labyrinth = Labyrinth(f.readlines())
  107.     labyrinth.build_path()
  108.     if labyrinth.path:
  109.         labyrinth.draw_all()
  110.     else:
  111.         print('No exit!')
  112.     # print(labyrinth.path)
Add Comment
Please, Sign In to add comment