diff --git a/reborn.py b/reborn.py index 602883e..b1aa999 100755 --- a/reborn.py +++ b/reborn.py @@ -1,19 +1,32 @@ #!/usr/bin/env python3 import sys +import math +import copy + +outLines = [] + +def log(*data): + if True: + print(*data) + +def output(*values): + global outLines + outLines.append(' '.join([str(val) for val in values])) + +def distance(A, B): + return math.ceil(math.sqrt(pow(B[0] - A[0], 2) + pow(B[1] - A[1], 2))) class Product: ALL = [] def __init__(self, weight): + self.id = len(self.ALL) self.ALL.append(self) self.weight = weight - def weight(pid): - return __class__.ALL[pid].weight - def get(pid): return __class__.ALL[pid] @@ -25,6 +38,7 @@ class Warehouse: ALL = [] def __init__(self, pos, items): + self.id = len(self.ALL) self.ALL.append(self) self.pos = pos @@ -41,10 +55,14 @@ class Client: ALL = [] def __init__(self, pos, needs): + self.id = len(self.ALL) self.ALL.append(self) self.pos = pos - self.items = needs + self.needs = needs + + def satisfied(self): + return len(self.needs) == 0 def get(pid): return __class__.ALL[pid] @@ -58,6 +76,7 @@ class Drone: PAYLOAD = 0 def __init__(self): + self.id = len(self.ALL) self.ALL.append(self) self.pos = Warehouse.get(0).pos @@ -65,6 +84,66 @@ class Drone: self.avail = 0 self.tasks = [] + def weight(self): + s = 0 + for i in self.items: + s += Product.get(i).weight + return s + + def busyFor(self, time): + self.avail += time + assert(self.avail < T) + + def available(self): + return self.avail <= turn + + def load(self, warehouse, product, qt): + assert(self.available()) + if (self.pos != warehouse.pos): + self.busyFor(distance(self.pos, warehouse.pos)) + self.pos = warehouse.pos + for q in range(qt): + warehouse.items.remove(product.id) + self.items.append(product.id) + self.busyFor(1) + assert(self.weight() <= __class__.PAYLOAD) + log("Drone", self.id, "loads", qt, "of", product.id, "from warehouse", warehouse.id, "→", self.avail) + output(self.id, 'L', warehouse.id, product.id, qt) + + def unload(self, warehouse, product, qt): + assert(self.available()) + if (self.pos != warehouse.pos): + self.busyFor(distance(self.pos, warehouse.pos)) + self.pos = warehouse.pos + for q in range(qt): + self.items.remove(product.id) + warehouse.items.append(product.id) + self.busyFor(1) + log("Drone", self.id, "unloads", qt, "of", product.id, "to warehouse", warehouse.id, "→", self.avail) + output(self.id, 'U', warehouse.id, product.id, qt) + + def deliver(self, client, product, qt): + assert(self.available()) + if (self.pos != client.pos): + self.busyFor(distance(self.pos, client.pos)) + self.pos = client.pos + for q in range(qt): + self.items.remove(product.id) + client.needs.remove(product.id) + self.busyFor(1) + log("Drone", self.id, "delivers", qt, "of", product.id, "to client", client.id, "→", self.avail) + output(self.id, 'D', client.id, product.id, qt) + if client.satisfied(): + global score + score += math.ceil((T-(self.avail-1))/T*100) + log("Client", client.id, "satisfied!", "New score:", score) + + def wait(self, turns=1): + assert(self.available()) + self.busyFor(1) + log("Drone", self.id, "waits", turns, "turn" + ('s' if turns >= 2 else ''), "→", self.avail) + output(self.id, 'W', turns) + def get(pid): return __class__.ALL[pid] @@ -76,6 +155,9 @@ X = 0 # Nb rows Y = 0 # Nb columns T = 0 # Deadline +turn = 0 # Turn +score = 0 # Score + def readFile(filename): global X, Y, T @@ -85,7 +167,7 @@ def readFile(filename): # Products P = int(f.readline()) - weights = f.readline().split(' ') + weights = [int(i) for i in f.readline().split(' ')] assert(len(weights) == P) for w in weights: Product(w) @@ -119,3 +201,35 @@ def readFile(filename): Drone() readFile(sys.argv[1]) + +def newTurn(): + global turn + # Finishing turn + for drone in [drone for drone in Drone.ALL if drone.available()]: + drone.wait() + # New turn + turn += 1 + log("--- Turn", turn) + availableDrones = [str(drone.id) for drone in Drone.ALL if drone.available()] + log("Drones", ", ".join(availableDrones), "("+str(len(availableDrones))+")", "are available") + +try: + d = 0 + N = Client.get(0).needs.copy() + for n in N: + Drone.get(d).load(Warehouse.get(0), Product.get(n), 1) + d += 1 + newTurn() + d = 0 + for n in N: + Drone.get(d).deliver(Client.get(0), Product.get(Drone.get(d).items[0]), 1) + d += 1 + + +except KeyboardInterrupt: + pass + +with open(sys.argv[1] + 'o', 'w') as f: + f.write(str(len(outLines)) + '\n' + '\n'.join(outLines) + '\n') +print("Score:", score) +