Translated using translate google. The original language is Russian. Original page https://hi-aga.ru/index.php/homepage/for-1-10

A new group of problems in which we will use the standard loop construction with a counter is denoted in many languages ​​by FOR (this is the word we use to denote the examples in this series). In Forth it is described by two words "DO" and "LOOP". The first takes two numbers from the stack - the boundaries of the loop parameter, the second increases the counter by one and ends the iteration. The upper limit comes first, then the lower limit inclusive. By definition, the loop ends when the loop parameter passes through the interval "upper bound minus one" - "upper bound".

First example. Print the given integer N times.

: FOR1 ( K N>0 -> ) 0 \ K N>0 -> K N>0 0, - add zero, lower bound
DO \ K N>0 0 -> K, “DO” removed two numbers from the stack – “loop range boundaries”
    DUP. \ K -> K – we simply duplicate the body of the loop and print it on the screen
LOOP
DROP; \ delete "K" clear the stack after itself

The word "DO" takes the top two numbers (N>0 0) from the stack, leaving only "K", which is duplicated in the body of the loop and printed from zero to "N-1" times, i.e. N times exactly.

Test the word "FOR1":

100 5 FOR1
100 100 100 100 100 Ok

The written word works according to the conditions of the task.

In example two, we print all the numbers from A to B inclusive (A<B) and the number of these numbers.

: FOR2 ( A B -> ) \ {A<B}
1+ SWAP \ A B -> B+1 A
2DUP - \ B+1 A -> B+1 A B+1-A=N
." N= " . CR \ B+1 A N -> B+1 A - print N
DO
    I. \ in a loop we print each iteration from A to B
LOOP;

We add one to “B” and swap places with “A”, this is necessary for “DO” to work correctly. The word "2DUP" duplicates the top two elements, and their difference gives the value "N", which is printed on the fourth line. Next in the loop, the word “I” iterates through all the numbers from A to B and they are printed here.

Word test "FOR2":

11 17 FOR2
N= 7
11 12 13 14 15 16 17 Ok

In example three, we display the numbers in descending order from B to A, not inclusive, and their number. To do this, we use a modified version of the loop with the parameter "DO <code> -1 +LOOP". The word "+LOOP" takes a number from the stack, in this case "-1", and adds it to the counter, so we iterate through numbers not in ascending, but in descending order (in general, instead of "-1" there can be any integer) . And the boundaries will also be in the reverse order (we start from the larger B-1 to the smaller A+1). We reduce “B” by one - the lower limit (not inclusive) and here we calculate “N” which is equal to “B-1-A” and print this on the next line.
Next, we prepare the boundaries of the loop parameter by increasing “A” by one. Range (“A-1”-1; “A-1”) = (11;12) the cycle jumps and stops at “11” (as indicated by the condition), not inclusive of “A” (for this it was necessary to subtract one from "A").

: FOR3 ( A B -> ) \ {A<B}
1- 2DUP SWAP - \ A B -> A B-1 B-1-A=N
." N= " . CR \ A B-1 N -> A B-1, - print N
SWAP 1+ SWAP \ A B-1 -> A+1 B-1
DO
    I. -1
+LOOP ;

The test of the "FOR3" example demonstrates its correct operation:

11 17 FOR3
N= 5
16 15 14 13 12 Ok

Example four. In a cycle we print the price from one to ten kg of candies. We simply run the cycle ten times (from 1 to 10), and inside we multiply the price by the “I” parameter of the cycle, obtaining the corresponding cost of “I” kg of candy, printing the result.

: FOR4 ( R -> ) \ 1.1E FOR4 – word work format
11 1 DO
    "Cost" I. "kg of sweets: "
    FDUP \ duplicate “R” price of candies
    I 0 D>F \ “I” is converted into a double precision number and sent to the real stack
    F* F. CR \ multiply “R” by “I” and print 1*R 2*R ... 10*R
LOOP FDROP ; \ remove “R” from the real stack, clear the stack after ourselves

Test for the price of sweets 1.1 per kg:

1.1E FOR4
Cost of 1 kg of sweets: 1.1000000
Cost of 2 kg of sweets: 2.2000000
Cost of 3 kg of sweets: 3.3000000
Cost of 4 kg of sweets: 4.4000000
Cost of 5 kg of sweets: 5.5000000
Cost of 6 kg of sweets: 6.6000000
Cost of 7 kg of sweets: 7.7000000
Cost of 8 kg of sweets: 8.8000000
Cost of 9 kg of sweets: 9.9000000
Cost of 10 kg of sweets: 11.000000
 Ok

And now the second version of the same example (without multiplication):

: FOR4 ( R -> ) \ 1.1E FOR4 – word work format
0E \ add "0" to the real stack as an adder
11 1 DO
    "Cost" I. "kg of sweets: "
    FOVER F+ \ R Sum -> R Sum+R
    FDUP F. CR \ duplicate and print (Sum+R), i.e. 1*R 2*R ... 10*R
LOOP FDROP FDROP ; \ remove “R” and “Sum”

The test gives identical results, check it yourself. The second option is preferable, since addition is a faster operation than multiplication and for large numbers of iterations - this can be noticeable in time.

Example five. We get it from the previous example by dividing the price by ten (here we divide the iterator “I” by ten, we get the same effect).

: FOR5 ( R -> ) \ 1.2E FOR5 – word work format
11 1 DO
    FDUP I 0 D>F 10E F/ FDUP \ R -> R R 0.1*I
    ." Cost " F. ." kg of sweets: "
    F* F. CR \ Cost 0.1*R 0.2*R ... 1*R kg of candy
LOOP;

The test gives the following result:

1.2E FOR5
Стоимость 0.1000000 кг конфет: 0.1200000
Стоимость 0.2000000 кг конфет: 0.2400000
Стоимость 0.3000000 кг конфет: 0.3600000
Стоимость 0.4000000 кг конфет: 0.4800000
Стоимость 0.5000000 кг конфет: 0.6000000
Стоимость 0.6000000 кг конфет: 0.7200000
Стоимость 0.7000000 кг конфет: 0.8400000
Стоимость 0.8000000 кг конфет: 0.9600000
Стоимость 0.9000000 кг конфет: 1.0800000
Стоимость 1.0000000 кг конфет: 1.2000000
 Ok

You can independently rewrite the code with the sum, as in the previous case, thus significantly reducing the number of operations in the loop.

Example six. Continuation of the series with another step. Everything is the same, we only change the limits and iteration step. The body of the loop is one to one as in example five.

: FOR6 ( R ->) ( 1.2E FOR6 )
22 12 DO
    FDUP I 0 D>F 10E F/ FDUP ." Cost " F. ." kg of candy: "
    F* F. CR \ Cost 1.2*R 1.4*R ... 2*R kg of sweets
2 +LOOP ;

Also optimize the code yourself.

Example seven. We calculate the sum of numbers from “A” to “B” inclusive.

: FOR7 ( A B -> )  \ A<B
1+ SWAP            \ A B -> B+1 A
0 ROT ROT          \ B+1 A -> 0 B+1 A – пределы цикла, «0» начальное значение суммы
DO
    I +
LOOP . ;

In the second line, from “A” and “B” we get the limits of the loop, add one to “B” to get the upper limit inclusive and swap them, since according to Forth syntax the upper limit comes first, and then the lower. In the third, we add zero to the stack - the amount where the final result will be stored, and move the loop limits to the “top” to start the loop, which starts from line four and ends at line six, after “LOOP” we display the result (operator dot “.”). The body of the loop – the fifth line simply adds the value of the loop parameter “I” to the current amount.

Since the sum of numbers from “A” to “B” inclusive is an arithmetic progression, it can be calculated using the formula (a1+an)*n/2. We can rewrite the “FOR7” example:

: FOR7 ( A B -> ) \ A<B
2DUP 1+ SWAP - \ A B -> A B B+1-A=n
ROT ROT + * 2/ \ A B n -> n*(A+B)/2
. ; \ end – output the result

Since this is a series of examples with a loop, only the first option is suitable for training purposes, but it is useful to know about the alternative, because in the first one a large number of additions can be performed, and in the second a constant number of operations.

Both options give the same result on test data:

1 10 FOR7
55 Ok
1 100 FOR7
5050 Ok
1 1000 FOR7
500500 Ok
1 10000 FOR7
50005000 Ok
1 100000 FOR7
705082704 Ok

Please note that for the amount from 1 to 100,000, the usual 32 bits are no longer enough, the result 5,000,050,000 does not fit in it, and as a result we see the wrong result. So be careful in your experiments. An incorrect result is not yet a sign that the code is incorrect. In this case, we can work with double-length numbers, but they also have their own size limitations.

Example eight. We obtain from the previous one by replacing the addition operation with multiplication and replacing the zero of the adder with one (the initial value of the final product).

: FOR8 ( A B -> ) \ A<B
1+ SWAP \ A B -> B+1 A
1 ROT ROT \ B+1 A -> 1 B+1 A – chicle limits, “1” final product
DO
    I*
LOOP. ;

Test of the eighth example:

1 3 FOR8
6 Ok
1 4 FOR8
24 Ok
1 5 FOR8
120 Ok
1 6 FOR8
720 Ok
10 15 FOR8
3603600 Ok

If we enter the first parameter equal to one, we obtain the factorial of the second limit.

Example nine. Now we calculate the sum of the squares of the numbers from “A” to “B” inclusive. Just as in the previous case, we get seven from example. Just sum up the squares of the numbers between “A” and “B”.

: FOR9 ( A B -> ) \ A<B
1+ SWAP \ A B -> B+1 A
0 ROT ROT \ B+1 A -> 0 B+1 A – cycle limits, “0” sum
DO
    I DUP * + \ Sum= Sum+I^2
LOOP. ;

Test for example nine:

1 1 FOR9
1 Ok
1 2 FOR9
5 Ok
1 3 FOR9
14 Ok
1 4 FOR9
30 Ok
1 5 FOR9
55 Ok
1 6 FOR9
91 Ok

Example ten. We calculate the sum of the reciprocal numbers of the natural series, the result itself is obtained as a real number.

: FOR10 ( I: N>0 -> ) \ 1+1/2+1/3+1/N
1+ 1 \ I: N -> N+1 1 – loop limits on the integer stack from 1 to N
0E\F: 0 = Sum – the sum of the series
DO
    1E I 0 D>F F/ F+ \ F: Sum=Sum+1/I
LOOP F. ;

Test of the above code:

1 FOR10
1.0000000 Ok
2 FOR10
1.5000000 Ok
3 FOR10
1.8333333 Ok
4 FOR10
2.0833333 Ok
5 FOR10
2.2833333 Ok
6 FOR10
2.4500000 Ok
7 FOR10
2.5928571 Ok