I got stuck on an interview question that I couldn't quite figure out.
Prompt Summary:
You are debugging a program of "length" lines.
You have 2 arrays: actions, breakpoints
The actions array consists of two different values: "next" or "continue" The breakpoints array consists of line numbers aka where the next breakpoint is.
It's guaranteed that 1<= breakpoints[i] <= length.
If the value is "next", you go to the next line.
If the value is "continue":
- You go to the next breakpoint that is greater than the current line number.
- If there are no more breakpoints left and the action is continue, return the length.
line_number is initialized to 1, but if there are breakpoints in breakpoints, the line_number should be initialized to breakpoints[0]
When there are no more actions left to do, return the line_number you're at.
I've been trying to figure it out after the interview, here is what I have so far.
# Initialize line_number to 1
line_number = 1
# If there are no breakpoints or actions, return 1
if len(actions) == 0 and len(breakpoints) == 0:
return line_number
# If there are no actions, but there are breakpoints, return the first breakpoint
if len(actions) == 0 and len(breakpoints) > 0:
return breakpoints[0]
# If there are actions, but not breakpoints, make sure actions are all "next", else, return length
if len(actions) > 0 and len(breakpoints) == 0:
if "continue" in actions:
return length
else:
for i in actions:
if i == "next":
line_number = 1
return line_number
# If there are actions and breakpoints...
while (len(actions) > 0):
# If the line_number exceeds the length, return length
if line_number >= length:
return length
# While the action is "continue"...
while actions[0] == "continue":
# If the length of breakpoint is greater than 0
if len(breakpoints) == 0:
return length
# If the length of breakpoints is greater than 0...
if len(breakpoints) > 0:
# If the next breakpoint is greater than the line_number, then set line_number to the next breakpoint
if breakpoints[0] > line_number:
line_number = breakpoints[0]
breakpoints.pop(0)
actions.pop(0)
# If the next breakpoint is less than the line_number...
else:
# Pop until the next breakpoint is greater than the line_number or the length of breakpoints is 0.
while breakpoints[0] <= line_number:
if len(breakpoints) == 0:
return length
breakpoints.pop(0)
line_number = breakpoints[0]
breakpoints.pop(0)
actions.pop(0)
# If the action is "next", then set line_number to the next line
while actions[0] == "next":
line_number = 1
actions.pop(0)
return(line_number)
I was only able to pass about 70% of the test cases. This isn't exactly what I submitted, but somewhat close. If anybody could give me some advice about what I'm doing wrong or how to optimize it, that would be great. I originally just did two nested while loops inside a while loop. I was using i to increment actions, and j to increment breakpoints.
CodePudding user response:
Your code is too busy, and it seems to be hiding the fact that you missed a requirement. For starters, you have a bunch of edge checks at the start of your function, but they're not necessary.
This is a more compact version that (I think) accomplishes the goal. Its key differences are twofold:
- Initialize
line_number
tobreakpoints[0]
if it exists. - Only pop one action per loop. This makes it much easier to follow what's going on.
# Initialize line_number to 1 or breakpoints[0]
if len(breakpoints) > 0:
line_number = breakpoints[0]
# You could pop that first breakpoint here, since line_number only increases
# But it's not necessary because the while True loop catches it.
else:
line_number = 1
while len(actions) > 0:
if actions[0] == 'continue':
# Jump to the next largest breakpoint, if it exists
while True:
if len(breakpoints) == 0:
# We've run out of breakpoints, return length.
return length
# Store the breakpoint and pop it
nextBreakpoint = breakpoints[0]
breakpoints.pop(0)
# If the breakpoint is ahead of line_number, update line_number and stop looking.
if nextBreakpoint > line_number:
line_number = nextBreakpoint
break
if actions[0] == 'next':
line_number = 1
# Inside this loop, each iteration will remove exactly ONE action.
actions.pop(0)
# If the action resulted in a number too large, stop.
if line_number > length:
line_number = length
break
# Note that if there were no actions, we return 1 or breakpoint[0], as required.
return line_number