Programming with array and flag

Discuss your code, get questions answered

Programming with array and flag

Postby d_motto » Thu Aug 30, 2012 1:45 pm

Oliver and others:

OK, I looked at my Period code and realized why it wasn't complete. Period attempts to find the period of a fraction by figuring out where the fraction starts repeating, using the modsto function: For the number n, 1/n repeats with a period length of r in this situation: For integer n, find the smallest integer r where 10^r = 1 mod n.
Now, this can lead to three results: either you will reach a situation where modsto gives you 0, in which case the invese of n terminates (e.g. 1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100), or modsto will reach 1, and it will return the period of the inverse (e.g. 3 (1), 7 (6), 9 (1), 11 (2) and so on), or it will loop, reaching neither 0 nor 1 (for example 6, which loops on the number 4).

Here is the original program:

≪ =:n @dup 1 - 1 @swap FOR x 10 x n modpow @dup IF 0 == THEN @drop "=terminates" @tag BREAK END IF 1 == THEN x "=period" @tag BREAK END NEXT ≫

I decided I wanted to handle the third case, so I added a little to my program, but it doesn't work:

[] =a 0 SF =:n @dup 1 - 1 @swap FOR x 10 x n modpow @dupdup a + =a IF 0 == THEN @drop "=terminates" @tag 0 CF BREAK END IF 1 == THEN x "=period" @tag 0 CF BREAK END NEXT IF 0 FS? THEN a size =:z 1 @swap 1 - FOR x x 1 + z FOR y IF a[x] a[y] == THEN y x - "=period" @tag 0 CF BREAK END NEXT IF 0 FS? THEN NEXT ELSE BREAK END

I have attempted to highlight the added code, but essentially I am doing this: An array variable (thanks Oliver!) called a will hold the results of the modpow function, and flag 0 will be set while the answer has NOT been found, and cleared when it has been found (all rational fractions either terminate or repeat with a period).

So, the first thing I do is set the array up and set flag 0.
Next, I store the number in n and leave it in the stack, subtract 1 from it and start a loop from 1 to that number. The loop index is x.
In the loop, I try to find the answers with the modpow function, and duplicate them twice in the stack (I changed @dup to @dupdup) so I can add the result to the array (a + =a) as well as checking whether it equals 0 or 1.
If it equals 0, I drop the result of modpow and append the tag "=terminates" to the number I started with, and clear the flag before I break out of the loop.
If it equals 1, I append the tag "=period" to the result of modpow and clear the flag before I break out of the loop.
Otherwise, I continue to the end of the loop and set up to look for the "repeats" option.
I figure out the length of the array (size) and store that in z, then start two loops (counters x and y), the first looks at the items from the array from 1 to z-1 and the second from x+1 to z. If the same number is found in positions x and y, I compute y-x as the period, tag it with "=period", clear the flag and break out of the inner loop. At the end of the inner loop, I check to see if the flag is still set; if so, I end the outer loop, otherwise I break out.

Here is what happens when I attempt this: A message comes up that says:
Program execution error
Detail: Result of expression "I.apply"
[undefined] is not a function.

I can't make out if it is the letter capital i or the letter lowercase L in the message.

In the stack are the original number (level 2) and the number 0 (level 1).

I believe the problem comes about in the first loop, where I am attempting to append the result of modpow to the variable a. That might only be my first problem, though.

Any ideas on this? And, can you point me to where I could figure out error messages?

Thanks...

Dave Motto
d_motto
 
Posts: 35
Joined: Tue Apr 17, 2012 9:19 am

Re: Programming with array and flag

Postby d_motto » Fri Aug 31, 2012 4:52 pm

OK, I rewrote it in JavaScript...

Code: Select all
function (n) { /* as is */
  var a = [] ;
  for (var x = 1; x<= n; x++) {
     var w = calculator.functions.modpow (10, x, n) ;
     a.push(w) ;
     if (w == 0) {
        return -x ;
     }
     if (w == 1) {
        return x ;
     }
  }
     var z = a.length ;
     for (x = 0; x<z-1; x++) {
        for (var y = x+1; y < z; y++) {
           if (a[y] == a[x]) {
              var v = y - x ;
              var u = x + 2 ;
              return v ;
           }
        }
     }
}


Since I couldn't figure out how to get @tag to work, I elected to omit it from this version; instead, it returns the period length for repeating numbers, or the negated length of a decimal that terminates. I am considering returning a vector with the length of the nonrepeating part followed by the length of the repeating part; 12 would return [2 1] because 1/12 is about 0.083333333333333 etc.

Dave Motto
d_motto
 
Posts: 35
Joined: Tue Apr 17, 2012 9:19 am

Re: Programming with array and flag

Postby oliver » Fri Aug 31, 2012 10:33 pm

Dave,

It looks like CF is broken. (I tried 0 CF which gives the error you're reporting.) Will look into that and amend this post if there's a quick fix for it.
In the interim, using a local and assigning it true or false should do the trick.

For debugging RPL, have you tried adding the command HALT anywhere in the program and then single-stepping?

To use @tag from JavaScript, do
Code: Select all
ME["@tag"](x, "=period");

or
Code: Select all
TaggedObject.fromNameAndObj("=period", x);


Instead of calculator.functions.modpow, you may also write ME.modpow, which is easier to type.

Period detection is a very nice function.

Adding a single item to an array with the + operator is fine and will work, though you can also use the command append, which is a bit clearer and will also appends a n-dim vector to an n-dim vector, whereas +, in that case only, do a vector addition.

Cheers.
oliver
Site Admin
 
Posts: 433
Joined: Sat May 01, 2010 2:11 pm


Return to Programming

Who is online

Users browsing this forum: Google [Bot] and 1 guest

cron