This is one of those unnecessarily cruel coding challenges that seems pretty straightforward, but requires a good deal of micro optimization to pass.
As mentioned in this answer, for starters, you shouldn't take the "drop" and "reverse" operations literally. Reversing a list is O(n), so in a worst-case scenario where you have a 100k element list and the operations are 100k of R
, you're doing 1010 steps that achieve nothing.
A better approach is to use a deque and a boolean. The deque has O(1) removal at either end, and the boolean flips back and forth between the front and back to determine which side to drop elements from. If we end with the list in a "reversed" state, print it reversed. Now we're down to linear time, but for Python, simple linear time isn't necessarily good enough, so we have to attack the constant factor.
My next attempt was to avoid the deque and instead focus on counting the number of elements I needed to remove on either end, then removing them all in one fell swoop with a slice. Separating the execution and analysis of the operations led to more optimizations. The order of the input for each test case is a good hint: we collect the operations, then the list size n
, then the list contents. Whenever there are more drops than items in the list, we can avoid parsing the list and print error
. If there are an equal number of drops as items in the list, we can print []
and again avoid parsing the list.
Tossing in these micro optimizations eventually allowed me to pass. Here's my solution:
from sys import stdin
def main():
for _ in range(int(next(stdin))):
forward = True
trim_from_front = 0
trim_from_rear = 0
for op in next(stdin):
if op == "R":
forward = not forward
elif op == "\n":
break
elif forward:
trim_from_front += 1
else:
trim_from_rear += 1
n = int(next(stdin))
if trim_from_front + trim_from_rear > n:
print("error")
next(stdin)
continue
elif trim_from_front + trim_from_rear == n:
print("[]")
next(stdin)
continue
x = next(stdin)[1:-2].split(",", n - trim_from_rear)
if trim_from_rear > 0:
x.pop()
if trim_from_front > 0:
x = x[trim_from_front:]
if not forward:
x = reversed(x)
print("[", ",".join(x), "]", sep="")
if __name__ == "__main__":
main()
See also: