Tuesday, October 8, 2019

UVa 10901 - Ferry Loading III

# UVa 10901 - Ferry Loading III

from collections import deque

def other(bank_name):
    if bank_name == 'left':
        return 'right'
    else:
        return 'left'

class Car:
    def __init__(self, arrival_time, arrival_bank):
        self.arrival_time = arrival_time
        self.arrival_bank = arrival_bank
        self.unload_time = 0
    def unload(self, time):
        self.unload_time = time

class Ferry:
    def __init__(self, ferry_capacity, crossing_time):
        self.ferry_capacity = ferry_capacity
        self.crossing_time = crossing_time
        self.bank = 'left'
        self.current_time = 0
        self.car_marker = 0
        self.cars_loaded = []
    
    def load(self, car):
        self.cars_loaded.append(car)
        
    def load_bank(self):
        while bank[self.bank] and len(self.cars_loaded) < self.ferry_capacity and bank[self.bank][0].arrival_time <= self.current_time:
            self.load(bank[self.bank].popleft())

    def switch_bank(self):
        self.bank = other(self.bank)
        self.current_time = self.current_time + self.crossing_time
        if self.cars_loaded:
            for loaded_car in self.cars_loaded:
                loaded_car.unload(self.current_time)
        self.cars_loaded = []

    def wait_for_next_car(self):
        if not bank['left'] and not bank['right']:
            return
        if not bank['right'] or (bank['left'] and bank['left'][0].arrival_time < bank['right'][0].arrival_time):
            next_car = bank['left'][0]
        else:
            next_car = bank['right'][0]
        self.current_time = next_car.arrival_time

    def run(self):
        self.current_time = 0        
        
        while bank['left'] or bank['right']:

            self.load_bank()
            if self.cars_loaded:
                self.switch_bank()
                continue
            
            if bank[other(self.bank)] and bank[other(self.bank)][0].arrival_time <= self.current_time:
                self.switch_bank()
                continue

            self.wait_for_next_car()

number_of_test_cases = int(input())
for test_case in range(1, number_of_test_cases+1):

    ferry_capacity, crossing_time, number_of_cars = map(int, input().split())
    
    cars = []
    bank = {'left': deque(), 'right': deque()}
    for i in range(number_of_cars):
        line = input().split()
        car_arrival_time = int(line[0])
        car_arrival_bank = line[1]
        car = Car(car_arrival_time, car_arrival_bank)
        bank[car.arrival_bank].append(car)
        cars.append(car)
                
    ferry = Ferry(ferry_capacity, crossing_time)
    ferry.run()

    for car in cars:
        print(f'{car.unload_time}')

No comments:

Post a Comment