Forth code formatting guide - code-formatting

I am trying to teach myself Forth by doing Project Euler exercises. I've looked into several tutorials, but I couldn't find any definitive guide as to how to position keywords / control structures. Emacs forth-mode seems to have some idea about how the code should be formatted, but I am not really convinced about what I see :) So, for example, the code below:
: euler1
0 1000 0
do i dup 3 mod -rot 5 mod -rot -rot * 0=
if i + then
loop ;
Does it make sense to format it this way? Where'd you put conditions? If there's any kind of style guide / a collection of examples, which, you believe, are properly formatted, could you please refer me to that example?

As a beginner, please do yourself a favor and thoroughly comment your code, like:
1 : euler1 ( -- n )
2 0 ( n )
3 1000 0 ( n HI-limit LO-index )
4 DO ( n )
5 I DUP ( n i i )
6 3 MOD ( n i mod3 )
7 -ROT ( mod3 n i )
8 5 MOD ( mod3 n mod5 )
9 -ROT ( mod5 mod3 n )
10 -ROT ( n mod5 mod3 )
11 * ( n mod5*mod3 )
12 0= ( n flag )
13 IF
14 i + ( n+i )
15 THEN
16 LOOP
17 ;
You'll see that:
at lines 9,10 -ROT -ROT could be resumed with simple ROT
it is not necessary to use ROT -ROT that juggle 3 items on data stack
and could just simple use SWAP like: 3 MOD SWAP 5 MOD
more yet you could avoid stack juggling and write: I 3 MOD I 5 MOD
I would write that:
: div? ( a b -- f ; b DIVIDES a ? )
mod 0=
;
: euler1.1 ( -- n )
0
1000 0
DO ( n )
I 3 div? I 5 div? OR
IF
I +
THEN
LOOP
;

If you mean formatting in the sense of where the whitespace should go, your example seems pretty reasonable; indentation for loops and words makes the code fairly readable for people more used to languages where indentation or brackets are required.
My style preference would be more like the code below, but I am not sure what you code is doing so I may have arranged it in a way that does not make perfect sense. In general I would put the conditions for a conditional on a new line along with the keyword, and if the condition is complicated I would factor it out into its own word (add-i? below).
: add-i?
dup 3 mod -rot 5 mod -rot -rot * 0= ;
: euler1
0
1000 0 do
i add-i? if
i +
then
loop ;
It can be a little unintuitive to have the starting keyword of a conditional block or loop at the end of the first line, but I sort of think of it as a visual cue similar to the way Python uses a : to enter an indented region (or how Visual Basic uses Then (see the second example)), e.g.
if true:
print("True")
The thens and loops are the equivalents of closing curly brackets or keywords like End If in Visual Basic e.g.
If True Then
MsgBox "True"
End If
(which is a slightly confusing example as the use of Then is different to its use in Forth)

A lot of the forth written today has C inspired formatting.
The classic, and (I think) clearest way to format Forth is to align corresponding or related things.
When corresponding pieces are aligned the code is easier to walk through and may expose a common factor that can be pulled out into its own word. Here's a snippet from my forth-crypt library.
\ RSA Digital Signature ( Notice the spacing )
: signat ( addr-c # -- s ) djb2a pub-key N rsa ;
: verify ( s addr-c # -- f ) djb2a swap prv-key N rsa = ;
It's now easy to see that ( N rsa ) is a factor that could be broken-out into another word if desired.
Another style point is, lookahead/parsing words should be flush to the left and regular postfix words are flush to right like so:
: P#REL ( -- PadLast ) FF CR1! DATA# REL ;
: P!REL ( PadLast -- ) FF CR1! DATA! REL ;

Related

Repeating numbers with modulo -1 to 1 using positive and negative numbers

Repeating numbers with modulo
I know I can "wrap" / loop numbers back onto themselves like 2,3,1,2,3,1,...
by using modulo.
Example code below.
a=[1:8]'
b=mod(a,3)+1
But how can I use modulo to "wrap" numbers back onto themselves from -1 to 1 (-1,-.5,0,.5,1). Some test numbers would be a=[1.1,-2.3,.3,-.5] it would loop around and the values would be between -1 to 1.
I guess a visual example would be bending an x,y plane from -1 to 1 into a torus (how it loops back onto itself).
I was thinking of how a sin wave goes 0,1,0,-1 and back again but I wasn't sure how I could implement it.
PS: I'm using Octave 4.2.2
This can be accomplished by offsetting the value before taking the modulo, then reversing the offset after.
For example, if the target range is [a,b) (the half-open interval such that b is not part of the interval), then one can do:
y = mod( x - a, b - a ) + a;
For example:
a = -1;
b = 1;
x = -10:0.01:10;
y = mod( x - a, b - a ) + a;
plot(x,y)

Shuffle data in a repeatable way (ability to get the same "random" order again)

This is the opposite of what most "random order" questions are about.
I want to select data from a database in random order. But I want to be able to repeat certain selects, getting the same order again.
Current (random) select:
SELECT custId, rand() as random from
(
SELECT DISTINCT custId FROM dummy
)
Using this, every key/row gets a random number. Ordering those ascending results in a random order.
But I want to repeat this select, getting the very same order again. My idea is to calculate a random number (r) once per session (e.g. "4") and use this number to shuffle the data in some way.
My first idea:
SELECT custId, custId * 4 as random from
(
SELECT DISTINCT custId FROM dummy
)
(in real life "4" would be something like 4005226664240702)
This results in a different number for each line but the same ones every run. By changing "r" to 5 all numbers will change.
The problem is: multiplication is not sufficient here. It just increases the numbers but keeps the order the same. Therefore I need some other kind of arithmetic function.
More abstract
Starting with my data (A-D). k is the key and r is the random number currently used:
k r
A = 1 4
B = 2 4
C = 3 4
D = 4 4
Doing some calculation using k and r in every line I want to get something like:
k r
A = 1 4 --> 12
B = 2 4 --> 13
C = 3 4 --> 11
D = 4 4 --> 10
The numbers can be whatever they want, but when I order them ascending I want to get a different order than the initial one. In this case D, C, A, B, E.
Setting r to 7 should result in a different order (C, A, B, D):
k r
A = 1 7 --> 56
B = 2 7 --> 78
C = 3 7 --> 23
D = 4 7 --> 80
Every time I use r = 7 should result in the same numbers => same order.
I'm looking for a mathematical function to do the calculation with k and r. Seeding the RAND() function is not suitable because it's not supported by some databases we support
Please note that r is already a randomly generated number
Background
One Table - Two data consumers. One consumer will get random 5% of the table, the other one the other 95%. They don't just get the data but a generated SQL. So there are two SQL's which must not select the same data twice but still random.
You could try and implement the Multiply-With-Carry PseudoRandomNumberGenerator. The C version goes like this (source: Wikipedia):
m_w = <choose-initializer>; /* must not be zero, nor 0x464fffff */
m_z = <choose-initializer>; /* must not be zero, nor 0x9068ffff */
uint get_random()
{
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w; /* 32-bit result */
}
In SQL, you could create a table Random, with two columns to contain w and z, and one ID column to identify each session. Perhaps your vendor supports variables and you need not bother with the table.
Nonetheless, even if we use a table, we immediately run into trouble cause ANSI SQL doesn't support unsigned INTs. In SQL Server I could switch to BIGINT, unsure if your vendor supports that.
CREATE TABLE Random (ID INT, [w] BIGINT, [z] BIGINT)
Initialize a new session, say number 3, by inserting 1 into z and the seed into w:
INSERT INTO Random (ID, w, z) VALUES (3, 8921, 1);
Then each time you wish to generate a new random number, do the computations:
UPDATE Random
SET
z = (36969 * (z % 65536) + z / 65536) % 4294967296,
w = (18000 * (w % 65536) + w / 65536) % 4294967296
WHERE ID = 3
(Note how I have replaced bitwise operands with div and mod operations and how, after computing, you need to mod 4294967296 to stay within the proper 32 bits unsigned int range.)
And select the new value:
SELECT(z * 65536 + w) % 4294967296
FROM Random
WHERE ID = 3
SQLFiddle demo
Not sure if this applies in non-SQL Server, but typically when you use a RAND() function, you can specify a seed. Everytime you specify the same seed, the randomization will be the same.
So, it sounds like you just need to store the seed number and use that each time to get the same set of random numbers.
MSDN Article on RAND
Each vendor has solved this in its own way. Creating your own implementation will be hard, since random number generation is difficult.
Oracle
dbms_random can be initialized with a seed: http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_random.htm#i998255
SQL Server
First call to RAND() can provide a seed: http://technet.microsoft.com/en-us/library/ms177610.aspx
MySql
First call to RAND() can provide a seed: http://dev.mysql.com/doc/refman/4.1/en/mathematical-functions.html#function_rand
Postgresql
Use SET SEED or SELECT setseed() : http://www.postgresql.org/docs/8.3/static/sql-set.html

J: Why does `f^:proposition^:_ y` stand for a while loop?

As title says, I don't understand why f^:proposition^:_ y is a while loop. I have actually used it a couple times, but I don't understand how it works. I get that ^: repeats functions, but I'm confused by its double use in that statement.
I also can't understand why f^:proposition^:a: y works. This is the same as the previous one but returns the values from all the iterations, instead of only the last one as did the one above.
a: is an empty box and I get that has a special meaning used with ^: but even after having looked into the dictionary I couldn't understand it.
Thanks.
Excerpted and adapted from a longer writeup I posted to the J forums in 2009:
while =: ^:break_clause^:_
Here's an adverb you can apply to any code (which would equivalent of the
loop body) to create a while loop. In case you haven't seen it before, ^: is the power conjunction. More specifically, the phrase f^:n y applies the function f to the argument y exactly n times. The count n maybe be an integer or a function which applied to y produces an integer¹.
In the adverb above, we see the power conjunction twice, once in ^:break_clause and again in ^:_ . Let's first discuss the latter. That _ is J's notation for infinity. So, read literally, ^:_ is "apply the function an infinite number of times" or "keep reapplying forever". This is related to a while-loop's function, but it's not very useful if applied literally.
So, instead, ^:_ and its kin were defined to mean "apply a function to its limit", that is, "keep applying the function until its output matches its input". In that case, applying the function again would have no effect, because the next iteration would have the same input as the previous (remember that J is a functional language). So there's
no point in applying the function even once more: it has reached its limit.
For example:
cos=: 2&o. NB. Cosine function
pi =: 1p1 NB. J's notation for 1*pi^1 analogous to scientific notation 1e1
cos pi
_1
cos cos cos pi
0.857553
cos^:3 pi
0.857553
cos^:10 pi
0.731404
cos^:_ pi NB. Fixed point of cosine
0.739085
Here, we keep applying cosine until the answer stops changing: cosine has reached its fixed point, and more applications are superfluous. We can visualize this by showing the
intermediate steps:
cos^:a: pi
3.1415926535897 _1 0.54030230586813 ...73 more... 0.73908513321512 0.73908513321
So ^:_ applies a function to its limit. OK, what about ^:break_condition? Again, it's the same concept: apply the function on the left the number of times specified by the function on the right. In the case of _ (or its function-equivalent, _: ) the output is "infinity", in the case of break_condition the output will be 0 or 1 depending on the input (a break condition is boolean).
So if the input is "right" (i.e. processing is done), then the break_condition will be 0, whence loop_body^:break_condition^:_ will become loop_body^:0^:_ . Obviously, loop_body^:0 applies the loop_body zero times, which has no effect.
To "have no effect" is to leave the input untouched; put another way, it copies the input to the output ... but if the input matches the output, then the function has reached its limit! Obviously ^:_: detects this fact and terminates. Voila, a while loop!
¹ Yes, including zero and negative integers, and "an integer" should be more properly read as "an arbitrary array of integers" (so the function can be applied at more than one power simultaneously).
f^:proposition^:_ is not a while loop. It's (almost) a while loop when proposition returns 1 or 0. It's some strange kind of while loop when proposition returns other results.
Let's take a simple monadic case.
f =: +: NB. Double
v =: 20 > ] NB. y less than 20
(f^:v^:_) 0 NB. steady case
0
(f^:v^:_) 1 NB. (f^:1) y, until (v y) = 0
32
(f^:v^:_) 2
32
(f^:v^:_) 5
20
(f^:v^:_) 21 NB. (f^:0) y
21
This is what's happening: every time that v y is 1, (f^:1) y is executed. The result of (f^:1) y is the new y and so on.
If y stays the same for two times in a row → output y and stop.
If v y is 0→ output y and stop.
So f^:v^:_ here, works like double while less than 20 (or until the result doesn't change)
Let's see what happens when v returns 2/0 instead of 1/0.
v =: 2 * 20 > ]
(f^:v^:_) 0 NB. steady state
0
(f^:v^:_) 1 NB. (f^:2) 1 = 4 -> (f^:2) 4 = 16 -> (f^:2) 16 = 64 [ -> (f^:0) 64 ]
64
(f^:v^:_) 2 NB. (f^:2) 2 = 8 -> (f^:2) 8 = 32 [ -> (f^:0) 32 ]
32
(f^:v^:_) 5 NB. (f^:2) 5 = 20 [ -> (f^:0) 20 ]
20
(f^:v^:_) 21 NB. [ (f^:0) 21 ]
21
You can have many kinds of "strange" loops by playing with v. (It can even return negative integers, to use the inverse of f).

Relatively Prime numbers VB

I have this number x and i wanted to find all numbers which are relatively prime to it.
my code so far:
For i = 1 To x-1
if [number n is relatively prime to x] Then
ListBox1.Items.Add(x)
End If
Next
Thanks in advance
Two numbers are relatively prime if their greatest common divisor is 1. VB doesn't have the GCD function built-in, but the algorithm is simple enough (and about 2300 years old!):
function gcd(m, n)
while n > 0
m, n = n, m%n
return m
Note that m and n are assigned simultaneously. I'll leave it to you to complete the VB implementation. You might be interested in googling for the totient of a number and the list of its totatives, which is what you are calculating.
Assuming you want only numbers that are smaller than x, which are coprime with it - you could also take a generative approach, running a special kind of a sieve. When the multiples of each prime are generated, you'd see if that sequence "hits" your upper limit x or misses it, and mark all the numbers in it as non-coprimes if it does hit x.
Or in "pseudocode" (with Haskell syntax :) ),
coprimes n = go( [1..n-1], [2..n-1]) where
go( xs, [] ) = xs -- ' no more numbers to sieve - return xs
go( xs, p:ks ) = -- ' p is first in candidates, ks is the rest
let ms = [p, 2*p .. n-1] -- ' p's multiples
in
go( if ( (mod n p) == 0 ) -- ' is n a multiple of p ?
then (xs\\ms) -- ' yes: remove p's multiples
else xs, -- ' no: possible coprimes
ks\\ms ) -- ' candidates to sieve
Haskell's set difference \\ is very inefficient with unordered list representation of sets, but you would naturally encode this efficiently, on top of mutable arrays, in VB.

How would I do this in a program? Math question

I'm trying to make a generic equation which converts a value. Here are some examples.
9,873,912 -> 9,900,000
125,930 -> 126,000
2,345 -> 2,400
280 -> 300
28 -> 30
In general, x -> n
Basically, I'm making a graph and I want to make values look nicer. If it's a 6 digit number or higher, there should be at least 3 zeros. If it's a 4 digit number or less, there should be at least 2 digit numbers, except if it's a 2 digit number, 1 zero is fine.
(Ignore the commas. They are just there to help read the examples). Anyways, I want to convert a value x to this new value n. What is an equation g(x) which spits out n?
It is for an objective-c program (iPhone app).
Divide, truncate and multiply.
10**x * int(n / 10**(x-d))
What is "x"? In your examples it's about int(log10(n))-1.
What is "d"? That's the number of significant digits. 2 or 3.
Ahhh rounding is a bit awkward in programming in general. What I would suggest is dividing by the power of ten, int cast and multiplying back. Not remarkably efficient but it will work. There may be a library that can do this in Objective-C but that I do not know.
if ( x is > 99999 ) {
x = ((int)x / 1000) * 1000;
}
else if ( x > 999 ) {
x = ((int) x / 100) * 100;
}
else if ( x > 9 ) {
x = ((int) x / 10) * 10;
}
Use standard C functions like round() or roundf()... try man round at a command line, there are several different options depending on the data type. You'll probably want to scale the values first by dividing by an appropriate number and then multiplying the result by the same number, something like:
int roundedValue = round(someNumber/scalingFactor) * scalingFactor;