Reborn: Functionnal
This commit is contained in:
parent
ab2d199d04
commit
db9496f4b1
124
reborn.py
124
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)
|
||||
|
||||
|
|
Reference in a new issue