UBS-Server / routes /parkinglot.py
m-abdur2024's picture
Upload 40 files
0d3476b verified
raw
history blame contribute delete
No virus
10.6 kB
from flask import request, jsonify
import logging
from routes import app
import re
from collections import deque
logger = logging.getLogger(__name__)
from copy import deepcopy
import sys
import threading
# Set recursion limit higher to prevent maximum recursion depth exceeded error
sys.setrecursionlimit(100000)
from flask import Flask, request, jsonify
from copy import deepcopy
import sys
import threading
from collections import deque
# Set recursion limit higher to prevent maximum recursion depth exceeded error
sys.setrecursionlimit(100000)
@app.route('/parkinglot', methods=['POST'])
def parking_lot():
test_cases = request.get_json()
responses = []
for test_case in test_cases:
response = process_test_case(test_case)
responses.append(response)
return jsonify(responses)
def process_test_case(test_case):
minimum_total_fare = test_case["minimumTotalFare"]
vehicles_info = {v["plateNumber"]: v for v in test_case["vehicles"]}
actions = test_case["actions"]
parking_lot = test_case["parkingLot"]
# Initialize parking lot state
parking_lot_state = ParkingLot(parking_lot)
# Keep track of parked vehicles and their positions
parked_vehicles = {}
total_fare_collected = 0
# Prepare the response actions
response_actions = []
# Sort vehicles by parking fare descending to prioritize higher fares
vehicles_by_fare = sorted(vehicles_info.values(), key=lambda v: -v["parkingFare"])
vehicles_parked = set()
for action in actions:
plate_number = action["plateNumber"]
vehicle_action = action["action"]
vehicle_info = vehicles_info[plate_number]
if vehicle_action == "park":
# If we need more fare, try to park the vehicle
if total_fare_collected < minimum_total_fare:
if plate_number not in vehicles_parked:
# Try to find a parking position
position = parking_lot_state.find_parking_position(vehicle_info)
if position:
# Park the vehicle
parking_lot_state.place_vehicle(vehicle_info, position)
parked_vehicles[plate_number] = (vehicle_info, position)
vehicles_parked.add(plate_number)
response_actions.append({
"plateNumber": plate_number,
"action": "park",
"execute": True,
"position": {
"x": position.x,
"y": position.y,
"direction": position.direction
}
})
else:
# Cannot park the vehicle
response_actions.append({
"plateNumber": plate_number,
"action": "park",
"execute": False,
"position": None
})
else:
# Vehicle already parked
response_actions.append({
"plateNumber": plate_number,
"action": "park",
"execute": False,
"position": None
})
else:
# Already met minimum fare, skip parking
response_actions.append({
"plateNumber": plate_number,
"action": "park",
"execute": False,
"position": None
})
elif vehicle_action == "exit":
if plate_number in parked_vehicles:
vehicle_info, position = parked_vehicles[plate_number]
# Try to find a path to exit
can_exit = parking_lot_state.can_exit_vehicle(vehicle_info, position)
if can_exit:
# Remove the vehicle
parking_lot_state.remove_vehicle(vehicle_info, position)
total_fare_collected += vehicle_info["parkingFare"]
del parked_vehicles[plate_number]
response_actions.append({
"plateNumber": plate_number,
"action": "exit",
"execute": True,
"position": {
"x": position.x,
"y": position.y,
"direction": position.direction
}
})
else:
# Cannot exit the vehicle
response_actions.append({
"plateNumber": plate_number,
"action": "exit",
"execute": False,
"position": None
})
else:
# Vehicle is not parked
response_actions.append({
"plateNumber": plate_number,
"action": "exit",
"execute": False,
"position": None
})
else:
# Unknown action, skip
response_actions.append({
"plateNumber": plate_number,
"action": vehicle_action,
"execute": False,
"position": None
})
return {
"actions": response_actions
}
class ParkingLot:
def __init__(self, parking_lot_map):
self.map = parking_lot_map
self.height = len(parking_lot_map)
self.width = len(parking_lot_map[0]) if self.height > 0 else 0
self.walls = set()
self.entrances = set()
self.exits = set()
self.occupied = set()
# Parse the parking lot map
for y in range(self.height):
for x in range(self.width):
cell = parking_lot_map[y][x]
if cell == 'X':
self.walls.add((x, y))
elif cell == 'I':
self.entrances.add((x, y))
elif cell == 'O':
self.exits.add((x, y))
# Initialize occupied cells (walls, entrances, exits)
if cell != ' ':
self.occupied.add((x, y))
def find_parking_position(self, vehicle_info):
# Try to find a valid parking position adjacent to an entrance
for entrance in self.entrances:
ex, ey = entrance
possible_directions = []
if ex == 0:
possible_directions.append('EAST')
if ey == 0:
possible_directions.append('SOUTH')
for direction in possible_directions:
dx, dy = self.direction_to_delta(direction)
for step in range(1, max(self.width, self.height)):
nx, ny = ex + dx * step, ey + dy * step
position = Position(nx, ny, direction)
if self.is_valid_parking_position(vehicle_info, position):
return position
return None
def is_valid_parking_position(self, vehicle_info, position):
occupied_cells = self.get_vehicle_cells(vehicle_info, position)
# Cannot park on walls, entrances, exits, or occupied cells
for cell in occupied_cells:
if cell in self.walls or cell in self.occupied or cell in self.entrances or cell in self.exits:
return False
# Check boundaries
for cell in occupied_cells:
if not (0 <= cell[0] < self.width and 0 <= cell[1] < self.height):
return False
return True
def get_vehicle_cells(self, vehicle_info, position):
length = vehicle_info["length"]
width = vehicle_info["width"]
x = position.x
y = position.y
direction = position.direction
cells = []
if direction == 'NORTH':
for dx in range(width):
for dy in range(length):
cells.append((x + dx, y - dy))
elif direction == 'SOUTH':
for dx in range(width):
for dy in range(length):
cells.append((x + dx, y + dy))
elif direction == 'EAST':
for dx in range(length):
for dy in range(width):
cells.append((x + dx, y + dy))
elif direction == 'WEST':
for dx in range(length):
for dy in range(width):
cells.append((x - dx, y + dy))
return cells
def place_vehicle(self, vehicle_info, position):
occupied_cells = self.get_vehicle_cells(vehicle_info, position)
for cell in occupied_cells:
self.occupied.add(cell)
def remove_vehicle(self, vehicle_info, position):
occupied_cells = self.get_vehicle_cells(vehicle_info, position)
for cell in occupied_cells:
if cell in self.occupied:
self.occupied.remove(cell)
def can_exit_vehicle(self, vehicle_info, position):
# Check if vehicle can exit directly from its position without collisions
possible_directions = []
if position.x + vehicle_info["length"] <= self.width - 1:
possible_directions.append('EAST')
if position.y + vehicle_info["length"] <= self.height - 1:
possible_directions.append('SOUTH')
for exit_point in self.exits:
ex, ey = exit_point
if position.direction == 'EAST' and ex == self.width - 1:
return True
if position.direction == 'SOUTH' and ey == self.height - 1:
return True
return False
def direction_to_delta(self, direction):
if direction == 'NORTH':
return (0, -1)
elif direction == 'SOUTH':
return (0, 1)
elif direction == 'EAST':
return (1, 0)
elif direction == 'WEST':
return (-1, 0)
class Position:
def __init__(self, x, y, direction):
self.x = x
self.y = y
self.direction = direction