When I tried to implement functions in TI-BASIC, I was frustrated by the fact that all variables are global and there are no ways to receive inputs and return outputs. After looking at a post on ti-basic deveoper and a related post on cemetech, I figured out some simple workarounds and managed to write a classical Fibonacci function both recursively and iteratively in TI-BASIC.

Recursion in TI-BASIC
Overview
The main idea is to store each local variable as a list (I called them "|LLOC1", "|LLOC2", ...) and initialize the lists with the input value of the function in the main program. You also need to store another index variable (I called it "I") to keep track of the current value.


Code:
{10}->|LLOC1 // input variable specifying the nth fibonacci number, here n = 10
// local variables
{0}->|LLOC2
{0}->|LLOC3
1->I
prgmFIB
Disp Ans


Start of the function
At the beginning of the function, you will increment "I" and append a new empty value to each local variable list.


Code:
I+1->I
augment(|LLOC1,{0->|LLOC1
augment(|LLOC2,{0->|LLOC2
augment(|LLOC3,{0->|LLOC3


Middle of the function
Inside the function, you can reference the input value using |LLOC1(I-1) and specify the next input value using |LLOC1(I) before calling the function recursively. You can access other local variables using |LLOC2(I) and |LLOC3(I). To specify the return values of the function, assign them to a variable (I called it "R").


Code:

If |LLOC1(I-1)<=2
Then
   1->R
Else
   |LLOC1(I-1)-1->|LLOC1(I)
   prgmFIB
   Ans->|LLOC2(I)
   
   |LLOC1(I-1)-2->|LLOC1(I)
   prgmFIB
   Ans->|LLOC3(I)

   |LLOC2(I)+|LLOC3(I)->R
End


End of the function
Before you assign "R" to "Ans" (by putting "R" on the last line of the function) and return to the caller, remember to decrement "I" and pop off the current local scope (I did I->dim(|LLOC1) for each local variable including the input variable). The best variable to use is "Ans" because it can take on whatever value and variable type you want, so the program doesn't have a specific variable hard-coded in. This is especially important because variables are shared by every program. Notice that we always pair up the operations: increment "I" and decrement "I", append to list and pop the list. This pairing prevents you from overwriting results from previous function calls and ensures no memory leaks.


Code:

I-1->I
I->dim(|LLOC1)
I->dim(|LLOC2)
I->dim(|LLOC3)

R // implicitly assign "R" to "Ans"


Full Code in TI-BASIC
The full code for a recursive Fibonacci function. Try out the code here

Main program:

Code:
{10}->|LLOC1 // input variable specifying the nth fibonacci number, here n = 10
// local variables
{0}->|LLOC2
{0}->|LLOC3
1->I
prgmFIB
Disp Ans


recursive Fibonacci function:

Code:
I+1->I
augment(|LLOC1,{0->|LLOC1
augment(|LLOC2,{0->|LLOC2
augment(|LLOC3,{0->|LLOC3

If |LLOC1(I-1)<=2
Then
   1->R
Else
   |LLOC1(I-1)-1->|LLOC1(I)
   prgmFIB
   Ans->|LLOC2(I)
   
   |LLOC1(I-1)-2->|LLOC1(I)
   prgmFIB
   Ans->|LLOC3(I)

   |LLOC2(I)+|LLOC3(I)->R
End
I-1->I
I->dim(|LLOC1)
I->dim(|LLOC2)
I->dim(|LLOC3)

R


Rewrite in JavaScript
For those who are familiar with JavaScript, Java, or C-family syntaxes, I rewrote the exact same function in JavaScript so it's easier to understand:

Main program

Code:

// initialize fibRecursive
let ans = 0
let i = 0
let loc1 = [10]
let loc2 = [0]
let loc3 = [0]

fibRecursive()

console.log(ans)


recursive Fibonacci function:

Code:

function fibRecursive() {
    i = i + 1
    loc1.push(0)
    loc2.push(0)
    loc3.push(0)
    if (loc1[i-1] <= 2) {
        ans = 1
    } else {
        loc1[i] = loc1[i-1]-1
        fibRecursive()
        loc2[i] = ans
       
        loc1[i] = loc1[i-1]-2
        fibRecursive()
        loc3[i] = ans
       
        ans = loc2[i] + loc3[i]
    }
    loc1.pop()
    loc2.pop()
    loc3.pop()
    i = i - 1
}


Iterative Fibonacci in TI-BASIC
You will use the same local variable approach but write loops instead of recursions. Iterations are magnitudes faster and cost far less memory than recursions in TI-BASIC. Try out the code here

Main program:

Code:
// The previous of previous Fibonacci number
{1->|LLOC1
// The previous Fibonacci number
{1->|LLOC2
// The current Fibonacci number
{1->|LLOC3
// Start the loop counter at 2
// The first and second Fibonacci numbers are defined to be 1 so no looping needed.
{2->|LLOC4
1->I
10->N // get the 10th Fibonacci number

prgmFIB

Disp Ans


Iterative Fibonacci function:

Code:
While |LLOC4(I)<N
        // calculate current Fibonacci number
        |LLOC1(I)+|LLOC2(I)->|LLOC3(I) // current = previousOfPrevious + previous
        // advance one step
        |LLOC2(I)->|LLOC1(I) // previousOfPrevous = previous
        |LLOC3(I)->|LLOC2(I) // previous = current
        // increment counter
        |LLOC4(I)+1->|LLOC4(I)
End

|LLOC3(I) // assign result to "Ans"


Rewrite iteractive Fibonacci in JavaScript

Main program:

Code:

// initialize fibIterative
let ans = 0
let n = 10

fibIterative()

console.log(ans)


Iterative Fibonacci function:

Code:

function fibIterative() {
    let prevPrev = 1
    let prev = 1
    let curr = 1
    let i = 2
    while (i < n) {
        curr = prevPrev + prev
        prevPrev = prev
        prev = curr
        i = i + 1
    }
    ans = curr
}


I hope that this post will help people write functions, especially recursive ones, in TI-BASIC. Also, I'd like to hear if there are ways to optimize the code.
It is rather disappointing TI-BASIC can't make full use of recursion. The fake local variables solution is about the best you have, as you have shown (though I would lean toward shorter list names to save on those sweet sweet bytes), although in some rare occasions you can actually get away without using those lists.

For example, a simple factorial function, where the input must initially be stored in N right before the first call:

Code:
PROGRAM:FACT
:DS<(N,1
:NAns
:If N
:prgmFACT

which takes advantage of the fact that DS<( doesn't change Ans. This approach is theoretically viable as long as you're only doing single recursion. Computing Fibonacci numbers the usually way, though, spawns a tree of recursive calls, so you're SOL unless you use the "local" lists.
Yes. It's quite disappointing because recursion is such an elegant solution to many problems. Your factorial example is interesting and I will definitely shorten the local variable name.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are GMT - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement