A bit of trivia - the Python recursion limit is actually artificially implemented to prevent bad coding practice and on it's own doesn't cause a stack overflow. Lets say we run this code: def foo(x): foo(x) foo(3) It will give us a recursion error after running around 1000 times (Pythons built in recursion limit). Now try this: import sys sys.setrecursionlimit(100000) def foo(x): foo(x) foo(3) Instead of a recursion error, this one runs a bit longer until it returns a SegmentationFault (core dumped) error. This is all because Pythons recursion limit of roughly 1000 doesn't cause a stack overflow and is only implemented to prevent bad coding practice, using sys module you can make the limit much higher until you cause an actual stack overflow (the SegmentationFault).
@Z0mbieAnt5 жыл бұрын
Yeah he doesn't seem to be too knowledgeable in python all together. If you want to put variables into a string you don't need the .format. Just put an f in front and enter the variable names into the curly braces. Makes the code way more readable. f'Move the disk from {f} to {t}!' (That is python 3.6 and up, but why would you teach your students anything else?) His if/pass/else is just absolutely terrible coding style. Just go if/return and keep your code flat.
@SergeMatveenko5 жыл бұрын
Well, this is video about recursion and the stack, but not about Python's implementation details, right?
@SergeMatveenko5 жыл бұрын
@@Z0mbieAnt Let me assure you that professor Altenkirch is aware of a lot of things in programming.
@Z0mbieAnt5 жыл бұрын
@@SergeMatveenko Oh I'm absolutely sure he is. He wouldn't be in that position if he wasn't. I'm mostly complaining about style issues, which are usually only relevant on bigger projects and teams. I might have been too rash in calling him out there.
@bytefu5 жыл бұрын
@@Z0mbieAnt He probably doesn't use format strings, because then he would have to explain them to those who don't know Python well. Everyone gets method calls. Early returns make sense in relatively long functions (which you shouldn't write), where the rest of the code is noticeably longer than the conditional return, so it makes sense to separate the "real work" from the handling of edge cases. I prefer short functions and the style he used, because it is explicit and because it is an expression rather than a statement. Also an early return does not make code "flatter", because now the return and the rest of the code have different indentation level. And you definitely should not be that concerned about "flatness" of your code if it's only 6 lines long anyway. You're thinking too hard about this, while also not paying enough attention to details. That's a suboptimal way to reason about code.
@mateja1765 жыл бұрын
"It's like a super power, ja?". It's always nice to hear that.
@willd0g5 жыл бұрын
Mateja Petrovic i came to the comments for this and the clever title associated with it!
@robertpeng56325 жыл бұрын
Resembalance of Einstein
@tabaks5 жыл бұрын
Op trt, gevezn zajn.
@billoddy56375 жыл бұрын
Wehrner von Braun
@theepicguy65754 жыл бұрын
I sense Assassins creed black flag
@wellreadbull37405 жыл бұрын
The skills, the looks, the accent... Prime movie villain material!
@videobenny35 жыл бұрын
I love listening to the professor!
@vojtechstrnad15 жыл бұрын
He reminds me of Javier Bardem in Skyfall.
@YouGuysAreAHoles5 жыл бұрын
The shirt: Prime grandmother material.
@Ayyy-lmao5 жыл бұрын
If you cant program the hanoi puzzle the laser moves 5 inches per minute!
@KurtRichterCISSP5 жыл бұрын
He doesn't have to be a bad guy. He can be Laszlo in Real Genius 2
@SergeMatveenko5 жыл бұрын
In order to understand recursion you need to understand recursion.
@callofdutymuhammad5 жыл бұрын
Overused.
@fnorgen5 жыл бұрын
I hate it when I get stuck in a why-loop.
@klaxoncow5 жыл бұрын
No. In order to understand recursion, you need to understand recursion, unless you already do, in which case do nothing. Don't forget the exit clause! ;D
@unclvinny5 жыл бұрын
@@klaxoncow Now I'm stuck doing nothing for the rest of my life. Perfect!
@schifoso5 жыл бұрын
If you think you understand recursion, you don't.
@davidkim20164 жыл бұрын
i love how everyone on Computerphile has a great sense of humor and they're charismatic as well
@isaactfa5 жыл бұрын
It kills me that he'll put a space before a colon, but not around operators or after commas.
@learnbytrying5 жыл бұрын
Absolutely barbaric
@tamasgal_com5 жыл бұрын
Yeah, Jupyter needs a PEP 8 linter... And also one for Julia ;)
@ori615115 жыл бұрын
PEP -8
@unclvinny5 жыл бұрын
Quoting Conrad: "The horror! ..... the horror!"
@iliakorvigo73415 жыл бұрын
@@tamasgal_com Jupyter would really benefit from a built-in static analyser. Unfortunately, I don't see it happening any time soon.
@amauta54 жыл бұрын
This video made me learn Python. Today, I have built a specific calculator for work and a document generator, albeit simple. Thank you. I still feel i know very little, but i am looking forward to continue learning.
@maaikevreugdemaker921028 күн бұрын
How's it going after 4y?
@amauta528 күн бұрын
@maaikevreugdemaker9210 Continued doing small projects for work. Dipped toes in javascript. now with Chagpt and AI i can get base code for simple tasks, i would say that i can do more, but i feel i learned less.
@jellevanbrandt53405 жыл бұрын
I do not understand anything, but I was satisfied when he moved the last disc from B to C.
@hammerjoe20083 жыл бұрын
The thing to understand how this works is that the code is not telling you what the size of the disc is. Its simply telling you to move the disc on A to C and so on. Because to solve this puzzle its simply a repetitive pattern (its always the same moves) the recursion works. Also note that the code starts at the bottom and recurses up, meaning that N=4 in reality is the bottom piece and not the top ond.
@mlguy83765 жыл бұрын
"I will leave the robotic arm as an exercise"
@KieranShort5 жыл бұрын
@MichaelKingsfordGray lol
@fathifathi87505 жыл бұрын
XDDD 😂😂😂😂
@afoiheagadwade20095 жыл бұрын
>every teacher ever
@egg54744 жыл бұрын
STEM Professors in a nutshell :
@Larbydarg5 жыл бұрын
Recursion is a magic spell and stack space is its mana.
@henrydorsett60765 жыл бұрын
Nice. This analogy will get used when teaching. :)
@jacobrose96065 жыл бұрын
and you're a wizard
@giannotti77775 жыл бұрын
1:09 Of course, Prof. Altenkirch brushed up on his game beforehand with "Conceptual Programming with Python" (by Thorsten Altenkirch) XD
I bet he prepared for writing the book by reading "Conceptual Programming with Python" (by Thorsten Altenkirch)
@pmcate25 жыл бұрын
This seems so magical! In every introduction to this game it is made clear that you cannot put a smaller disc on a larger one. But here we have no explicit mention of that!
@caw25sha5 жыл бұрын
I once found a recursive function call in an exception handler in C#. In the catch it waited 5 seconds and then called the same function again with the same arguments. Genius!
@softwaretechnologyengineering5 жыл бұрын
If at first you don't succeed...
@BlockOfRed5 жыл бұрын
I've done something like this one time (without a sleep)… It caused my program to send roughly 10000 mails to a colleague… 😂
@matteopascoli5 жыл бұрын
caw25sha : maybe in python 4 they will add the try:except:retry construct 😈
@BlockOfRed5 жыл бұрын
@@matteopascoli Retry until it works: for i in …: while True: try: # Do something… except: continue break
@matteopascoli5 жыл бұрын
@@BlockOfRed : retry n times: for i in reversed(range(n)): try: foo() bar() baz() break except: if i == 0: raise but the retry construct would not repeat foo() if bar() raised ;)
@b4ux1t3-tech5 жыл бұрын
I am disappointed with the lack of f-strings! In all seriousness, always love seeing Prof Altenkirch! Excellent, simple video illustrating a powerful tool.
@crashbunks5 жыл бұрын
I know right! My friend was using .format() in his project and when I tried to make it an f-string he looked so confused haha
@GuilhermeDiGiorgi3 жыл бұрын
At first I was using "yada yada" + str(variable) + "yada yada" logic, then I learn to use .format, and of last month and so, I am getting used to f-strings, it's very satisfying to get to know better techniques over time.
@CatzHoek5 жыл бұрын
I'm not going to read all comments but i just want to make sure you guys appreciate his shirt. It's absolutely marvellous. And this absolutely dry german manner when he delivered the jupiter joke, i love it.
@mohammedsharikuzama55185 жыл бұрын
This was soooooooo supercool! My professor just copied the code and explained. Now, I understand the power. And, I really love his carefree nature and his accent.
@hoplahey5 жыл бұрын
I have used recursion two times in my programming life. Once when I learned recursion using the tower of hanoi example in class. The second when I wrote my thesis, and in the x-reference section I wrote; Recursion, see Recursion.
@tmcode20105 жыл бұрын
I also only used 1 recursion on my programming life to make a tree view from 1 table. It took me 1 full day, but I'm proud of myself LOL
@GateOfSteins4 жыл бұрын
I use it often when solving coding puzzles.
@RijuChatterjee4 жыл бұрын
Never did a data structures course? Depth-first tree and graph traversals are what I associate recursion with most strongly.
@maaikevreugdemaker921028 күн бұрын
Dijkstra entered the chat
@doctortroels5 жыл бұрын
Just to be hannoying: For an odd number of disks (for even, replace "right" with "left"), the iterative solution goes as follows. move the smallest disk to the right (with wrap around) repeat 2^(n-1) times: make the unique valid move between the two other poles move the smallest disk to the right (with wrap around)
@sultandaris43155 жыл бұрын
"To move a robotic arm.....zzzz zzzzz" I died🤣🤣
@unlockwithjsr4 жыл бұрын
I don't know why, but just the way he speaks make me smile, with a hidden sense of laughter, but still saying serious because I gotta understand recursion
@vadrif-draco5 жыл бұрын
Is it weird that I understood recursion but not how the solution to this puzzle works?
@livedandletdie5 жыл бұрын
It is easy, You move disc from Point A to Point C or to point B then you move a disc from Point A B or C to Point A B or C, until such as all discs have moved from Point A to C and are in the same ordering. It's really simple though For 1 disc it's simple you just move disc 1 from A to C for 2 discs it's move A to B A to C B to C. For 3 it's slightly harder, but it's AC AB CB AC BA BC AC, for 4 it's AB AC BC AB CA CB AB AC BC BA CA BC ACand so on.
@vadrif-draco5 жыл бұрын
@@livedandletdie Thank you, Major.
@sairohit82015 жыл бұрын
@@livedandletdie you are simply amazing salute to you major
@kuyaraf1105 жыл бұрын
@@livedandletdie But where in the program is the "in the same ordering" implementation ? Why does the program build the tower on C like it was initially standing on A, biggest disk on bottom, smallest disk on top ?
@xdtimetoastergaming2734 жыл бұрын
Just move the bottom one *with the rest on top*
@icytailhonetoeknee5 жыл бұрын
Oh man recursion. It wasn't until I did Standard ML that I finally got to understand it. Definitely awesome stuff!
@KhanleGrand5 жыл бұрын
This professor explains things very well.
@jackhindbrain68335 жыл бұрын
Please have this guy on more! His explanations are sooo good
@jej34515 жыл бұрын
Any recursive algorithm can be implemented nonrecursively using a stack. I learned that 25 years ago in an undergraduate computer science course. If you use a recursive algorithm, you are in effect just using the built-in stack managed by the compiler / interpreter.
@MinusPi-p9c5 жыл бұрын
It always annoyed me how in the video do the Ackerman function the guys says that there's just no way to avoid recursion. It *has* to be turned into a loop, that's just how computers work.
@zamalek40795 жыл бұрын
Using a custom stack is one possible outcome of defunctionalizing the continuation. You can also get simple loops (i.e. tail call optimization) or other solutions that require less memory. It's a refactoring worth learning.
@lycan16025 жыл бұрын
@@MinusPi-p9c The reason that's said is because the loop you would have to write the calculation of the Ackerman function in is so impractical it becomes impossible, and it would take a tremendous amount of lines to write down. Recursion allows you to write it down in just a few lines instead. In that same video, he predicted the calculation (that was already going on for 2 months) would take a literal eternity to complete, but it is computable. To write it down in a for loop, however, is not possible, as you would run out of atoms to write it on.
@TheRiskyChance5 жыл бұрын
I'm new to computer science: Are you saying that you shouldn't use recursive functions, and instead just use the stack?
@jej34515 жыл бұрын
@@TheRiskyChance Not at all. Sometimes a recursive implementation is the simplest one, and that usually means it's the best. I was just quibbling with the claim in the video that it isn't possible to implement the algorithm nonrecursively.
@anmjubaer2 жыл бұрын
Wow. That's amazing power of recursion! Glad to experience it with hands on practice.
@simonhirst94695 жыл бұрын
I spent a so long trying to understand recursion... and this guy made it so easy to understand.
@ogmcwangster3 жыл бұрын
This still blows my mind. Very jolly good video.
@pararera63945 жыл бұрын
It is like: "Mom, I will be home for 20 minutes. If I am not, read it again." 🤣
@pararera63945 жыл бұрын
@MichaelKingsfordGray explain why. And what name has to do?
@pararera63945 жыл бұрын
Who is your dealer?
@tubeyoukonto5 жыл бұрын
@@pararera6394 let me answer the question, as the asshole wouldnt. The effect you describe is basically a while-loop always just asking if you arrived already. You dont need recursion for that. Recursion is used when the iterations/steps/layers are dependent of each other, especially when the ith iteration is dependent on the i+1th iteration. So you could have something like this: while(not at home) sleep(20 minutes) I mean, you can always create recursions on a way that they act like loops but thats bad practice. You would for example use recursion to calculate the nth number of the fibonacci sequence. You can google recursive implementations of that. Basically, a loop is just that, a loop. And recursion is a tree/graph, which is built up and then breaks itself down again to return the calculated outcome in the first node.
@pararera63945 жыл бұрын
@@tubeyoukonto but you can do it with recursion also, right?
@tubeyoukonto5 жыл бұрын
@@pararera6394 well, yes. You could, but as I said its bad practice. You needlessly build a stack of iterations that dont hold any important information. If you would do this recursive like function waitIfImNotThere() { If(not arrived) { wait 20 min waitIfImNotThere() } } Then the program would remember every iteration. So it builds a stack. If(not arrived) { Wait 20 min If(not arrived) { Wait 20 min If(not arrived) { .... You remember all of that information. And if you have a bad exit condition and its never called (thats where the recursion works back again, returning the values back to the iterations that called them), you might run into an error, a stack overflow, because that stack building runs indefinetly or at least until the limit is reached. So yes, its possible, but nobody should ever use recursion like that. Thats what loops are for :) Because loops basically throw away the information after every iteration. You dont build a stack. The only information you can save is the one that is based outside the loop and that you only manupulate/override in the loop, still saving it outside. So if you simply looped waitIfImNotThere. There would be no stack and after every iteratiln all info within that functiln is lost. However, if you initialize a variable outside of the loop and always add the waiting time to it, that info obviously stays. Because the reference is outside the loop and will be available in that frame.
@someonewhobitthedust91245 жыл бұрын
I love the way he uses simple and clear examples to demonstrate an idea that is rather complex. Great work!
@emiljanQ35 жыл бұрын
Recursion is like an applied induction proof. Never thought of it this way before.
@boonator14965 жыл бұрын
I can see where you draw that analogy from, but I don't think that's true, I still have to give it some thought for a definite answer though
@benwincelberg96845 жыл бұрын
Yeah
@jonahcornish61604 жыл бұрын
Was thinking the same thing as I watched this
@Vaaaaadim5 жыл бұрын
There is a way to do Towers of Hanoi without recursion, but doing this problem with recursion is insanely easy, and figuring it out non-recursively takes a wild insight I think. Anyways, 3Blue1Brown made a video about how you can use counting in Binary to solve Towers of Hanoi. Titled "Binary, Hanoi and Sierpinski, part 1".
@maaikevreugdemaker921028 күн бұрын
Towers of Hanoi was a puzzle my dad gave me. I figured out that it eventually was just repeating steps and i could answer how many moves it would take. Yet when I learned recursion I was still blown away by it.
@Juventinos5 жыл бұрын
i remember in school learning this. it was a real moment of "before" and "after".
@monaliftza67873 жыл бұрын
Officially my new favorite Computerphile guy.
@killingbillGaming5 жыл бұрын
0 Sekunden und nach dem SOOOOO weiß man schon dass der deutsch ist xD
@iQKyyR3K5 жыл бұрын
"das wird dem studierenden als Übung überlassen" ich krieg Alpträume
@livedandletdie5 жыл бұрын
Weiß=Deutsch...
@boonator14965 жыл бұрын
Am geilsten war eigentlich schon noch "Anakonda"
@vorrnth87345 жыл бұрын
Wanz ju no rekörschen.
@Luca-hn2ml5 жыл бұрын
@@vorrnth8734 xDD
@brandonmack1115 жыл бұрын
The example I always use to demonstrate recursion is the Fibonacci sequence, but I have to agree Towers of Hanoi is a very elegant example.
@WILDWILDVAPE5 жыл бұрын
I only noticed after a couple of minutes that he was speaking English... Ich dachte er redet deutsch mit mir.. so hart war de Akzent :D
@tainicon46395 жыл бұрын
WILD WILD VAPE haha, I have had that happen the other way around too haha
@opse82344 жыл бұрын
I once at work created a program where the use of recursion simplified the solution. What it does is that the program takes one input file and generates an output file. The output file is just a sequential file containing the structure of xml(tags, attributes, elements, namespaces) and the values. It just converts the xml from one markup language to another, cobol-friendly, markup language. It goes the orher way around aswell. Generating an xml from the sequential data file. I did use recursion to visit every child of the xml-node I was standing at. So for every node the function called itself until I had visited every node on that xml-tree. It was done using python and we use it everytime we have to handle xml-files in cobol. 👍🏻
@mangethegamer5 жыл бұрын
I remember the Hanoi recursion puzzle from back when I was in University. It's en excellent exercise for a beginner programmer.
@DutchmanDavid5 жыл бұрын
For me, it was a terrible intro. Recursion really clicked for me when I learned how the map function worked in Haskell.
@molejaboy5 жыл бұрын
More of these basic concepts with examples from this man please that was brilliant.
@Lomund4 жыл бұрын
This guy is like every lecturer i've ever had rolled into one
@matiasnoriega11544 жыл бұрын
Love the accent, love the shirt, love recursion explanation. This video is a pure win situation.
@urinveisinfeksjon5 жыл бұрын
PEP8 police does not approve!
@vincenzo35745 жыл бұрын
It hurts to look at the space before the colons and at the missing space after the commas
@BlazingSun465 жыл бұрын
Well, that’s one of the beauties of Python, everybody uses it. Researcher, Mathematician, Educator, they don’t care one bit about convention, as long as it get stuff done (and they aren’t coding in a team) it’s fine.
@tamasgal_com5 жыл бұрын
It's called "PEP 8", not "PEP8".
@code-dredd5 жыл бұрын
@@tamasgal_com Technically, it's PEP-0008 😏
@code-dredd5 жыл бұрын
@@BlazingSun46 As long as I don't have to clean it up, then he's free to create (and maintain!) his own mess. The problem is that, in reality, someone else must always end up reading and working with such code.
@diegosolis96814 жыл бұрын
This man not only amaze me with his skills, his dry homour cracks me up.
@JohnDoe-df9qx5 жыл бұрын
I bet this dude is a member of some industrial music band.
@sairohit82015 жыл бұрын
he's dave grohl from foo fighters lol
@reljasaurus4 жыл бұрын
@@sairohit8201 foo(x) fighters
@NoahNobody5 жыл бұрын
Thanks for sharing one of your superpowers with us, Thor!
@arifroktim33665 жыл бұрын
First 40 seconds and I already love this guy..
@costargc5 жыл бұрын
Awesome. I've just added this to stack overflow. I wish all questions in there had an answer like that!
@lpkuchembuck5 жыл бұрын
Muito interessante!.....🤔
@jjuca_5 жыл бұрын
@@lpkuchembuck hahahahahahahahaha
@justinlindfors85125 жыл бұрын
Not sure If toxic community Or very critical of code
@MarioWenzel5 жыл бұрын
I have to say, as a C.S. master I do not understand recursion. I always write down the base case and the inductive/recursive step(s) and am always amazed that it just works. With recursion I can trust my worked out theory. Formulating this loop-based with some mutating data-structures taxes my programming skills, which I am less confident of.
@chocOneOOne5 жыл бұрын
This is exactly the type of guy that I would expect to learn recursion from
@HemogIobin5 жыл бұрын
What an amazing professor, he looked boring and intimidating at the beginning , but you discover he's funny, interesting and smart once he begins explaining. I I gotta look into his book now
@Adamreir7 ай бұрын
I don’t know why I havent seent this before. This solution is *stupidly* elegant. Amazing!
@draakisback5 жыл бұрын
Recursion itself isn't that difficult but figuring out when you should use it can be hard especially in non functional languages. Even in functional languages you generally will have access to iterators and recursion won't always be the best choice (though the system probably uses recursion in the iterator).
@gileee5 жыл бұрын
You only use recursion when doing it Iteratively would be much more difficult or impossible (since problems which have an iterative solution is a subset of the problems with recursive solutions). I mostly use it when my code branches like when going over an n-ary tree. But recursion can be a fun exercise. I've written a c++ program before where I removed all loops and just used recursion, so for example my main program loop was the main function calling itself.
@draakisback5 жыл бұрын
@@gileee sure you are absolutely right. I use recursion quite a bit when working with elixir and clojure since it's fairly intuitive to do so in those languages. With clojure youve got concepts like transducers which rely on recursive code (they are essentially combined reduce functions) and in elixir it's not uncommon to write multiple function heads which call each other recursively. It can also help with managing state especially since all of the data types are immutable.
@gileee5 жыл бұрын
@MichaelKingsfordGray Tail recursion sure, just replace it with a loop and however many extra variables outside the loop you need. But in the general case it's as trivial as implementing your own stack and program flow control from scratch.
@gileee5 жыл бұрын
@MichaelKingsfordGray But at the end of the day you're just moving where your program saves the calls, which granted does give you an option of dynamically increasing the stack as needed (which is very useful if you're willing to take the small performance hit). But it's still going to crash eventually when you hit the max memory available to your program. Binary, Ternary... recursions can't be optimized out since logically you keep needing to hold more data at each step into a new function. With tail recursion you can just replace the current function call with the new one, so your tail recursive function never grows the stack beyond the 1 function call.
@ferggill9461 Жыл бұрын
I liked this video after the first 48 seconds. The way he described recursion as a Super Power. Just take my money.
@knuspergreg18485 жыл бұрын
3:20 why not use fstrings? print(f'Hello {variable}') (or use " if you want)
@nyaaanjake5 жыл бұрын
He may be using an older version of Python, or not yet broken the habit of string formatting. That said, f-strings are a godsend and one of my favorite recent features.
@bytefu5 жыл бұрын
Then he would have to explain them to non-pythonists, but everyone gets method calls.
@xario20075 жыл бұрын
@@bytefu Arent fstrings also kinda self explanatory? Since they are so easy to read.
@muche63215 жыл бұрын
@@xario2007 I would say, str.format() builds on the knowledge that values of parameters listed in a function call are passed into the function (used in majority of programming languages) and a literal string can behave like an object and have methods (only a subset of languages). fstrings at first sight look like specially marked literal strings; they require the knowledge that the interpreter itself evaluates the string at runtime using variables in the scope.
@lewismassie5 жыл бұрын
I used to use recursion for input error checking for code at school. Throw the input and the expected type into the function, the fucntion checks it and if invalid, printed a message. Then you would add another input, throw it into itself, and so on. When a legit input was found the fucntions would all 'collapse' back out and give you your input back. I came up with it around year 10 (14-15 yrs old) while writing programs at school. I've never seen anyone else do it
@Henrix19985 жыл бұрын
I cant believe the problem can be solved with that simple code
@jaroslavsevcik34215 жыл бұрын
But I think that the video has been shortened because it does not stress enough importance of trivial cases for recursion. And then there are more types of recursion, of course, which are not mentioned there.
@dragohammer69375 жыл бұрын
loots of stuff in coding/computer science is like that: there's a obvious to anyone solution, that is not too hard to implement, but extremely inefficient. then, there's a completely different solution, probably invented by Euler(or at least some other mathematician), that wasn't even supposed to have anything to do with computers, that solves the problem much more efficiently. my favorite example is the Fibonacci sequence. in python code: obvious solution: def Fibonacci(N): if n < 1: return 1 else: return Fibonacci(N - 1) + Fibonacci(N - 2) the problem of this solution is that it calculates the lower Fibonacci numbers over and over again, resulting in a lot repetitive computation to calculate result you already knew, and this problem gets worse as N increases, making this algorithm exceedingly slow for any practical use. but did you know that the Fibonacci sequence can be approximated by (phi^N)/root(5)? yeah, instead of all this recursion, repeatedly calculating the same values, there's a way to go straight from the index of the number on the sequence to, approximately, the number itself. with some extra code for the rounding/square roots we have: def round(x: (int, float), r: float = 0.5) -> int: """ Rounds up if the fractional part of x is greater than r, otherwise down""" if x - int(x) > r: return int(x)+1 else: return int(x) def root(x, r=2): """ root function, since i don't like to import just one function""" return x**(1/r) """ the number phi ~ 1.618""" phi = (1 + root(5))/2 def fibo(n: (int, float), rounded: bool = True) -> (int, float): """ calculate the Nth Fibonacci number using it's approximate exponential, (phi^n) / root(5), then rounding if desired""" res = (phi**(n))/5**(1/2) if rounded: res = round(res) return res if you want to be ... scientific about how bad the recursive implementation is(even when using a cache to avoid repeating the same index!), the recursive implementation(with cache!) has time complexity(how longer the program tends to take as N increases) of O(phi^(N)), meaning, it increases exponentially(I.E. super fast -> inefficient algorithm), meanwhile second implementation has a time complexity of O(1), which means, it doesn't increase even as N becomes larger and larger(not exactly true, due to the fact that as N gets bigger storing it becomes harder for the computer which increases overhead, but the number of operations, which is what the O notation cares about, stays the same)
@klaxoncow5 жыл бұрын
That's the super power of recursion!
@framegrace15 жыл бұрын
Yeah, recursive solutions are normally simpler. But simpler to us. You have to avoid recursion when programming, is usually horribly inefficient and has the inherent limit of the stack size. Fortunately, there's always a way to do it non-recursively.
@jasonschuler22565 жыл бұрын
Marc Gràcia As with all things, there are exceptions to that. For example, the recursive solution for calculating greatest common denominators (developed by Euclid) is actually the most efficient solution.
@pritabratamallik53914 жыл бұрын
I liked the way in which Professor Altenkirch used the toy to write the program. Visualizing things really helps us to program.
@patton720105 жыл бұрын
Professor Thorsten Altenkirch looks like Dave Grohl and Taylor Hawkins have morphed into 1 person and quit Foo Fighters for Foo(x) Pythons.
@muhaha7144 жыл бұрын
LOL yes! He also looks like the guy from the 'give me compliments' music video
@baphnie5 жыл бұрын
Those variable names are stellar.
@Sp0nge55 жыл бұрын
1:57 'i'll leave [the robotic arm] as an excercise' *smirk* And they say Germans don't do jokes haha
@badnamewolfie77895 жыл бұрын
Really good case for recursion. In most cases you can use a while loop (or tail recursion in the functional programming languages which is the same).
@TylerMatthewHarris5 жыл бұрын
Downloaded Anaconda and it throws “GOT NO BUNS” error
@7027-s6f5 жыл бұрын
Do some squats
@Blox1175 жыл бұрын
@@7027-s6f will that make me a better programmer?
@WhompingWalrus5 жыл бұрын
@@Blox117 Worse. if ( ! social_prospects ) code();
@rob0114 жыл бұрын
raise AnacondaDontError
@tombrady73904 жыл бұрын
Exception handling, bro do one of those
@uam2252 жыл бұрын
Brilliant product placement! Had to order the book!
@sp10sn5 жыл бұрын
:Jupiter.. I think it's also a planet? Something like this."
@wilsonhu30145 жыл бұрын
//N=4 a=A b=B c=C line 1 //N=3 a=A b=C c=B line 2 //N=2 a=A b=B c=C line 3 //N=1 a=A b=C c=B line 4 //Move a to c from line 4 A-B //End of recursion from line 4, continues back to line 3 //Move a to c from line 3 A-C //N=1 a=B b=A c=C line 5 //Move a to c from line 5 B-C //End of recursion from line 5, continues back to line 2 //Move a to c from line 2 A-B //N=2 a=C b=A c=B line 6 //N=1 a=C b=B c=A line 7 //Move a to c from line 7 C-A //End of recursion from line 7, continues back to line 6 //Move a to c from line 6 C-B //N=1 a=A b=C c=B line 8 //Move a to c from line 8 A-B //End of recursion from line 8, continues back to line 6 //End of recursion from line 6, continues back to line 1 //Move a to c from line 1 A-C //N=3 a=B b=A c=C line 9 //N=2 a=B b=C c=A line 10 //N=1 a=B b=A c=C line 11 //Move a to c from line 11 B-C //End of recursion from line 11, continues back to line 10 //Move a to c from line 10 B-A //N=1 a=C b=B c=A line 12 //Move a to c from line 12 C-A //End of recursion from line 12, continues back to line 9 //Move a to c from line 9 B-C //N=2 a=A b=B c=C line 13 //N=1 a=A b=C c=B line 14 //Move a to c from line 14 A-B //End of recursion from line 14, continues back to line 13 //Move a to c from line 13 A-C //N=1 a=B b=A c=C line 15 //Move a to c from line 15 B-C //End of recursion from line 15 //End of recursion I lost 3 brain cells doing this.
@Mo-kv9hg5 жыл бұрын
Recursion in German is recursion (recursioooon)
@Goejii5 жыл бұрын
You mean recurziooon
@NicosLeben5 жыл бұрын
It' Rekursion.
@michaelwood22922 жыл бұрын
Thanks for the video(s)... I just purchased your book... Looking forward to digging into it.
@aaron58095 жыл бұрын
Is the if x: pass else: do_something() construct pythonic? Alternative would be if not x: do_something(), right?
@keejay981955 жыл бұрын
Yes. Or just if n==0: return and then the rest. Don't even need an else statement there
@myself3874 жыл бұрын
if *variable* != *otherVariable*:
@daon234 жыл бұрын
You want me to explain recursion? Wait a bit I gotta get my towers of hanoi. Literaly every video about recursion I've seen uses this problem, and it's clear why. It sums it up really nice.
@pmcgee0035 жыл бұрын
Lucky we saved *all that typing* with single letter variable names. :D
@liangyi20125 жыл бұрын
wow, nice and simple illustration to the super power of recursion
@TYKUHN25 жыл бұрын
Unfortunately this video about recursion doesn't mention a video about recursion that mentions a video about recursion that....
@xizar0rg3 жыл бұрын
As a mathematician, I get recursion. As someone who hasn't done much coding since Borland was still putting out Pascal, this feels a little like magic.
@ZeedijkMike5 жыл бұрын
If I remember right, back in the mid/late 80ies, I saw this as an example file in one of the earliest versions of Autocad. Drew the game in 3D and moved the discs. Of course created in AutoLisp.
@zalasyu4 жыл бұрын
He is so naturally funny! I'd love for him to be my mentor!
@SergeMatveenko5 жыл бұрын
Sadly, there is no tail optimized recursion in Python:(
@overclockinggames24195 жыл бұрын
Why so ? It doesn't depends on language right
@SergeMatveenko5 жыл бұрын
@UCxfH8O5kzZjtweUpr_w5WIg I'd say almost impossible. Also, it is something not that easy to implement in a dynamic language.
@SergeMatveenko5 жыл бұрын
@@overclockinggames2419 It depends on a specific language implementation. CPython simply doesn't do this optimization. Period.
@TheMysteriousMrM5 жыл бұрын
@@SergeMatveenko It has nothing to do with implementation limitations. The problem is keeping track of stack frames, and it just gets messy when debugging. Java does not optimize tail recursion either, for the same reason.
@MadocComadrin5 жыл бұрын
@@TheMysteriousMrM That's exactly the meaning of "depending on the implementation." Easily keeping track of debugging info (e.g. stack trace) is a trade-off you get by not allowing tail-call optimization (or as a subset, tail-call recursion). IMO, Guido is a bit too militant with this decision (there are some ways to keep a decent amount of debugging info with TCO).
@doughale15554 жыл бұрын
Anything done with recursion can be done with iteration and a stack since that is how recursion is implemented anyway.
@glorytoarstotzka3305 жыл бұрын
2:40 "you download something called anaconda" conda is completely optional to run jupyter notebook , just do `pip install jupyter` then do `jupyter notebook` and you are set
@nikhilpandey23645 жыл бұрын
I prefer pip over anaconda just because it is easier for me to install requirements.txt using pip. Although I haven't tried anything other than pip3 so far
@АйбатАманбайұлы5 жыл бұрын
Could never imagine the use of recursion except for factorials. Nice job!
@Sebastian-ru3ed5 жыл бұрын
I dont have a lot of examples but its used in sorting algorythms eg. Merge Sort
@youri760005 жыл бұрын
Never do the mistakes of running this with 20 discs... (for hours now, my computer still writing hundreds/sec of "move disc ... to ...")
@coolguy284_24 жыл бұрын
Twenty disks should require 1,048,575 moves. Although that is a lot, a computer should be able to print 1 million lines to the console in a fairly short amount of time.
@glocrowhurst4 жыл бұрын
@@coolguy284_2 takes about 10-15 minutes, in my experience.
@senpaireymes14824 жыл бұрын
M=2^n-1 n: number of disqus M: number of move So you need 2^20-1 about 1,048,575 move
@bobfg31304 жыл бұрын
Have you checked the parameters?
@SteveJones172pilot4 жыл бұрын
In thinking about this before watching the video, I am stuck on the fact that If I were to build this in the "real world" I would be error-checking to make sure that the discs were never on top of a smaller disc, and keeping track of all the disc sizes, just for error checking purposes.. (even it it was just error checking that the human setting up the discs didn't make a mistake) but this is a truly elegant solution for the specific case where the starting setup is assumed correct, which it must be, by the rules of the game. In situations like this, I need to wrap my head around the fact that you should not worry about the definition of the "given" situation, and not complicate code just to detect or avoid error situations that cannot exist.
@ScoopexUs5 жыл бұрын
This was done in BASIC in the 1970s without recursion.
@TheSlizzer3483 жыл бұрын
This video is brilliant, he's a great teacher!
@CTimmerman5 жыл бұрын
Start at 9:30 and use return instead of else please.
@TheMrFatlo5 жыл бұрын
I forgot about that one .... very nicely explained, thank you.
@tubeyoukonto5 жыл бұрын
Highness level: Yes.
@chefhearne4 жыл бұрын
If you wanted to decorate your "Moves" list you could do the following: (hopefully looks alright) def move(n,f,t) : print("Moving disc {} from {} to {}".format(n,f,t)) def hanoi(n,f,h,t) : if n==0 : pass else : hanoi(n-1,f,t,h) move(n,f,t) hanoi(n-1,h,f,t)
@chefhearne4 жыл бұрын
With these changes you get the following output. (Discs are numbered 1 - 4 smallest to largest.) hanoi(4,"A","B","C") ----------------------------------------- Moving disc 1 from A to B Moving disc 2 from A to C Moving disc 1 from B to C Moving disc 3 from A to B Moving disc 1 from C to A Moving disc 2 from C to B Moving disc 1 from A to B Moving disc 4 from A to C Moving disc 1 from B to C Moving disc 2 from B to A Moving disc 1 from C to A Moving disc 3 from B to C Moving disc 1 from A to B Moving disc 2 from A to C Moving disc 1 from B to C
@chefhearne4 жыл бұрын
Any super nerds wondering how many moves a high number of rings would produce need to wonder no longer. I had set the python script to calculate all from 1-100 before it slowed to a crawl at 29 and I had noticed the formula below. Number of Moves = 2^(num_of_rings) - 1 BTW with 100 rings it takes *1,267,650,600,228,229,401,496,703,205,375 moves* With an extremely crude calculation (0.36 µs/move * the_big_number_above), a very low-ball estimate for the calculation time would be *4.653×10^23 seconds or ~ a million times the age of the universe.* Results ---------------------------------------------- 1 ring/s - 1 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 2 ring/s - 3 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 3 ring/s - 7 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 4 ring/s - 15 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 5 ring/s - 31 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 6 ring/s - 63 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 7 ring/s - 127 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 8 ring/s - 255 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 9 ring/s - 511 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 10 ring/s - 1023 move/s -- 0.0 ms Calc Time -- 0.0000 µs/move 11 ring/s - 2047 move/s -- 1.0 ms Calc Time -- 0.4883 µs/move 12 ring/s - 4095 move/s -- 2.0 ms Calc Time -- 0.4880 µs/move 13 ring/s - 8191 move/s -- 3.0 ms Calc Time -- 0.3663 µs/move 14 ring/s - 16383 move/s -- 6.0 ms Calc Time -- 0.3662 µs/move 15 ring/s - 32767 move/s -- 12.0 ms Calc Time -- 0.3664 µs/move 16 ring/s - 65535 move/s -- 24.0 ms Calc Time -- 0.3661 µs/move 17 ring/s - 131071 move/s -- 49.0 ms Calc Time -- 0.3736 µs/move 18 ring/s - 262143 move/s -- 98.0 ms Calc Time -- 0.3738 µs/move 19 ring/s - 524287 move/s -- 192.0 ms Calc Time -- 0.3663 µs/move 20 ring/s - 1048575 move/s -- 385.0 ms Calc Time -- 0.3671 µs/move 21 ring/s - 2097151 move/s -- 770.0 ms Calc Time -- 0.3672 µs/move 22 ring/s - 4194303 move/s -- 1534.0 ms Calc Time -- 0.3657 µs/move 23 ring/s - 8388607 move/s -- 3073.0 ms Calc Time -- 0.3663 µs/move 24 ring/s - 16777215 move/s -- 6151.0 ms Calc Time -- 0.3666 µs/move 25 ring/s - 33554431 move/s -- 12276.0 ms Calc Time -- 0.3659 µs/move
@paulkevinkoehler94905 жыл бұрын
This guy is the Rick Wakeman of programming... just needs the cape! 😂
@jaimeduncan61675 жыл бұрын
I had this problem in a quiz using Pascal , I used two as the base case , it did not cross my brain to use zero as the base case. Granted it was the day is pen and pencil, and I have two more problems to solve but this is quite clever
@iandrsaurri6255 жыл бұрын
I traced the code by hand with some simple cases so I get how it operates now but, I still don't get exactly why this solution should work.
@0LoneTech5 жыл бұрын
The rules of the towers of Hanoi force discs to always be in order - smallest on top, larger in the bottom. Every function call is moving the largest disc it knows about to a space that has no smaller discs, because it just made a recursive call to move any smaller discs to the third (helper) stack. It finishes by transferring the smaller discs onto the large disc, ensuring that all the smaller discs are on one pillar when the function returns. As long as the deepest call works, and it will because it won't have to move any discs, the whole arrangement of movements will complete the task. Some call designing a function like this "leap of faith" programming; by divide and conquer, we assume we can complete the task for some smaller problem. We then find a set of smallest needed problems to solve, and address those specifically.
@victos-vertex5 жыл бұрын
So the solution uses the cases of "one disk less" (n-1) to solve the problem for any amount of disks (n), but how can this work you ask? In case 0 (base case): we simply don't move, done, nice job. In case 1: We use the solution for 0 to move 0 disks from A to B (via C), then we move our single disk from A to C, then we move 0 disks from B to C (via A). In case 2: We use the solution for 1 to move 1 disk from A to B (via C), then we move our single disk from A to C, then we move 1 disk from B to C (via A). In case 3: We use the solution for 2 to move 2 disks from A to B (via C), then we move our single disk from A to C, then we move 2 disks from B to C (via A). You can already very clearly see the pattern that arises. We always start with all disks on A and (B and C) empty, and (that's also important for this solution) with all disks ordered from smallest at the top to biggest at the bottom! Given such problem (n) we can look at a simpler problem of "one disk less" (n-1) and just "ignore" the biggest disk (1) on the bottom as all other disks are smaller and thereby can move freely onto the bigger one by definition of the problem. Then solve (n-1), move our previously ignored single disk over to the target and now repeat the process for the (n-1) disks. So how do we solve (n-1)? That's easy, we already did that, didn't we? We know we can move (n-1) disks from A to C (via B) by simplifying the problem to (n-2). Now that we know we can move (n-1) disks from A to C (via B) we also know we could do the same to move them from A to B (via C), we just switch target and helper this time (or switch accordingly for any desired origin, destination and helper). Knowing this we can solve for n! We first simplify the problem and: We use the solution for (n-1) to move (n-1) disks from A to B (via C), then we move our single disk from A to C, then we move (n-1) disks from B to C (via A). But that sentence is exactly what I used for cases 0 to 3 isn't it? The sentence above is also basically already the code (with A = f, B = h, C = t): "We use the solution for (n-1)" already screams recursion base case is 0, we don't work with "negative disks" -> if n == 0: pass else "move (n-1) disks from A to B (via C)" -> hanoi(n-1, f, t, h) "then we move our single disk from A to C" -> move(f, t) "then we move (n-1) disks from B to C (via A)" -> hanoi(n-1, h, f, t) So in essence this simply works because the case of "one disk less", which ultimately boils down to the base case of 0, works. Example 5: How do we solve for 5? We solve for 4, move 1 over, solve for 4 again, done. But how do we solve for 4? We solve for 3, move 1 over, solve for 3 again, done. But how do we solve for 3? We solve for 2, move 1 over, solve for 2 again, done. But how do we solve for 2? We solve for 1, move 1 over, solve for 1 again, done. But how do we solve for 1? We solve for 0, move 1 over, solve for 0 again, done. But how do we solve for 0? We are already done.
@TheJonathankang4 жыл бұрын
@@victos-vertex Well articulated, much thanks.
@Nellak20115 жыл бұрын
The reason for an iterative solution rather a recursive solution is that, although easier to implement, the recursive solution usually has higher time and space complexities. I remember the tower of hanoi is related to counting in base 2, so if I wanted to implement an iterative solution, assuming that the tower of hanoi is Primitive Recursive, I would use the counting in base 2 as my starting point for analysis.
@shashwatvaibhav45965 жыл бұрын
and the recurrence relation is : T(n) = 2T(n-1) + 1 memories from few semesters back😄😄😁😆
@clairevicidomini31995 жыл бұрын
O(nlogn)
@shashwatvaibhav45965 жыл бұрын
@@clairevicidomini3199 It's O(2^n)... wish it would have been O(nlogn)...but it's not...☹️
@clairevicidomini31995 жыл бұрын
@@shashwatvaibhav4596 oops, yep, that is no t(n/2) xD
@thomasslone1964 Жыл бұрын
I think the first time I figured recursion out was when I was writing a function that listen all the files and directories inside a given path and realized the only way to do it was for the function to call it's self until it ran out of new subdirectories
@AndreSomers5 жыл бұрын
I always wonder what programmers or professors have against using readable names? If you mean "from" and "to", just call the variables "from" and "to" instead of 'f' and 't'. Please. It makes your application so much more readable and easier to understand.
@sharkinahat5 жыл бұрын
I agree but 'from' is a keyword in python so that's not the best example ;)
@AndreSomers5 жыл бұрын
@@sharkinahat Ah, well. I'm not a pythonian. Call it 'source' or whatever. But not just f, t, n, ... That just gets confusing.
@RedwoodRhiadra5 жыл бұрын
When I started programming all variable names were either a single letter or a single letter with a digit - the programming language simply didn't allow more than that (early versions of BASIC). It's hard to break the habit. The professor looks older than me, which means probably spent more years in environments with limited variable names, and the habit is even more ingrained for him.
@0LoneTech5 жыл бұрын
It might save time on a blackboard. In an editor, not so much, and words are both more distinct and descriptive.
@VidyaBhandary5 жыл бұрын
Very easy to understand hanoi with this video ! Thanks !
@Dmittry5 жыл бұрын
The best example of the worst naming of variables.
@preyes775 жыл бұрын
He just minifies when he feels like it.
@quorkquork5 жыл бұрын
@@BitWise501 Generic programming uses generic identifier names like the single letter ones because it's generic and there's no better name to give. Math uses generic names for the same reason, because it's abstract and there's no descriptive name.
@jakobfg975 жыл бұрын
the last thing he said is correct, that (in this case) its easier to use recursion but what i learned so far is that for every recursive solution there is an iterable solution too and the other way around. it sounded for me like there would be no solution without recursion.
@shdon5 жыл бұрын
The iterative solution is trivial too and much easier to process when doing it by hand: 1. move the smallest disk one peg to the left (if it's on the leftmost peg, move it to the rightmost peg - basically wrapping around) 2. if not solved, do the only move you can make that doesn't involve the smallest disk 3. if not solved, go to step 1 You can also move the disk to the right in the first step, as long as you do it consistently. Moving to the left will end up with the stack on peg B for an even number of disks and on peg C for an odd number of disks. Moving to the right will end up with the stack on peg B for an odd number of disks and on peg C for an even number of disks. I suppose you could adjust step 1 to make sure it always ends up on peg C.
@raykent32115 жыл бұрын
@@shdon tracing that through for two disks (even), move right solves in two steps. Move left also solves, but in six steps. So I think your last point is for efficiency?
@shdon5 жыл бұрын
@@raykent3211 That is correct, it basically moves the stack in the direction of small disk movement by 1 peg. And for an even number of disks, the stack moves in the opposite direction by 1 peg. So if you want to move the stack to peg B or peg C, you need to choose appropriately.
@cedricwang75245 жыл бұрын
brad pitt is into programming now?
@RamsesTheFourth5 жыл бұрын
Neat! You can easily guess how many steps you have to do to complete it based on number of discs. Its (2^n)-1.