Блог пользователя Moody_in_a_hoodie

Автор Moody_in_a_hoodie, история, 4 года назад, По-английски

for context: problem link :link

my solution :link

Got RE in 35th case the python AC submissions for this problem are executed using bfs. I looked at some AC submissions in c++. looks like the logic is same. So the problem I guess is with python.

lets say I avoid recursive implementation and go for iterative ones..for example Bfs over dfs. but is it even possible in all cases? And also if you can provide a feasible way to execute deep recursions without runtime error I will be extremely grateful.

Please don't suggest to learn C++ right now. I know it is a great language. But I just can't afford the time now. I am currently working on learning new skills that will help me in web dev. I hope you understand my position.

  • Проголосовать: нравится
  • +16
  • Проголосовать: не нравится

»
4 года назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится

Yes, there is a way to use recursions in python without stack overflow. Put below snippet in your code and then put @bootstrap over recursive function. And replace instances of return with yield. (Credit goes to pajenegod)

Spoiler
  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    It was accepted in no time. thank you!! But i also needed do a slight modification. ~~~~~

    def dfs(node,m):
        visited[node]=1
        if a[node-1]==1:
            m=m+1
        else:
            m=0
        if m>k:
            yield 0
        for v in g[node]:
            if visited[v]!=1:
                yield dfs(v,m) #it was just dfs(v,m) before
        if node in leaf:
            leaf[node]=1
        yield 1
    

    ~~~~~ without the modification yield was stopping the complete process if it was hitting the leaf node. So now it works. But the same modification if i do on a normal recursion the program is giving WA even for smaller values. I think it has to do something with being stackless. I am keeping this here just so that everyone keeps in mind some slight changes may be needed to be done if you use this version. Thanks again though. :) i am gonna use this code from now on.

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Yes, you are right you have to use yield for accepting results from recursion call also. You can refer to examples in the below comment.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I'm trying to get this to work but can't seem to, trying to make it work with some very simple recursive functions and I just get errors. The following code gives me TypeError: unsupported operand type(s) for +: 'generator' and 'generator' on both python 2 and 3:

    fibonacci recursive function

    An even more trivial function that dodges the above error will still error out with File "main.py", line 18, in wrappedfunc to = stack[-1].send(to):

    trivial recursive function

    Is there something obvious I'm missing?

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Actually you have to use yield for accepting results from the recursive call as well for returning the value also. It will be more clear from these examples.

      Example 1
      Example 2
»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Note that tail call optimization doesn't work in Python.

»
4 года назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Here is a version of your solution getting Accepted: 86938135

The solution is wrapped into a function.
This function is run in a new thread.
Before that, the stack limit for new threads is updated.

The trick of starting a new thread to control the stack size in the contests is old.
I first saw it used for Java some time around 2010.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +7 Проголосовать: не нравится

    Wow that's really simple and clever!!

    I am so glad I asked this question here. somehow when I searched it on google all answers were like switch to c++ or set recursion limit. But now when I dig deeper specially in codeforces blogs I found the topic of threading mentioned but very vague. All this blogs were about getting stuck on a specific problem statement. So I did not click on it before.

    its sad that even it is an old trick its not very well known as no blog/resource actually exists dedicated to this topic. Thank you so much for answering :)

  • »
    »
    21 месяц назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    This code gives Memory limit exceeded in pypy3. You have any trick for pypy3?

  • »
    »
    5 месяцев назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    how can I use this for multiple test cases? I have no idea about threading and how it works. I am very new at this

    • »
      »
      »
      5 месяцев назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Perhaps you want to create a thread once, then solve the problem inside (one test case or many test cases, does not matter).