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

Now we solve a new group of problems with exclusively integer parameters. We will number all tasks with the prefix I, short for Integer, meaning an integer.

Example 1. Convert cm to m without rounding. Here you will see the beauty of the Fort.

Rm=Rcm/100 – integer

: I1 (Rcm -> Rm)
    100 /
;
503 I1
 OK (5)

Which means 503 cm contains 5 full meters.

Example 2. Differs from the previous one by replacing 100 with 1000.

Mt= Mkg/1000

: I2 (Mkg -> Mt)
    1000/
;
12683 I2
 OK (12)

12683 kg is 12 full tons.

Example 3. Also differs from the previous one by a constant. Now we change 1000 to 1024.

DkB=DB/1024

: I3 (DB -> DkB)
    1024/
;
2050 I3
 OK (2)

2050 B is 2 full kB.

Example 4. Also the simplest integer division problem.

To be specific, A>B, the result is A/B.

: I4 (A B -> A/B)
    /
;
15 4 I4
 OK (3)

A segment of length 15 contains 3 whole segments of length 4.

Example 5. Differs from the previous example by replacing integer division with taking the remainder of the division.

: I5 ( A B -> remainder {A/B} )
    MOD
;
15 4 I5
 OK (3)

15/4 – the remainder is 3 – everything is correct, the test result is correct.

Examples 1-5 are so simple that there is no need to create corresponding words. You can simply enter the number operand then the body of the word. You will get the result in brackets on the stack. To print it and not clog up the stack, click “.” and "Enter". Let's rewrite these examples for clarity.

"503 100/."
"12683 1000/."
"2050 1024 / ."
"15 4/."
"15 4 MOD."
But if you will often use the written code, it is highly advisable to create separate function words and also give them easy-to-remember, meaningful names.

Example 6. Print the number of tens and units of a two-digit number. To do this, we use the /MOD operation, which simultaneously calculates both the integer part and the remainder of the division.

: I6 (AB -> A B)
    10 /MOD SWAP
;
45 I6
 Ok (4 5)

To print in the same order as on the stack, let’s slightly change the code (remember that the top of the stack will be printed first, so we use the SWAP command before printing)

45 I6 SWAP. .
4 5 Ok

Theoretically, the final touch will be to format the output into a separate word, as mentioned earlier in the previous group of tasks, according to the scheme:

: I6. I6 SWAP. . ;

Now the task will finally be solved simply by calling one word with one argument:

45 I6.
4 5 Ok

The result is the same, but the solution looks more professional.

Of course, these two words can be combined into one according to the scheme:

: I6. 10 /MOD SWAP SWAP . . ;
: I6. 10 /MOD. . ;

Two words SWAP will no longer be needed, but this is not recommended for complex tasks; in addition, as was said earlier, it is highly desirable to separate the output interface and the logic of the algorithm, so a change in the code of one will not affect the other.

Example 7. Calculate the sum and product of the digits of a two-digit number. Further development of the previous example.

: I7 ( AB -> A+B A*B )
    10 /MOD\AB -> A B
    2DUP + \ A B -> A B A+B
    ROT ROT * \ A B A+B -> A+B A*B
;
45 I7
 Ok (9 20)

The sum of the digits of the number 45 is 4+5=9, and the product is 4*5=20, the test is correct.

If you are not satisfied with the result on the stack, you can write a word to display on the screen, similar to the previous example.

Example 8. Rearranging digits in a two-digit number.

: I8 (AB -> BA)
    10 /MOD SWAP 10 * +
;
45 I8
 Ok (54)

Example 9. Print the number of hundreds in a three-digit number.

: I9 (ABC -> A)
    100 /
;
578 I9
 OK (5)

That's right. The hundreds number in 578 is 5.

Example 10. Similar to the previous one. We first print the number of ones and then the number of tens.

: I9 ( ABC ->C B )
    10 /MOD 10 MOD
;
123 I9
Ok (3 2)

Example 11. Calculate the sum and product of the digits of a three-digit number.

: I11 ( ABC -> A+B+C A*B*C )
    10 /MOD 10 /MOD \ ABC -> C B A
    DUP 2OVER + + \ C B A -> C B A A+C+B
    SWAP 2SWAP * * \ C B A A+C+B -> A+C+B A*C*B
;
456 I11
 Ok (15 120)

The sum is 4+5+6=15, and the product is 4*5*6=120.

Example 12. Flip a three-digit number from right to left.

: I12 (ABC -> CBA)
    10 /MOD 10 /MOD \ ABC -> C B A
    SWAP 10 * + \ C B A -> C BA
    SWAP 100 * + \ C BA -> CBA
;
123 I12
 OK (321)

This is how Fort simply turns a three-digit number backwards.

Example 13. In a three-digit number, move the hundreds to the far right instead of the units.

: I13 (ABC -> BCA)
    100 /MOD \ ABC -> BC A
    SWAP 10 * +\BC A -> BCA
;
123 I13
 OK (231)

Example 14. Similar to the previous one. Quite a simple task.

: I14 (ABC -> CAB)
    10 /MOD\ABC -> C AB
    SWAP 100 * + \ C AB -> CAB
;
123 I14
 OK (312)

Example 15. In a three-digit number, rearrange the hundreds and tens digits.

: I15 (ABC -> BAC)
    10 /MOD 10 /MOD \ ABC -> C B A
    10 * SWAP 100 * + + \ C B A -> BAC
;
123 I15
 OK (213)

As before, we first parse the number into digits, then assemble it in the order required by the conditions of the problem.

Example 16. Swap tens and ones in a three-digit number.

: I16 (ABC -> ACB)
    10 /MOD 10 /MOD \ ABC -> C B A
    100 * + SWAP 10 * + \ C B A -> ACB
;
123 I16
 OK (132)

Example 17. Quite a trivial problem. In a number greater than 999, determine the number of hundreds.

: I17 ( A -> X ) \ X – number of hundreds
    1000 MOD 100 /
;
123456 I17
 OK (4)

Example 18. Absolutely identical to the previous example and also primitive. In a similar number, find the number of thousands.

: I18 ( A -> X ) \ X – number of thousands
    10000 MOD 1000 /
;
123456 I18
 OK (3)

Example 19. Given S seconds, convert to the number of full minutes M.

: I19 ( S -> M ) \ M – result in minutes
    60/
;
179 I19
 OK (2)

Example 20. Similar to the previous one. Convert seconds S to full hours H.

: I20 ( S -> H ) \ H – result in hours
    3600/
;
7201 I20
 OK (2)

Example 21. Identical to example 19, only we calculate the number of seconds since the last minute.

: I21 ( S -> Sm ) \ Sm – result in seconds
    60 MOD
;
179 I21
 OK (59)

Example 22. Similar to example 20, we determine the number of seconds since the last hour.

: I22 ( S -> Sh ) \ Sh – result in seconds
    3600 MOD
;
7201 I22
 OK (1)

Example 23. Unlike the previous one, we determine the number of minutes since the last hour.

: I23 ( S -> Sm ) \ Sm – result in minutes
    3600 MOD 60 /
;
7201 I23
 OK (0)

Example 24. Determine the day of the week. The number of day D is given (1-365). It is known that 01.01 – Mon.

: I24 ( D -> W ) \ W – number of the day of the week, 0 - Sun, 1 - Mon, etc.
    7 MOD
;
8 I24
 OK (1)

Example 25. Differs from the previous one in that 01.01 is THURSDAY.

: I25 ( D -> W ) \ W – number of the day of the week, 0 - Sun, 1 - Mon, etc.
    3 + 7 MOD
;
8 I25
 OK (4)

We added 3 to synchronize the day of the week with the remainder of the division. Since the remainder of division of 1 by 7 is 1, and 1 is PN. The remainder of (1+3)/7 is 4, which encodes CHT.

Looking ahead, I’ll tell you how to test the words I24 and I25, running through all the options in a loop, without diving deep into the code itself.

I24 word test:

: TEST-I24
    366 1 DO I . .” - day of the year - “I I24. .” day of week code" CR LOOP
;

Word test I25:

: TEST-I25
    366 1 DO I . .” - day of the year - “I I25. .” day of week code" CR LOOP
;

As before, to call a test for these words, you need to type the corresponding names (“TEST-I24”, “TEST-I25”). Enter one at a time so that the results do not merge into one.

Example 26. Now 01.01 – Tue. We synchronize the day of the week and reduce the task to the previous two.

: I26 ( D -> W ) \ W – number of the day of the week, 0 - Sun, 1 - Mon, etc.
    1 + 7 MOD
;
1 I26
 OK (2)

Corresponding test word:

: TEST-I26
    366 1 DO I . .” - day of the year - “I I26. .” day of week code" CR LOOP
;

Example 27. No different from the previous three examples, with the exception of the synchronization number for the condition of problem 01.01 - SB.

: I27 ( D -> W ) \ W – number of the day of the week, 0 - Sun, 1 - Mon, etc.
    5 + 7 MOD
;
1 I27
 OK (6)

Another test word:

: TEST-I27
    366 1 DO I . .” - day of the year - “I I27. .” day of week code" CR LOOP
;

Example 28. “Quintessence” of previous examples No. 24-27, and their solution in general form. The number of day D in the range 1-365 and the coding of the day of the week are still given. As before, it is necessary to calculate the day of the week code for D.

: I28 ( D N -> W ) \ W – number of the day of the week, 0 - Sun, 1 - Mon, etc.
    + 1- 7 MOD
;

With parameter N=1 it reduces to example 24.

8 1 I28
 OK (1)

With parameter N=4 it reduces to example 25.

8 4 I28
 OK (4)

With parameter N=2 it reduces to example 26.

1 2 I28
 OK (2)

With parameter N=6 it reduces to example 27.

1 6 I28
 OK (6)

Test word for the 28th example:

: TEST-I28
    366 1 DO I . .” - day of the year - “I OVER I28. .” day of week code" CR LOOP DROP
;

You need to call “6 TEST-I28” as follows, where only parameter N is set, in this case Saturday. Examples of test words are not given due to the large volume of similar text.

Example 29. Determine how many squares with side C cover a rectangle with sides A and B without overlap, as well as the area of ​​the free part.

: I29 ( A B C -> N {A*B-N*C^2} ) \ N - number of squares {A*B-N*C^2} - area of ​​the free part
    DUP 2OVER\A B C -> A B C C A B
    ROT / ROT ROT OVER / ROT * \ A B C C A B -> A B C [A/C]*[B/C]=N - number of squares
    SWAP DUP * OVER * \ A B C N -> A B N N*C^2
    2SWAP * SWAP - \ A B N N*C^2 -> N {A*B-N*C^2}=free part area
;
11 21 5 I29
 Ok (8 31)

The integer part of dividing 11 by 5 is 2, and 21 by 5 is 4, therefore, without overlap, 2*4=8 squares with side 5 are placed (which is what the Forth word produces as the first argument). The area of ​​the rectangle is 11*21= 231. So, by simple calculation we obtain by subtracting from the latter the area of ​​eight squares, equal to 8*5*5=200, that is, 231-200=31, and this is the second argument of the function described above. The Fortword test is correct.

Example 30. Determine the century by year. The beginning of the century is considered to be the year xx01, so we subtract 1 to get rid of this exception. Let us not forget that the xx54th year is the xx+1st century, which is taken into account by adding one.

: I30 (Y -> C) \ C - century
    1- 100 / 1+
;
1901 I30
 OK (20)

But 1900 is still the 19th century.

1900 I30
 Ok (20 19)