Теперь мы решаем новую группу заданий с исключительно целочисленными параметрами. Все задания мы будем нумеровать с префиксом I, сокращение от Integer, означающее целое число.

Пример 1. Перевести см в м без округления. Здесь вы увидите всю красоту Форта.

Rm=Rcm/100 – целочисленно

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

Что означает в 503 см содержится 5 полных метров.

Пример 2. Отличается от предыдущего заменой 100 на 1000.

Mt= Mkg/1000

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

В 12683 кг 12 полных тонн.

Пример 3. Так же отличается от предыдущего константой. Теперь 1000 меняем на 1024.

DkB= DB/1024

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

2050 B - это 2 полных kB.

Пример 4. Так же простейшая задачка на целочисленное деление.

Для определенности A>B, результат равен A/B.

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

В отрезке длиной 15 размещается 3 целых отрезка длиной 4.

Пример 5. Отличается от предыдущего примера заменой целочисленного деления на взятие остатка от деления.

: I5 ( A B -> остаток{A/B} )
    MOD
;
15 4 I5
 Ok ( 3 )

15/4 – остаток равен 3 – все верно, результат теста корректный.

Примеры 1-5 настолько просты, что даже нет необходимости создавать соответствующие слова. Можно просто ввести число-операнд затем тело слова. Результат получите в скобках на стеке. Чтобы распечатать его и не засорять стек нажмите «.» и «Enter». Перепишем эти примеры для наглядности.

  1. «503 100 / .»
  2. «12683 1000 / .»
  3. «2050 1024 / .»
  4. «15 4 / .»
  5. «15 4 MOD .»

Но если вы будете часто пользоваться написанным кодом, крайне желательно создавать отдельные слова-функции, также дать им легко запоминающиеся осмысленные названия.

Пример 6. Вывести число десятков и единиц двузначного числа. Для этого используем операцию /MOD, которая одновременно вычисляет и целую часть, и остаток от деления.

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

Чтобы вывести в таком же порядке как на стеке слегка изменим код (помним, что сначала напечатается вершина стека, поэтому перед выводом используем команду SWAP)

45 I6 SWAP . .
4 5  Ok

Теоретически, последним штрихом, будет оформление вывода в отдельное слово, как говорилось ранее в предыдущей группе задач, по схеме:

: I6. I6 SWAP . . ;

Теперь окончательно задача решаться будет просто вызовом одного слова с одним аргументом:

45 I6.
4 5  Ok

Результат тот же, но решение выглядит более профессионально.

Разумеется, эти два слова можно объединить в одно по схеме:

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

Два слова SWAP уже не будут нужны, но так для сложных задач не рекомендуется делать, кроме того, как говорилось раннее интерфейс вывода и логику работы алгоритма крайне желательно отделять, так изменение в коде одного не повлияет на другое.

Пример 7. Вычислить сумму и произведение цифр двузначного числа. Дальнейшее развитие предыдущего примера.

: 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 )

Сумма цифр числа 45 равна 4+5=9, а произведение 4*5=20, тест корректен.

Если вас не удовлетворяет результат на стеке, то можете аналогично предыдущему примеру написать слово для вывода на экран.

Пример 8. Перестановка местами цифр в двузначном числе.

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

Пример 9. Вывести число сотен в трехзначном числе.

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

Все верно. Число сотен в числе 578 равно 5.

Пример 10. Аналогичен предыдущему. Выводим сначала число единиц затем десятков.

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

Пример 11. Вычислить сумму и произведение цифр трехзначного числа.

:  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 )

Сумма 4+5+6=15, а произведение 4*5*6=120.

Пример 12. Перевернуть трехзначное число справа на лево.

: 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 )

Вот так просто Форт переворачивает трехзначное число «задом наперед».

Пример 13. В трехзначном числе сотни перенести в крайнее правое положение, вместо единиц.

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

Пример 14. Аналогичен предыдущему. Довольно несложная задачка.

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

Пример 15. В трехзначном числе переставить цифры сотен и десятков местами.

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

Как и прежде, сначала разбираем число на цифры, затем собираем, в требуемом условиями задачи, порядке.

Пример 16. Поменять местами десятки и единицы в трехзначном числе.

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

Пример 17. Довольно тривиальная задачка. В числе, большем 999, определить число сотен.

: I17 ( A -> X )     \ X – число сотен
    1000 MOD 100 /
;
123456 I17
 Ok ( 4 )

Пример 18. Абсолютно идентична предыдущему примеру и также примитивна. В аналогичном числе найти число тысяч.

: I18 ( A -> X )    \ X – число тысяч
    10000 MOD 1000 /
;
123456 I18
 Ok ( 3 )

Пример 19. Дано S секунд перевести в количество полных минут M.

: I19 ( S -> M )    \ M – результат в минутах
    60 /
;
179 I19
 Ok ( 2 )

Пример 20. Аналогична предыдущему. Переводим секунды S в число полных часов H.

: I20 ( S -> H )     \ H – результат в часах
    3600 /
;
7201 I20
 Ok ( 2 )

Пример 21. Идентична примеру 19, только вычисляем количество секунд с последней минуты.

: I21 ( S -> Sm )  \ Sm – результат в секундах
    60 MOD
;
179 I21
 Ok ( 59 )

Пример 22. Аналогична примеру 20, определяем число секунд с последнего часа.

: I22 ( S -> Sh )    \ Sh – результат в секундах
    3600 MOD
;
7201 I22
 Ok ( 1 )

Пример 23. В отличии от предыдущего, определяем число минут с последнего часа.

: I23 ( S -> Sm )  \ Sm – результат в минутах
    3600 MOD 60 /
;
7201 I23
 Ok ( 0 )

Пример 24. Определить день недели. Дан номер дня D (1-365). Известно, что 01.01 – ПН.

: I24 ( D -> W )   \ W – номер дня недели, 0 - ВС, 1 - ПН и т. д.
    7 MOD
;
8 I24
 Ok ( 1 )

Пример 25. Отличается от предыдущего тем, что 01.01 – ЧТ.

: I25 ( D -> W )   \ W – номер дня недели, 0 - ВС, 1 - ПН и т. д.
    3 + 7 MOD
;
8 I25
 Ok ( 4 )

Прибавили 3, чтобы синхронизировать день недели с остатком от деления. Так как остаток от деления 1 на 7 равно 1, а 1 – это ПН. Остаток (1+3)/7 равна 4, что кодирует ЧТ.

Забегая вперед, расскажу вам как протестировать слова I24 и I25, пробежав по всем вариантам в цикле, не погружаясь глубоко в сам код.

Тест слова I24:

: TEST-I24
    366 1 DO I . .” - день года - “ I I24  . .” код дня недели" CR LOOP
;

Тест слова I25:

: TEST-I25
    366 1 DO I . .” - день года - “ I I25  . .” код дня недели" CR LOOP
;

По-прежнему, чтобы вызвать тест данных слов нужно набрать соответствующие имена («TEST-I24», «TEST-I25»). Вводите по одному, чтобы результаты не сливались в одно.

Пример 26. Теперь 01.01 – ВТ. Синхронизируем день недели и сводим задачу к предыдущим двум.

: I26 ( D -> W )   \ W – номер дня недели, 0 - ВС, 1 - ПН и т. д.
    1 + 7 MOD
;
1 I26
 Ok ( 2 )

Соответствующее тест-слово:

: TEST-I26
    366 1 DO I . .” - день года - “ I I26  . .” код дня недели" CR LOOP
;

Пример 27. Ничем не отличается от предыдущих трех примеров, за исключением числа синхронизации к условию задачи 01.01 – СБ.

: I27 ( D -> W )   \ W – номер дня недели, 0 - ВС, 1 - ПН и т. д.
    5 + 7 MOD
;
1 I27
 Ok ( 6 )

Очередное тест-слово:

: TEST-I27
    366 1 DO I . .” - день года - “ I I27  . .” код дня недели" CR LOOP
;

Пример 28. «Квинтэссенция» предыдущих примеров № 24-27, и их решение в общем виде. Дано по-прежнему номер дня D в диапазоне 1-365 и кодировка дня недели. Как и ранее необходимо вычислить код дня недели для D.

: I28 ( D N -> W )              \ W – номер дня недели, 0 - ВС, 1 - ПН и т. д.
    + 1- 7 MOD
;

С параметром N=1 сводится к примеру 24.

8 1 I28
 Ok ( 1 )

С параметром N=4 сводится к примеру 25.

8 4 I28
 Ok ( 4 )

С параметром N=2 сводится к примеру 26.

1 2 I28
 Ok ( 2 )

С параметром N=6 сводится к примеру 27.

1 6 I28
 Ok ( 6 )

Тест-слово для 28-ого примера:

: TEST-I28
    366 1 DO I . .” - день года - “ I OVER I28  . .” код дня недели" CR LOOP DROP
;

Вызвать нужно следующим образом «6 TEST-I28», где задается только параметр N, в данном случае суббота. Примеры работ тест-слов не приводятся по причине большого объема однотипного текста.

Пример 29. Определить какое количество квадратов со стороной C покрывает прямоугольник со сторонами A и B без наложений, а также площадь свободной части.

: I29 ( A B C -> N {A*B-N*C^2} )  \ N - количество квадратов {A*B-N*C^2} - площадь свободной части
    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 - количество квадратов
    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}=площадь свободной части
;
11 21 5 I29
 Ok ( 8 31 )

Целая часть от деления 11 на 5 равна 2, а 21 на 5 - 4, следовательно, без наложения размещается 2*4=8 квадратов со стороной 5 (что и выдает Форт-слово в качестве первого аргумента). Площадь прямоугольника равна 11*21= 231. Так, что путем нехитрого расчета получаем вычитанием из последней - площадь восьми квадратов, равной 8*5*5=200, то есть 231-200=31, а это второй аргумент работы вышеописанной функции. Тест Форт-слова корректен.

Пример 30. Определить столетие по году. Началом столетия считается хх01-ый год, поэтому мы вычитаем 1, чтобы избавиться от этого исключения. Незабываем что хх54-ый год – это хх+1-ое столетие, что учитывается прибавлением единицы.

: I30 ( Y -> C )    \ C - столетие
    1- 100 / 1+
;
1901 I30
 Ok ( 20 )

А вот 1900 год всё еще XIX век.

1900 I30
 Ok ( 20 19 )