If I put just only the title of today's challenge here, you might say, "Nah!! it shouldn't be considered as a challenge; it's so easy," but don't let the title trick you cause that's what it does to me.

The title of the problem was "print in order" when I saw it, I was like, "what the hell?!" but when I read the description, I was like, "Ohhh! that shit! 😲😲😲".

Here is the thing, I got many chances to learn about Event-Driven programming, and every time I didn't put much of my focus into it cause I thought it was useless. However, if you really think about it, it's the most crucial skill you need in today's world because there are so many interactions with calling APIs, accessing data from somewhere, and so forth. Long story short, today's challenge made me return to my old study materials and notes and do lots of Googling. I am happy that it made me revise my resources.

Let me stop talking and give you the problem and my solution.

The Problem

Suppose we have a class:

public class Foo {
  public void first() { print("first"); }
  public void second() { print("second"); }
  public void third() { print("third"); }

The same instance of Foo will be passed to three different threads. Thread A will call first(), thread B will call second(), and thread C will call third(). Design a mechanism and modify the program to ensure that second() is executed after first(), and third() is executed after second().

Note: We do not know how the threads will be scheduled in the operating system, even though the numbers in the input seem to imply the ordering. The input format you see is mainly to ensure our tests' comprehensiveness.

You can find the problem and all the descriptions here.

The Solution

At the first trial, I wasn't thinking about events; what I did was the stupidest solution. I initiated an attribute called state with the value of 1; then I increment it by one at the end of the first and second methods. The reason I did that was, at the first line of each function, I will check if the state is the correct one; if yes, the function will execute; if not, I will return.

The idea is excellent, but I forgot that when I return a function, I am telling the thread that the function is done executing, which means I am not giving him any chance to call it again. I had to think about how to make a function wait; I realized that I could use the sleep function from the time module.

The next problem was finding the right amount of time to make the execution faster. I tried giving a deficient number of seconds like 0.000001, considering it will make the execution faster. The problem with such a number is that since the sleep time is so small, the thread will end up calling the function over and over again within a short period, leading to a massive increase in execution time. After a lot of trials, I found out 0.1 seconds work best.

The result

Runtime: 80 ms, faster than 68.26% of Python3 online submissions for Print in Order.

Memory Usage: 14.5 MB, less than 55.81% of Python3 online submissions for Print in Order.