First of all, credit to Simon Hutchinson @ RPGPGM.com and the article ‘Calculating prime numbers in RPG’ for reminding me of this.

8 years ago, when I was first learning RPG (and had slightly more hair than I do now, not sure if those two factors are related!) I decided to test some of what I’d learned by writing a program for the Collatz Conjecture.

According to Wikipedia:

*The Collatz conjecture is a conjecture in mathematics
that concerns a sequence defined as follows: start with any positive integer n.
Then each term is obtained from the previous term as follows: if the previous
term is even, the next term is one half of the previous term. If the previous
term is odd, the next term is 3 times the previous term plus 1. The conjecture
is that no matter what value of n, the sequence will always reach 1.*

Personally, I prefer the xkcd definition:

*The Collatz Conjecture states that if you pick a number,
and if it’s even divide it by two and if it’s odd multiply it by three and add
one, and you repeat this procedure long enough, eventually your friends will
stop calling to see if you want to hang out.*

(un)fortunately I can’t find the original source despite digging through my old system saves, was written when I was learning RPG III so I imagine it would look atrocious.

The basic loop of the RPG IV version that I could find:

*C
Move(P) P#Input WK#Result *

*C
Dou Output = 1 *

*C
Eval InputNo = WK#Result *

*C
If %REM(WK#Result:2) = 1
C Eval Output = ((WK#Result*3)+1)
C Else
C Eval
Output = (WK#Result/2)
C EndIf
C Eval WK#Result = Output *

*C
Eval OutputNo = OutPut
C Eval
Counter = Counter + 1
C Eval StepNo = Counter *

*C
Write CALCR
*

*C
EndDo *

So, take a number and check does it have a remainder when you /2? Thus, you know if it’s odd (in which case * 3 + 1) or even (in which case /2). Write to a workfile (CL in front setting it up not shown here) and repeat until you hit 1. InputNo/OutputNo/StepNo are my fields on the workfile.

Given that I like to think I’ve learned more since then, it seems a perfect time to update into a slightly more modern style. First off let’s convert it to free-format:

* WK#Result =
%dec(P#Input:10:0);*

* DOU Output
= 1;*

* InputNo =
WK#Result;*

* IF
%REM(WK#Result:2) = 1;
Output = ((WK#Result*3)+1);
ELSE;
Output = (WK#Result/2);
ENDIF;*

* WK#Result
= Output;*

* OutputNo
= OutPut;
StepNo = Counter;
Counter = Counter + 1;*

* WRITE
CALCR;*

* ENDDO;*

That looks a little nicer (yes, I’m lazy so the input is character for ease of typing on the command line.)

However, given that I’ve been playing with nodejs recently I wonder what it would look like there? I also fancy actually outputting my results on a screen rather than a file that I then query.

*function collatzcalc(){*

* // Start off by
getting input value*

* var StartValue
= document.getElementById(“Start”).value;
var Steps = 0;
var resultstext = “”;*

* // Test if
we’ve been given a number, if not then no point doing anything else
if (isNaN(StartValue) || StartValue
== ”) {
document.getElementById(“results”).value = “Not a
number”;
}*

* else {
// Actual processing of calculation
// No point processing if we’ve been
given < 1 as a value
if (StartValue >= 1)
{
var Conjecture =
function(value,callback)
{
var outvalue = 0;
var remain = value % 2;
if (remain != 0) {
var outvalue = (value
* 3) + 1;
return
callback(outvalue);
}
else {
var outvalue = value
/ 2;
return
callback(outvalue);
}
}*

* do {
Steps ++;
Conjecture(StartValue,function(outvalue){
resultstext +=
“Step Number: ” + Steps + “, results in value: ” + outvalue
+ “\n”;
StartValue =
outvalue;
});
}
while (StartValue != 1);
document.getElementById(“results”).value = resultstext;
}
// We’ve been given a number <
1 so cannot process
else {
document.getElementById(“results”).value = “No
processing, invalid start number”;
}
}
}*

Ignoring the fact that I’m god awful at UI design this works quite nicely:

The main thing I might want to improve upon is the validation (would be nice to take the isNaN out and check it before we get here, maybe the >= 1 as well) and maybe add in an option to download to CSV (I’m sure I have a Scott Klement example kicking around somewhere….)

I wonder what other languages I’ll convert it to in the future, and/or if anyone has any suggestions for improvement. Do you have any pet programs you come back to when you’re learning a language / want to practise a new trick?

## Leave a Reply