Skip to content

Instantly share code, notes, and snippets.

@pmusa
Created March 13, 2024 14:12
Show Gist options
  • Save pmusa/818b05fa1755278385cb96a6a5584b65 to your computer and use it in GitHub Desktop.
Save pmusa/818b05fa1755278385cb96a6a5584b65 to your computer and use it in GitHub Desktop.
valencia_dev_dive_robot.py
import sys
import math
class Robot:
MAX_FUEL = 200
BASE_X = 0
BASE_Y = 0
BASE = (BASE_X, BASE_Y)
CAR_WEIGHT = 5
SAMPLE_WEIGHT = 10
MAX_X = 40
MIN_X = -40
MAX_Y = 40
MIN_Y = -40
def __init__(self):
self.x = Robot.BASE_X
self.y = Robot.BASE_Y
self.fuel = Robot.MAX_FUEL
self.weight = Robot.CAR_WEIGHT
self.samples = 0
self.total_samples = 0
def move(self, destination):
dest_x, dest_y = destination
dx = dest_x - self.x
dy = dest_y - self.y
if not Robot.is_valid_destination(dest_x, dest_y):
print("Invalid destination. Skipping...")
return
dist_to_dest = abs(dx) + abs(dy)
fuel_to_dest = dist_to_dest * self.get_fuel_per_move()
# distance to base from the next destination
dist_to_base = abs(dest_x) + abs(dest_y)
fuel_to_base = dist_to_base * self.get_fuel_per_move(1)
self.print_status(fuel_to_dest + fuel_to_base)
if fuel_to_dest + fuel_to_base > self.fuel:
if self.x == Robot.BASE_X and self.y == Robot.BASE_Y:
print("Error: will run out of Fuel.")
return
print("Fuel is not sufficient. Returning to base to refuel...")
self.move(Robot.BASE)
self.refill()
print(f"Refueled. Resuming mission to coordinates x={dest_x};y={dest_y}")
self.move(destination)
else:
while dx != 0 or dy != 0:
if dx != 0:
self.x += int(math.copysign(1, dx))
dx -= math.copysign(1, dx)
elif dy != 0:
self.y += int(math.copysign(1, dy))
dy -= math.copysign(1, dy)
self.consume_fuel()
print(f'>{self.x};{self.y}')
def is_valid_destination(x, y):
return x >= Robot.MIN_X and x <= Robot.MAX_X and y >= Robot.MIN_Y and y <= Robot.MAX_Y
def get_fuel_per_move(self, extra_samples=0):
if not extra_samples:
extra_samples = 0
return math.log10(self.weight + (extra_samples * Robot.SAMPLE_WEIGHT))
def consume_fuel(self):
self.fuel -= self.get_fuel_per_move()
def print_status(self, fuel_needed):
print(f'Current location is x={self.x} y={self.y}')
print(f'Samples [total:{self.total_samples} current:{self.samples}] Weight:{self.weight}')
print(f'Fuel: {self.fuel} - Total fuel needed: {fuel_needed}')
def refill(self):
self.drop_samples()
self.fuel = Robot.MAX_FUEL
def collect_sample(self):
self.samples += 1
self.total_samples += 1
self.weight += Robot.SAMPLE_WEIGHT
def drop_samples(self):
print(f'Dropping {self.samples} sample(s).')
self.samples = 0
self.weight = Robot.CAR_WEIGHT
def run_sequence(self, sequence):
destinations = sequence.split(">")
destinations.pop(0) # skip the first empty match.
print(f"Starting Delivery to {destinations}")
for dest_str in destinations:
x, y = map(int, dest_str.split(";"))
print("---------")
print(f"Going to coordinates x={x};y={y}")
self.move((x, y))
if self.x == x and self.y == y:
self.collect_sample()
print(f"Sample collected! New weight: {self.weight}")
print("All destinations reached!")
print("Returning to base...")
self.move(Robot.BASE)
print("Returned to base. Dropping samples...")
self.drop_samples()
print("Samples dropped. Mission complete!")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 robot.py <sequence>")
sys.exit(1)
sequence = sys.argv[1]
robot = Robot()
robot.run_sequence(sequence)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment