| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- '''
- @author: olivier.massot, 2019
- '''
- import heapq
- import itertools
- import sys
- def log(x):
- print(x, file=sys.stderr)
- # Cells
- BLUEBERRIES_CRATE = "B"
- ICE_CREAM_CRATE = "I"
- WINDOW = "W"
- EMPTY_TABLE = "#"
- DISHWASHER = "D"
- FLOOR_CELL = "."
- # Items
- NONE = "NONE"
- DISH = "DISH"
- ICE_CREAM = "ICE_CREAM"
- BLUEBERRIES = "BLUEBERRIES"
- location = {DISH: DISHWASHER,
- ICE_CREAM: ICE_CREAM_CRATE,
- BLUEBERRIES: BLUEBERRIES_CRATE,
- WINDOW: WINDOW}
- class Base():
- def __repr__(self):
- return f"<{self.__class__.__name__}: {self.__dict__}>"
- class Customer(Base):
- def __init__(self, item, award):
- self.item = item
- self.award = int(award)
- class Cook(Base):
- def __init__(self, x, y, item):
-
- self.x = int(x)
- self.y = int(y)
- self.item = item
- self.order = ""
- @property
- def pos(self):
- return (self.x, self.y)
- def use(self, x, y, msg=""):
- print("USE", x, y, msg)
- def move(self, x, y):
- print("MOVE", x, y)
-
- class Table(Base):
- def __init__(self, x, y, item):
- self.x = int(x)
- self.y = int(y)
- self.item = item
-
- class Oven(Base):
- def __init__(self, contents, timer):
- self.contents = contents
- self.timer = int(timer)
- class NoPathFound(Exception):
- pass
- class PathNode(tuple):
- def __new__(self, x, y, parent=None):
- n = tuple.__new__(self, (x, y))
- n.parent = parent
- n.cost = 0
- return n
- class Grid(Base):
- def __init__(self, cells):
- self.cells = cells
- def at(self, x, y):
- return self.cells[y][x]
-
- def is_in(self, x, y):
- try:
- self.at(x, y)
- return True
- except IndexError:
- return False
- def flatten(self):
- return [(x, y, c) for y, row in enumerate(self.cells) for x, c in enumerate(row)]
-
- def where_are(self, content):
- return [(x, y) for x, y, c in self.flatten() if c == content]
-
- def is_passable(self, x, y):
- return self.at(x, y) in (FLOOR_CELL, "0", "1")
-
- def closest(self, from_, content):
- return min(self.where_are(content), key=lambda k: (abs(from_[0] - k[0]) + abs(from_[1] - k[1])))
- def neighbors(self, x, y):
- return [(xn, yn) for xn, yn in [(x - 1, y - 1), (x, y - 1), (x + 1, y - 1), \
- (x - 1, y), (x + 1, y) , \
- (x - 1, y + 1), (x, y + 1), (x + 1, y + 1)]
- if self.is_in(xn, yn)]
- def path_to(self, origin, target):
- nodes = []
- origin = PathNode(*origin)
-
- heapq.heappush(nodes, (0, origin))
- while nodes:
- current = heapq.heappop(nodes)[1]
- if current == target:
- break
- for x, y in self.neighbors(*current):
- node = PathNode(x, y, current)
- if not self.is_passable(*node):
- continue
- node.cost = current.cost + 1
- priority = node.cost + (abs(node[0] - target[0]) + abs(node[1] - target[1]))
- heapq.heappush(nodes, (priority, node))
- else:
- raise NoPathFound("no path were found to the targetted location {}".format(target))
- result = [target]
- while current != origin:
- result.append(tuple(current))
- current = current.parent
- result.append(origin)
- result.reverse()
- return result
- # input vars
- num_all_customers = int(input())
- all_customers = [Customer(*input().split()) for _ in range(num_all_customers)]
- grid = Grid([list(input()) for i in range(7)])
- log(f"{num_all_customers} customers: {all_customers}")
- log(f"grid: {grid}")
- while True:
- turns_remaining = int(input())
- player = Cook(*input().split())
- log(f"*** player: {player}")
-
- partner = Cook(*input().split())
- log(f"*** partner: {partner}")
-
- num_tables_with_items = int(input()) # the number of tables in the kitchen that currently hold an item
- tables = [Table(*input().split()) for _ in range(num_tables_with_items)]
- log(f"*** tables: {tables}")
-
- oven = Oven(*input().split())
- log(f"*** oven: {oven}")
-
- num_customers = int(input()) # the number of customers currently waiting for food
- customers = [Customer(*input().split()) for _ in range(num_customers)]
- log(f"*** customers: {customers}")
-
- ### SCRIPT
-
- # if no current order, take the most beneficial
- if not player.order:
- queue = sorted(customers, reverse=True, key=lambda x: x.award)
- # what is my partner doing?
- player.order = queue[0].item
- log(f'>>> new order taken: {player.order}')
-
- todo = player.order.split('-')
- log(f"todo: {todo}")
-
- next_task = next([t for t in todo if not t in player.item], WINDOW)
- if next_task == WINDOW:
- player.order, todo = [], []
- log(f"next_task: {next_task}")
-
- target = location[next_task]
- log(f"target: {target}")
-
- closest = grid.closest(player.pos, target)
- log(f"closest: {closest}")
-
- player.use(*closest)
|