Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: cannot follow hanoi subroutine

by tilly (Archbishop)
on Nov 05, 2007 at 23:24 UTC ( [id://649114]=note: print w/replies, xml ) Need Help??


in reply to cannot follow hanoi subroutine

I've always found it useful to use indentation to indicate program calling depth. While it is very simple, that makes it easy to keep straight how many call frames are open at any point, and what they are. (All the statements from a particular call to the function should line up nicely.)
#!/usr/bin/perl -w use strict; my $recursion = 0; sub hanoi { my ($n, $start, $end, $extra) = @_; $recursion++; my $indent = " " x $recursion; print $indent, "Entering hanoi($n, $start, $end, $extra)\n"; if ($n == 1) { print $indent, "Move disk #1 from $start to $end.\n"; } else { hanoi($n-1, $start, $extra, $end); print $indent, "Move disk #$n from $start to $end.\n"; hanoi($n-1, $extra, $end, $start); } print $indent, "Leaving hanoi($n, $start, $end, $extra)\n"; $recursion--; } hanoi(3, 'A', 'C', 'B'); __END__ Entering hanoi(3, A, C, B) Entering hanoi(2, A, B, C) Entering hanoi(1, A, C, B) Move disk #1 from A to C. Leaving hanoi(1, A, C, B) Move disk #2 from A to B. Entering hanoi(1, C, B, A) Move disk #1 from C to B. Leaving hanoi(1, C, B, A) Leaving hanoi(2, A, B, C) Move disk #3 from A to C. Entering hanoi(2, B, C, A) Entering hanoi(1, B, A, C) Move disk #1 from B to A. Leaving hanoi(1, B, A, C) Move disk #2 from B to C. Entering hanoi(1, A, C, B) Move disk #1 from A to C. Leaving hanoi(1, A, C, B) Leaving hanoi(2, B, C, A) Leaving hanoi(3, A, C, B)
As the saying goes, to understand recursion you must first understand recursion. But hopefully this simple output will help you get that "ah hah!" moment where it starts to make sense.

Replies are listed 'Best First'.
Re^2: cannot follow hanoi subroutine
by convenientstore (Pilgrim) on Nov 06, 2007 at 04:11 UTC
    Huge thank you to everyone as I finally got it..

    It took re-reading everyone's post and trying combination of different things.. but I finally got it. Thank you so much!!!!
    Long time ago, I took a pascal course and there was a tracing program where I can actually step through the program and I personally think perl's debugging mechanism is little bit behind.(but then what do i know)

    I ran the debug on this program but I was not able to follow through.. now that i am running with extra print and indentation, I can clearly see

    btw, Mark, when is book "Perl Program Repair Shop and Red Flags" coming out? I am reading the "higher learning" (but bit too advance for me at this stage) and I feel that beginners like me can benefit big time by reading the completed book of reapir shop
    1 #!/usr/bin/perl -w 2 use strict; 3 4 my $recursion = 0; 5 my $count; 6 7 sub hanoi { 8 warn "invoked @_"; 9 my ($n, $start, $end, $extra) = @_; 10 $recursion++; 11 my $indent = " " x $recursion; 12 13 print$indent, "Entering hanoi($n, $start, $end, $extra)\n"; 14 15 if ($n == 1) { 16 warn $indent, "----------Move disk #1 from $start to $e +nd.------------\n"; 17 $count++; 18 } else { 19 print"enter first hanoi\n"; 20 print"\$n is $n\n"; 21 hanoi($n-1, $start, $extra, $end); 22 print"AFTER first hanoi\n"; 23 print "\$n is $n\n"; 24 warn $indent, "----------$count Move disk #$n from $st +art to $end.\n"; 25 print " enter second hanoi\n"; 26 hanoi($n-1, $extra, $end, $start); 27 print " AFTER second hanoi\n"; 28 print " \$n is $n\n"; 29 } 30 print $indent, " __LEAVING hanoi($n, $start, $end, + $extra)\n"; 31 print " \$n is $n\n"; 32 $recursion--; 33 } 34 35 hanoi(3, 'A', 'C', 'B'); invoked 3 A C B at ././perl.hanoi_f line 8. Entering hanoi(3, A, C, B) enter first hanoi $n is 3 invoked 2 A B C at ././perl.hanoi_f line 8. Entering hanoi(2, A, B, C) enter first hanoi $n is 2 invoked 1 A C B at ././perl.hanoi_f line 8. Entering hanoi(1, A, C, B) ----------Move disk #1 from A to C.------------ __LEAVING hanoi(1, A, C, B) $n is 1 AFTER first hanoi $n is 2 ----------1 Move disk #2 from A to B. enter second hanoi invoked 1 C B A at ././perl.hanoi_f line 8. Entering hanoi(1, C, B, A) ----------Move disk #1 from C to B.------------ __LEAVING hanoi(1, C, B, A) $n is 1 AFTER second hanoi $n is 2 __LEAVING hanoi(2, A, B, C) $n is 2 AFTER first hanoi $n is 3 ----------2 Move disk #3 from A to C. enter second hanoi invoked 2 B C A at ././perl.hanoi_f line 8. Entering hanoi(2, B, C, A) enter first hanoi $n is 2 invoked 1 B A C at ././perl.hanoi_f line 8. Entering hanoi(1, B, A, C) ----------Move disk #1 from B to A.------------ __LEAVING hanoi(1, B, A, C) $n is 1 AFTER first hanoi $n is 2 ----------3 Move disk #2 from B to C. enter second hanoi invoked 1 A C B at ././perl.hanoi_f line 8. Entering hanoi(1, A, C, B) ----------Move disk #1 from A to C.------------ __LEAVING hanoi(1, A, C, B) $n is 1 AFTER second hanoi $n is 2 __LEAVING hanoi(2, B, C, A) $n is 2 AFTER second hanoi $n is 3 __LEAVING hanoi(3, A, C, B) $n is 3
      When you said "... there was a tracing program where I can actually step through the program and I personally think perl's debugging mechanism is little bit behind. ...."
      I wondered if you were aware that Perl has a trace command that you can turn on the trace flag, and then just continue the code and watch it work --- that might be easier to follow than "stepping" through the program.
      DB<1> t Trace = on DB<1> c
      Long time ago, I took a pascal course and there was a tracing program where I can actually step through the program and I personally think perl's debugging mechanism is little bit behind.
      While it's not state-of-the-art, Perl's debugger is useful either by itself or when used from another tool.

      The full version of Komodo IDE comes with Perl debugger integration, allowing you to visually set/clear breakpoints and to step through the code as with other IDEs.

      The Data Display Debugger also integrates with the Perl debugger in a way familiar to users of GDB, allowing you to trace the execution of your programs and to visualise the contents of your data-structures over time.

      Aside from "backward in time" debuggers which are starting to appear recently, the state-of-the-art is probably Visual Studio 2005's .NET debugger. Specifically the edit-and-continue and exception tracing facilities are fantastic. Hopefully Perl will one day attract such tools.

      -David

        Hopefully Perl will one day attract such tools. (speaking of Visual Studio's debugger)

        With all due respect, I sincerely hope not!

        I routinely work in a state-of-the-art IDE with all the usual debugging bells and whistles, but strenuously avoid their use. Years ago, watching my collegues and myself bog down in "step-in", "step-out", "step-over" swamps, I began to suspect that such an approach to understanding a program is counterproductive. (And, as we all know, totally impossible for multithreaded code!)

        Years ago Fred Brooks described the OS/360 linking loader as the most impressive, powerful implementation of a concept whose time had passed. I feel the same way about debuggers. With CPU clock speeds in the GHz range, and program execution times of minutes, hours, or months common (e.g. reactive systems, transaction processing, etc.), attempting to understand a program by single-stepping (whether at machine opcode or program statement) feels like trying to recognize a friend's face by examining DNA sequences.

        I sincerely suggest that the sooner we get out of the habits of thinking about control flow and micromanagement (literally! ;-) and concentrate more on abstraction and composition, the better equipped we will be to write beautiful code that will effectively use those 80-core laptops soon to appear.

        I earlier praised Mark Jason Dominius' book Higher Order Perl (and he in no way is to be held responsible for my ranting). That book provides an excellent introduction into thinking functionally rather than operationally. I can't speak highly enough of the value of making that shift in one's thinking, regardless of the language at hand.

      btw, Mark, when is book "Perl Program Repair Shop and Red Flags" coming out?
      That is a good question. Thanks for asking.

      It was supposed to be out already, but about a year ago, the publisher fired my editor and did not appoint another one. I am not sure what is going on, and I have been busy enough with other stuff that I have not pursued it.

      So I don't know.

      Sorry.

        Mark, would you consider having the unfinished-material available for fee?

        I am a big fan of "Perl program repair shop and red flags" articles and been waiting for a while for more articles on line or actual book to come out
        Unforunately, I feel that I learn more about writing Perl from those articles than reading any articles or books
        I brought a whole bunch of perl books after finishing "Learning Perl" because I needed to write longer and complicated programs.

        My honest opinion(?) with no CS background, is that all these perl books are not that helpful when it comes to teaching people how to
        top down design and come up with algorithm and putting codes together.
        And that’s why now I am going back to my pascal course that I took almost 13 years ago to help me understand the algorithm and way to design.
        Someone suggest to me that reading someone else’s program is the best way to learn and after reading "redflag series", I feel that there should be more books with real programs(since locating just right program for me to learn from of someone else’s code is not that easy) explaning things rather Than typical Perl books that out there.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://649114]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (1)
As of 2024-04-16 19:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found