Code challenge: Can the guards of the stadium guard all gates

Question:

I am looking at this code challenge:

There are 26 Gates enumerated with the uppercase English alphabet from A to Z. The door of each gate is opened right before the first person enters and closed right after the arrival of the last guest that should enter through this gate. No two guests can enter the stadium simultaneously. For a gate to be properly checked, a security guard should be assigned to it. There are ‘k’ such guards in the stadium, so if there are more than ‘k’ gates opened, one of them is going to be left unguarded. Note that a guard can’t leave his post until the gate he is guarding is closed. Can we check if there was a moment when more than ‘k’ doors were opened? From the barcode scanning, we know the order in which the people having tickets entered.

Input:

  • No of people = 5
  • No of guards (k) = 1
  • Gate used by ith guest: AABBB

Output: NO

Input:

  • No of people = 5
  • No of guards (k) = 1
  • Gate used by ith guest: ABABB

Output: YES

I tried using deque to store the incoming alphabet is different from the previous alphabet and pop until the same alphabet is repeated. Not giving desired output. This is the code I tried:

from collections import deque
def solve(people, k, gate):
    stack = deque()  # Stack to track opened gates
    counter = 0  # Counter for opened gates
    for gate in gate_usage:
        if len(stack) == 0 or stack[-1] == gate:
            stack.append(gate)
        else:
            while len(stack) > 0 and stack[-1] != gate:
                stack.pop()
                counter += 1
                if counter > k:
                    return "NO"
    return "YES"


no_of_people = 5
k = 1
gate_usage = "ABABB"

print(solve(no_of_people, k, gate_usage))
Asked By: Shailaputri

||

Answers:

A solution is to gather for each gate which is its first use and its last use (the index in the input string is the time dimension). Then iterate the time points in order and when that time has a first use of a gate, decrease (the available guards), and when that time has a last use of a gate, increase . If ever becomes negative we have an overrun and should return "YES".

Implementation:

def solve(k, gate_usage):
    last = { gate: time 
                for time, gate in enumerate(gate_usage)
           }
    first = { gate: time 
                for time, gate in reversed(list(enumerate(gate_usage)))
            }
        
    for time, gate in enumerate(gate_usage):
        if time == first[gate]:
            k -= 1
            if k < 0:
                return "YES"
        if time == last[gate]:
            k += 1
            
    return "NO"

# Example runs
print(solve(2, "EAEBACDBDB"))  # NO
print(solve(2, "EAEBADCBDB"))  # YES
Answered By: trincot
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.