1 CS 410 Mastery in Programming Chapter 2 Recursion Herbert G. Mayer, PSU CS status 7/3/2011.

Slides:



Advertisements
Similar presentations
ECE 103 Engineering Programming Chapter 54 Recursion Herbert G. Mayer, PSU CS Status 6/4/2014 Initial content copied verbatim from ECE 103 material developed.
Advertisements

Types of Recursive Methods
Computer Architecture CSCE 350
The University of Adelaide, School of Computer Science
ECE 103 Engineering Programming Chapter 11 One Minute Synopsis Herbert G. Mayer, PSU CS Status 7/1/2014.
Factorial Recursion stack Binary Search Towers of Hanoi
Lesson 19 Recursion CS1 -- John Cole1. Recursion 1. (n) The act of cursing again. 2. see recursion 3. The concept of functions which can call themselves.
More on Recursive Methods KFUPM- ICS Data Structures.
Recursion. Binary search example postponed to end of lecture.
Slides prepared by Rose Williams, Binghamton University Chapter 11 Recursion.
Slides prepared by Rose Williams, Binghamton University Chapter 11 Recursion.
Recursion. 2 CMPS 12B, UC Santa Cruz Solving problems by recursion How can you solve a complex problem? Devise a complex solution Break the complex problem.
CS Data Structures Appendix 1 How to transfer a simple loop- expression to a recursive function (factorial calculation)
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
Recursion.
CS 106 Introduction to Computer Science I 03 / 28 / 2008 Instructor: Michael Eckmann.
PSU CS 106 Computing Fundamentals II VB Subprograms & Functions HM 4/29/2008.
Recursion A recursive function is a function that calls itself either directly or indirectly through another function. The problems that can be solved.
Recursion Chapter 7. Chapter 7: Recursion2 Chapter Objectives To understand how to think recursively To learn how to trace a recursive method To learn.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
1 CS 162 Introduction to Computer Science Chapter 10 C++ Simulation of Recursion Herbert G. Mayer, PSU Status 11/17/2014.
Recursion and Implementation of Functions
1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Recursion Review.
20-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN
Department of Computer Science and Engineering, HKUST 1 HKUST Summer Programming Course 2008 Recursion.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 12: Recursion Problem Solving, Abstraction, and Design using C++
1 CS 162 Introduction to Computer Science Chapter 4 Function Calls Herbert G. Mayer, PSU Status 11/9/2014.
Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top.
Recursion Chapter 7. Chapter Objectives  To understand how to think recursively  To learn how to trace a recursive method  To learn how to write recursive.
1 CS 410 / 510 Mastery in Programming Chapter 2 Recursion Herbert G. Mayer, PSU CS Status 7/6/2013 With improvements suggested by: Gaby Haddock, summer.
CHAPTER 02 Recursion Compiled by: Dr. Mohammad Omar Alhawarat.
Lecturer: Dr. AJ Bieszczad Chapter 11 COMP 150: Introduction to Object-Oriented Programming 11-1 l Basics of Recursion l Programming with Recursion Recursion.
CIS 068 Welcome to CIS 068 ! Stacks and Recursion.
Computer Science and Software Engineering University of Wisconsin - Platteville 9. Recursion Yan Shi CS/SE 2630 Lecture Notes Partially adopted from C++
Chapter 14 Recursion. Chapter Objectives Learn about recursive definitions Explore the base case and the general case of a recursive definition Learn.
Chapter 8 Recursion Modified.
Chapter 13 Recursion. Learning Objectives Recursive void Functions – Tracing recursive calls – Infinite recursion, overflows Recursive Functions that.
Chapter 4 Recursion. Copyright © 2004 Pearson Addison-Wesley. All rights reserved.1-2 Chapter Objectives Explain the underlying concepts of recursion.
CSIS 123A Lecture 9 Recursion Glenn Stevenson CSIS 113A MSJC.
Recursion. What is recursion? Rules of recursion Mathematical induction The Fibonacci sequence Summary Outline.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
ECE 103 Engineering Programming Chapter 18 Iteration Herbert G. Mayer, PSU CS Status 7/19/2015 Initial content copied verbatim from ECE 103 material developed.
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
CS 161 Introduction to Programming and Problem Solving Chapter 18 Control Flow Through C++ Program Herbert G. Mayer, PSU Status 10/8/2014 Initial content.
1 CS 163 Data Structures Chapter 6 Function Calls and Recursion Herbert G. Mayer, PSU Status 6/1/2015.
Recursion A recursive definition is one which uses the word or concept being defined in the definition itself Example: “A computer is a machine.
ECE 103 Engineering Programming Chapter 31 C Scopes Herbert G. Mayer, PSU CS Status 8/1/2015 Initial content copied verbatim from ECE 103 material developed.
Recursion Chapter 17 Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013.
CS 161 Introduction to Programming and Problem Solving Chapter 17 Nested Loops Herbert G. Mayer, PSU Status 9/8/2014 Initial content copied verbatim from.
1 Recursion Recursive function: a function that calls itself (directly or indirectly). Recursion is often a good alternative to iteration (loops). Its.
ECE 103 Engineering Programming Chapter 30 C Functions Herbert G. Mayer, PSU CS Status 8/9/2014 Initial content copied verbatim from ECE 103 material developed.
1 CSC 143 Recursion [Reading: Chapter 17]. 2 Recursion  A recursive definition is one which is defined in terms of itself.  Example:  Sum of the first.
Recursion.
Chapter 13 Recursion Copyright © 2016 Pearson, Inc. All rights reserved.
Chapter 5 Microprocessor Runtime Stack
Chapter Topics Chapter 16 discusses the following main topics:
CS 201 Computer Systems Programming Chapter 6 “Recursion”
More on Recursive Methods
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
6.001 SICP Stacks and recursion
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Stacks & Recursion.
CS 320 Principles of Programming Languages
CS 320 Principles of Programming Languages
Recursion and Implementation of Functions
Yan Shi CS/SE 2630 Lecture Notes
ECE 103 Engineering Programming Chapter 18 Iteration
Chapter 13 Recursion Copyright © 2010 Pearson Addison-Wesley. All rights reserved.
Presentation transcript:

1 CS 410 Mastery in Programming Chapter 2 Recursion Herbert G. Mayer, PSU CS status 7/3/2011

2 Syllabus Definition of Recursion Definition of Recursion Recursion vs. Iteration Recursion vs. Iteration Q-Sequence Q-Sequence Ackermann Function Ackermann Function Simulate Recursion via Iteration Simulate Recursion via Iteration References References

3 Definition of Recursion An algorithms is recursive, if it is partly defined in simpler versions of itself [1] A recursive program is the implementation of a recursive algorithm What if a programming language is non-recursive (e.g. Fortran) and we wish to express a recursive algorithm (e.g. parsing) in that very language? --See later! What then are the other parts of a recursive algorithm? A correctly defined recursive algorithm requires a starting point, formally known as the “base case” Base case could be multiple steps Recursive algorithm A() uses a base case as origin of computation, plus the actual, recursive function body, including some recursive use of A() Recursive body can be indirectly recursive through intermediate function a()-> b()-> a() – through intermediate function b() Primitive examples are the factorial( n ) function; or Fibonacci( n ), for non-negative arguments n; the latter shown here: Base case 1:Fibo(0) = 0 Base case 2:Fibo(1) = 1 Recursive Definition:Fibo( n ) for n > 1 = Fibo( n-1 ) + Fibo( n-2 )

4 Recursion vs. Iteration Iteration is expressed in programming languages by loops; e.g. for-, while-, do-, repeat loops These are readable and efficient methods for expressing iteration, but are not necessary Recursion can easily replace such iterative steps; yet for some people this seems hard to understand In reality, people are simply unused to recursion; else recursion would be as immediately understandable as iteration

5 Q-Sequence, Definition Q-Sequence is defined in [1] as a function q(n) for positive integers n Base case 1: q(1) = 1 Base case 2: q(2) = 1 Recursive definition of q(n), for n > 2 q( n ) = q( n – q( n-1 ) ) + q( n – q( n-2 ) ) Q-Sequence reminds us of Fibonacci( n ) function, but with a great difference in type of result: The function results of Fibonacci( n ) are monotonically increasing with increasing argument Yet surprisingly, the results of q( n ) are non-monotonic! Note # of calls: calls( q( 40 ) ) = 1,137,454,741

6 Q-Sequence, Coded in C #define MAX 100// arbitrary limit int calls;// will be initialized each time int q( int arg ) { // q calls++;// track another call if ( arg <= 2 ) { return 1;// base case return 1;// base case }else{// now recurse! return q( arg - q( arg-1) ) + q( arg - q( arg-2) ); return q( arg - q( arg-1) ) + q( arg - q( arg-2) ); } //end if } //end q void main() { // main for ( int i = 1; i < MAX; i++ ) { calls = 0;// initially no calls yet calls = 0;// initially no calls yet printf( "Q(%2d) = %3d, #calls = %10d\n", i, q(i), calls ); printf( "Q(%2d) = %3d, #calls = %10d\n", i, q(i), calls ); } //end for } // end main

7 Q-Sequence Results Q( 1) = 1, #calls = 1 Q( 2) = 1, #calls = 1 Q( 3) = 2, #calls = 5 Q( 4) = 3, #calls = 13 Q( 5) = 3, #calls = 25 Q( 6) = 4, #calls = 49 Q( 7) = 5, #calls = 93 Q( 8) = 5, #calls = 161 Q( 9) = 6, #calls = 281 Q(10) = 6, #calls = 481 Q(11) = 6, #calls = Q(26) = 14, #calls = Q(27) = 16, #calls = Q(28) = 16, #calls = Q(29) = 16, #calls = Q(30) = 16, #calls = Q(31) = 20, #calls = Q(32) = 17, #calls = Q(33) = 17, #calls = Q(34) = 20, #calls = Q(35) = 21, #calls = Q(36) = 19, #calls = Q(37) = 20, #calls = Q(38) = 22, #calls = Q(39) = 21, #calls = Q(40) = 22, #calls = Will never reach 100 in your life time... Will never reach 100 in your life time

8 Ackermann Definition Ackermann a( m, n ) is defined as a function of two non-negative integers m and n Base case 1: a( 0, n ) = n+1 Base case 2: a( m, 0 ) = a( m-1, 1 ) Recursive definition of a( m, n ), m, n > 0 a( m, n ) = a( m-1, a( m, n-1 ) ) Ackermann grows awfully fast. For example: a(4,2) is integer with 19,729 decimal digits

9 Ackermann Coded in C unsigned a( unsigned m, unsigned n ) { // a calls++;// global unsigned if ( 0 == m ) { return n + 1;// a base case return n + 1;// a base case }else if ( 0 == n ) {// m > 0 return a( m-1, 1 );// other base case return a( m-1, 1 );// other base case }else{// m > 0, n > 0 return a( m-1, a( m, n-1 ) );// recurse return a( m-1, a( m, n-1 ) );// recurse } //end if } //end q void main() { // main for( int i = 0; i < MAX; i++ ) { printf( "\nFor m = %d\n", i ); printf( "\nFor m = %d\n", i ); for( int j = 0; j < MAX; j++ ) { for( int j = 0; j < MAX; j++ ) { calls = 0; calls = 0; printf( "a(%1d,%1d) = %10u, calls = %12u\n", printf( "a(%1d,%1d) = %10u, calls = %12u\n", i, j, a( i, j ), calls ); i, j, a( i, j ), calls ); } //end for } //end for } //end for } // end main

10 Ackermann Results For m = 0 a(0,0) = 1, calls = 1... For m = 1... a(1,7) = 9, calls = 16 For m = 2 a(2,0) = 3, calls = 5 a(2,1) = 5, calls = 14 a(2,2) = 7, calls = 27 a(2,3) = 9, calls = 44 a(2,4) = 11, calls = 65 a(2,5) = 13, calls = 90 a(2,6) = 15, calls = 119 a(2,7) = 17, calls = 152 For m = 3 a(3,0) = 5, calls = 15 a(3,1) = 13, calls = 106 a(3,2) = 29, calls = 541 a(3,3) = 61, calls = 2432 a(3,4) = 125, calls = a(3,5) = 253, calls = a(3,6) = 509, calls = a(3,7) = 1021, calls = For m = 4 a(4,0) = 13, calls = 107 don’t even dream about computing a(4,2) or higher!

11 Simulate Recursion via Iteration What to do, if you implement a recursive algorithm using a language that does not support recursion? Replace the recursive by a non-recursive algorithm! Or simulate recursion via non-recursive methods After all, a computer chip has no notion of recursion; it is a sequential machine that “simulates recursion” via non-recursive methods; compiler maps! Done so frequently in industry; e.g. FPS used Fortran to implement System SW and compilers Here are the actual steps of simulating recursion via iteration:

12 Steps of Simulating Recursion consider directly-recursive calls, i.e. calls from within recursive function:  Define explicit stack with top of stack (tos) index, initially 0; like a real stack, it may overflow, include code to check; holds all parameters, function return value, return location (labels after a recursive call)  Define labels for each point of recursive call, and each point of return; number these labels, for example l1, l2, l3 etc. There will be branches to the points of return  At each point of recursive call: Increment the tos Move parameters for “this call” onto stack; e.g. stack[ tos ].arg1 = … Store place of return; e.g. stack[ tos ].ret = 1, 2, 3 alluding to labels l1, l2, l3 Jump to the head of the function, not including initializing code

13 Steps of Simulating Recursion 4. Ideally, all explicitly coded returns and the implied return at the end of the recursive function body can be re-coded into a single place; if not, the code before each return is replicated: Decrement the top of stack index Check, to which of the stored labels the flow of control has to branch to continue execution; e.g.: if ( stack[ tos ].ret == xyz ) goto label_xyz; And if no other branch is open, then fall through the end For void functions this is a literal fall-through For true functions, the return value has to be computed, e.g.: stack[ tos ].return_val = … 5. For nested recursive calls or several recursive calls in a row or both: “be creative” 5. For nested recursive calls or several recursive calls in a row or both: “be creative”

14 Simulate Recursion, fact() #include #include #define MAX_STACK 100// never reached or exceeded! #define MAX 14// higher factorials overflow 32b unsigned calls;// in case we track # of calls typedef struct s_tp { unsigned arg; unsigned fact; unsigned ret; } struct_s_tp; // first the recursive fact() function for reference // includes tracking # of calls unsigned fact( unsigned arg ) { // fact calls++;// gotta be global if ( 0 == arg ) { return 1; return 1;}else{ return fact( arg - 1 ) * arg; return fact( arg - 1 ) * arg; } //end if } //end fact

15 Simulate Recursion, fact() unsigned nrfact( unsigned arg ) { //nrfact struct_s_tp s[ MAX_STACK ];// local stack, no recursion! unsigned top = 0; s[ top ].arg = arg;// this call’s argument s[ top ].ret = 3;// 3 alludes to label l3 l1:if ( 0 == s[ top ].arg ) { s[ top ].fact = 1; s[ top ].fact = 1;}else{ top++;// recurse soon top++;// recurse soon s[ top ].arg = s[ top-1 ].arg-1; s[ top ].arg = s[ top-1 ].arg-1; s[ top ].ret = 2;// remember label l2 s[ top ].ret = 2;// remember label l2 goto l1;// here simulate recursion goto l1;// here simulate recursionl2: // back from recursive call. // back from recursive call. top--;// back from call top--;// back from call s[ top ].fact = s[ top + 1 ].fact * s[ top ].arg; s[ top ].fact = s[ top + 1 ].fact * s[ top ].arg; } //end if if ( s[ top ].ret == 2 ) {// test, where to branch to goto l2;// unstructured goto into if goto l2;// unstructured goto into if } //end if l3: return s[ top ].fact; } //end nrfact

16 Simulate Recursion, fact() Results r_fact( 0) = 1, calls = 1 r_fact( 1) = 1, calls = 2 r_fact( 2) = 2, calls = 3 r_fact( 3) = 6, calls = 4 r_fact( 4) = 24, calls = 5 r_fact( 5) = 120, calls = 6 r_fact( 6) = 720, calls = 7 r_fact( 7) = 5040, calls = 8 r_fact( 8) = 40320, calls = 9 r_fact( 9) = , calls = 10 r_fact(10) = , calls = 11 r_fact(11) = , calls = 12 r_fact(12) = , calls = 13 r_fact(13) = , calls = 14 nr_fact( 0) = 1 nr_fact( 1) = 1 nr_fact( 2) = 2 nr_fact( 3) = 6 nr_fact( 4) = 24 nr_fact( 5) = 120 nr_fact( 6) = 720 nr_fact( 7) = 5040 nr_fact( 8) = nr_fact( 9) = nr_fact(10) = nr_fact(11) = nr_fact(12) = nr_fact(13) = r_fact( 0) = 1, calls = 1 r_fact( 1) = 1, calls = 2 r_fact( 2) = 2, calls = 3 r_fact( 3) = 6, calls = 4 r_fact( 4) = 24, calls = 5 r_fact( 5) = 120, calls = 6 r_fact( 6) = 720, calls = 7 r_fact( 7) = 5040, calls = 8 r_fact( 8) = 40320, calls = 9 r_fact( 9) = , calls = 10 r_fact(10) = , calls = 11 r_fact(11) = , calls = 12 r_fact(12) = , calls = 13 r_fact(13) = , calls = 14 nr_fact( 0) = 1 nr_fact( 1) = 1 nr_fact( 2) = 2 nr_fact( 3) = 6 nr_fact( 4) = 24 nr_fact( 5) = 120 nr_fact( 6) = 720 nr_fact( 7) = 5040 nr_fact( 8) = nr_fact( 9) = nr_fact(10) = nr_fact(11) = nr_fact(12) = nr_fact(13) =

17 Simulate Recursion, fibo() #define MAX_STACK 100// never to be reached or exceeded! #define MAX 30// higher fibo(n) not computed unsigned calls;// in case we track # of calls typedef struct s_tp {// type of stack unsigned arg;// copy of fibo’s arg unsigned fibo;// return value for fibo unsigned ret;// to which label to goto? } struct_s_tp; // recursive function for reference: unsigned fibo( unsigned arg ) { // fibo calls++; if ( arg <= 1 ) {// base case? return arg;// if so: done return arg;// if so: done}else{ return fibo( arg-1 ) + fibo( arg-2 ); return fibo( arg-1 ) + fibo( arg-2 ); } //end if } //end fibo

18 Simulate Recursion, fibo() unsigned nr_fibo( unsigned arg ) { //nr_fibo struct_s_tp s[ MAX_STACK ];// stack can be local struct_s_tp s[ MAX_STACK ];// stack can be local unsigned top = 0;// initially unsigned top = 0;// initially s[ top ].arg = arg;// copy arg to stack s[ top ].arg = arg;// copy arg to stack s[ top ].ret = 4;// if all fails, return s[ top ].ret = 4;// if all fails, return l1: if ( s[ top ].arg <= 1 ) { s[ top ].fibo = s[ top ].arg; s[ top ].fibo = s[ top ].arg; }else{ }else{ top++;// ready to recurse top++;// ready to recurse s[ top ].arg = s[ top - 1 ].arg - 1; s[ top ].arg = s[ top - 1 ].arg - 1; s[ top ].ret = 2;// to place of 1. return s[ top ].ret = 2;// to place of 1. return goto l1;// recurse goto l1;// recurse l2: top++;// ready to recurse again s[ top ].arg = s[ top - 2 ].arg - 2; s[ top ].arg = s[ top - 2 ].arg - 2; s[ top ].ret = 3;// to place of 2nd return s[ top ].ret = 3;// to place of 2nd return goto l1;// recurse goto l1;// recurse l3:// two returns simulated top -= 2;// simulate 2 returns top -= 2;// simulate 2 returns s[ top ].fibo = s[ top+1 ].fibo + s[ top+2 ].fibo; s[ top ].fibo = s[ top+1 ].fibo + s[ top+2 ].fibo; } //end if } //end if if ( 2 == s[ top ].ret ) {// second recursive call if ( 2 == s[ top ].ret ) {// second recursive call goto l2; goto l2; }else if ( 3 == s[ top ].ret ) { }else if ( 3 == s[ top ].ret ) { goto l3; goto l3; } //end if } //end if l4:return s[ top ].fibo;// all done } //end nr_fibo

19 Simulate Recursion, fibo() Results r_fibo( 0) = 0, calls = 1 r_fibo( 1) = 1, calls = 1 r_fibo( 2) = 1, calls = 3 r_fibo( 0) = 0, calls = 1 r_fibo( 1) = 1, calls = 1 r_fibo( 2) = 1, calls = 3 r_fibo( 3) = 2, calls = 5 r_fibo( 4) = 3, calls = 9... r_fibo( 3) = 2, calls = 5 r_fibo( 4) = 3, calls = 9... r_fibo(22) = 17711, calls = r_fibo(23) = 28657, calls = r_fibo(24) = 46368, calls = r_fibo(25) = 75025, calls = r_fibo(26) = , calls = r_fibo(27) = , calls = r_fibo(28) = , calls = r_fibo(29) = , calls = nr_fibo( 0) = 0 nr_fibo( 1) = 1 nr_fibo( 2) = 1 nr_fibo( 3) = 2 nr_fibo( 4) = 3... r_fibo(22) = 17711, calls = r_fibo(23) = 28657, calls = r_fibo(24) = 46368, calls = r_fibo(25) = 75025, calls = r_fibo(26) = , calls = r_fibo(27) = , calls = r_fibo(28) = , calls = r_fibo(29) = , calls = nr_fibo( 0) = 0 nr_fibo( 1) = 1 nr_fibo( 2) = 1 nr_fibo( 3) = 2 nr_fibo( 4) = 3... nr_fibo(22) = nr_fibo(23) = nr_fibo(24) = nr_fibo(25) = nr_fibo(26) = nr_fibo(27) = nr_fibo(28) = nr_fibo(29) =

20 Simulating Return of fibo() Must the computation of the continuation place be after the if-statement? Or can we relocate it into the Else-Clause? Must the computation of the continuation place be after the if-statement? Or can we relocate it into the Else-Clause? That would lead to a partial simulation, in which only the case arg > 1 continues correctly That would lead to a partial simulation, in which only the case arg > 1 continues correctly Yet even cases for arg <= 1 must compute the right continuation via (unstructured) brute-force gotos: Yet even cases for arg <= 1 must compute the right continuation via (unstructured) brute-force gotos: if ( 2 == s[ top ].ret ) {// second recursive call goto l2; goto l2; }else if ( 3 == s[ top ].ret ) { goto l3; goto l3; } //end if

21 Simulate Recursion, fibo2() unsigned nr_fibo2( unsigned arg ) { //nr_fibo2 struct_s_tp s[ MAX_STACK ];// stack can be local struct_s_tp s[ MAX_STACK ];// stack can be local unsigned top = 0;// initially unsigned top = 0;// initially s[ top ].arg = arg;// copy arg to stack s[ top ].arg = arg;// copy arg to stack s[ top ].ret = 4;// if all fails, return s[ top ].ret = 4;// if all fails, return l1: if ( s[ top ].arg <= 1 ) { s[ top ].fibo = s[ top ].arg; s[ top ].fibo = s[ top ].arg; if ( 2 == s[ top ].ret ) {// second recursive call if ( 2 == s[ top ].ret ) {// second recursive call goto l2; goto l2; }else if ( 3 == s[ top ].ret ) { }else if ( 3 == s[ top ].ret ) { goto l3; goto l3; } //end if } //end if }else{ }else{ top++;// ready to recurse top++;// ready to recurse s[ top ].arg = s[ top - 1 ].arg - 1; s[ top ].arg = s[ top - 1 ].arg - 1; s[ top ].ret = 2;// to place of 1. return s[ top ].ret = 2;// to place of 1. return goto l1;// recurse goto l1;// recurse l2: top++;// ready to recurse again s[ top ].arg = s[ top - 2 ].arg - 2; s[ top ].arg = s[ top - 2 ].arg - 2; s[ top ].ret = 3;// to place of 2nd return s[ top ].ret = 3;// to place of 2nd return goto l1;// recurse goto l1;// recurse l3:// two returns simulated top -= 2;// simulate 2 returns top -= 2;// simulate 2 returns s[ top ].fibo = s[ top+1 ].fibo + s[ top+2 ].fibo; s[ top ].fibo = s[ top+1 ].fibo + s[ top+2 ].fibo; if ( 2 == s[ top ].ret ) {// second recursive call if ( 2 == s[ top ].ret ) {// second recursive call goto l2; goto l2; }else if ( 3 == s[ top ].ret ) { }else if ( 3 == s[ top ].ret ) { goto l3; goto l3; } //end if } //end if l4: return s[ top ].fibo;// all done } //end nr_fibo2

22 Simulate Recursion, hanoi() void nr_hanoi( unsigned discs, char* start, char* buffer, char* target ) { //nr_hanoi struct_h_type s[ MAX_STACK ]; unsigned top = 0; s[ top ].discs = discs; s[ top ].start = start; s[ top ].buffer = buffer; s[ top ].target = target; s[ top ].ret = 4; l1:if ( s[ top ].discs > 0 ) { top++; s[ top ].discs = s[ top-1 ].discs - 1; s[ top ].start = s[ top-1 ].start; s[ top ].buffer= s[ top-1 ].target; s[ top ].target= s[ top-1 ].buffer; s[ top ].ret = 2; goto l1; l2:printf( "nr move disc %1u from %s to %s\n", s[ top ].discs, s[ top ].start, s[ top ].target ); top++; top++; s[ top ].discs = s[ top-1 ].discs - 1; s[ top ].discs = s[ top-1 ].discs - 1; s[ top ].start = s[ top-1 ].buffer; s[ top ].start = s[ top-1 ].buffer; s[ top ].buffer= s[ top-1 ].start; s[ top ].buffer= s[ top-1 ].start; s[ top ].target= s[ top-1 ].target; s[ top ].target= s[ top-1 ].target; s[ top ].ret = 3; s[ top ].ret = 3; goto l1; goto l1; } //end if l3:if ( 2 == s[ top ].ret ) { top--; top--; goto l2; goto l2; }else if ( 3 == s[ top ].ret ) { top--; top--; goto l3; goto l3; } //end if } //end nr_hanoi

23 References  Douglas R. Hofstader, “Gödel, Escher, Bach: an eternal golden braid”, Basic Books, 1999, ISBN  Ackermann functiona at NIST:  Herbert G Mayer: “Advanced C Programming on the IBM PC”, 1989, Windcrest, ISBN  Non-recursive solution to Towers of Hanoi: