Speeding Ticket

December 2015 Bronze - Problem 2: speeding

Algorithm

For each "event" (every time Bessie's speed changes or the speed limit changes), we calculate how much far past the speed limit Bessie is going. Take the maximum difference.

Python

def run(bessie,speedlimit):
    # Combine "speedlimit" and "bessie" events into one "events" list
    # Format: [time,speed,type] -> type 0 = limit, type 1 = bessie
    events = []
    time = 0
    print(bessie)
    print(speedlimit)
    for i in range(len(bessie)):
        events.append([time,bessie[i][1],1])
        time += bessie[i][0]
    time = 0
    for i in range(len(speedlimit)):
        events.append([time,speedlimit[i][1],0])
        time += speedlimit[i][0]
    events.sort(key=lambda i:-i[2]) # Bessie before SpeedLimit to make things easier
    events.sort(key=lambda i:i[0]) # Sort by time
    print(events)
    # Run through all events to determine maximum speed overrun
    record = 0
    limit = float('inf') # Current speed limit
    speed = 0 # Speed of Bessie
    for i in range(len(events)):
        event = events[i]
        if event[2] == 0: limit = event[1]
        if event[2] == 1:
            speed = event[1]
            # If the limit changes at the same time as Bessie, then skip this event
            if i+1 < len(events) and events[i+1][0] == event[0]: 
                continue
        record = max(record,speed-limit)
        print(record)
    return record

def main():
    # Read input
    with open('speeding.in','r') as fIn:
        f = fIn.read().split('\n')
        n,m = map(int,f[0].split())
        speedlimit = list(map(lambda i:list(map(int,i.split())),f[1:n+1])) # Sorry
        bessie = list(map(lambda i:list(map(int,i.split())),f[n+1:n+m+1])) # Every entry represents one Bessie change. Format: [length,speed]
    record = run(bessie,speedlimit)
    # Write output
    with open('speeding.out','w') as fOut:
        fOut.write(str(record)+'\n')

if __name__ == '__main__': main()