Пример 21. Проверить, что цифры трехзначного числа образуют возрастающую последовательность. Для этого сперва разбиваем данное число на цифры, затем производим двойное сравнение, т.е. в числе ABC должно быть: A<B<C.

: BOOL21 ( ABC -> )
   10 /MOD 10 /MOD   \ ABC -> C B A
   OVER < ROT ROT    \ C B A -> A<B C B
   > AND             \ A<B C B -> [A<B]AND[C>B]
   B.
;
123 BOOL21
True  Ok
111 BOOL21
False  Ok
112 BOOL21
False  Ok
122 BOOL21
False  Ok
321 BOOL21
False  Ok

Пример 22. Проверить, что цифры трехзначного числа образуют возрастающую или убывающую последовательность, то есть у числа ABC A<B<C или A>B>C. Отличается от предыдущего дополнительной проверкой.

: BOOL22 ( ABC -> )
    DUP                     \ ABC -> ABC ABC
    10 /MOD 10 /MOD         \ ABC ABC -> ABC C B A
    OVER < ROT ROT          \ ABC C B A -> ABC A<B C B
    > AND                   \ ABC A<B C B -> ABC [A<B]AND[C>B]
    SWAP 10 /MOD 10 /MOD    \ ABC [A<B]AND[C>B] -> [A<B]AND[C>B] C B A
    OVER > ROT ROT          \ [A<B]AND[C>B] C B A -> [A<B]AND[C>B] A>B C B
    < AND                   \ [A<B]AND[C>B]  A>B C B -> [A<B]AND[C>B]  [A>B]AND[C<B]
    OR                      \ [A<B]AND[C>B]  [A>B]AND[C<B] -> {[A<B]AND[C>B]}OR{[A>B]AND[C<B]}
    B.
;
123 BOOL22
True  Ok
321 BOOL22
True  Ok
210 BOOL22
True  Ok
211 BOOL22
False  Ok
112 BOOL22
False  Ok

Можно оптимизировать код. Используем для этого предыдущий пример. Уберем оттуда вывод и первую строчку разбивающее число на цифры, теперь оно просто определяет «A<B<C» истина или ложь.

: BOOL21 ( C B A -> Bool )
    OVER < ROT ROT          \ C B A -> A<B C B               
    > AND                   \ A<B C B -> [A<B]AND[C>B]
;

Теперь перепишем слово BOOL22.

: BOOL22 ( ABC -> )
    DUP 10 /MOD 10 /MOD              \ ABC -> ABC C B A
    BOOL21 IF 1 B. DROP EXIT THEN    \ ABC -> ABC
    10 /MOD 10 /MOD SWAP ROT         \ ABC -> A B C
    BOOL21 IF 1 B. EXIT THEN
    0 B.
;

  1. Первая строка стандартное начало
  2. Во втором мы копируем число затем разбиваем его на цифры
  3. В третьей отправляем результаты разбиения на проверку в слово «BOOL21», получив результат в переменной Bool на вершине стека, и в случае его истинности печатаем это через слово «B.», передав ему аргумент один. Удаляем оставшееся на стеке число ABC и выходим оператором «EXIT».
  4. В четвертом проверяем неравенство A>B>C, для чего после разбиения числа меняем порядок на обратный.
  5. В пятом опять цифры отправляем на проверку в «BOOL21», с той же логикой работы.
  6. Шестая строчка срабатывает, когда ни одно из двух неравенств не являются истинными, что значит цифры исходного числа не отсортированы ни по возрастанию, ни по убыванию, для чего мы печатаем ложь, вызвав «B.» с аргументом ноль.

Если код нужен без условного оператора, то можем переписать последнее.

: BOOL22 ( ABC -> )
    DUP 10 /MOD 10 /MOD        \ ABC -> ABC C B A
    BOOL21                     \ ABC -> ABC Bool1
    SWAP                       \ ABC Bool1-> Bool1 ABC
    10 /MOD 10 /MOD SWAP ROT   \ Bool1 ABC-> Bool1 C B A
    BOOL21 OR                  \ Bool1 ABC -> Bool1&Bool2
    B.
;

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

Пример 23. Проверить, что четырехзначное число одинаково читается слева направо и справа на лево. Это значит, что число должно быть вида ABBA.

: BOOL23 ( ABCD -> )
    100 /MOD          \ ABCD -> CD AB
    10 /MOD           \ CD AB -> CD B A
    SWAP 10 * +       \ CD B A -> CD BA
    =                 \ CD BA -> CD= BA
    B.
;

Код «100 /MOD» делит исходное число на две половинки: первая – это десятки с единицами, вторая – тысячи с сотнями. Затем «10 /MOD» разбивает последнее на отдельные цифры, а «SWAP 10 * +» собирает в обратном порядке. Эти манипуляции необходимы для сравнения «CD= BA». В случае равенства исходное число – «палиндром», т. е. одинаково читается слева направо и справа на лево.

1221 BOOL23
True  Ok
1234 BOOL23
False  Ok
1001 BOOL23
True  Ok
1220 BOOL23
False  Ok

Тесты корректны.

Пример 24. Проверить высказывание на истинность «квадратное уравнение с коэффициентами A, B, C имеет действительные корни». Для этого вычисляем дискриминант, и если оно не отрицательно, то выводим «истина» (True), иначе «ложь» (False).

: BOOL24 ( A B C -> )
    SWAP DUP *         \ A B C -> A C B^2
    ROT ROT            \ A C B^2 -> B^2 A C
    -4 * * +           \ B^2 A C -> B^2+A*C*(-4)
    -1 > B.
;
1 2 1 BOOL24
True  Ok
1 3 2 BOOL24
True  Ok
1 2 5 BOOL24
False  Ok

Проверка дискриминанта на не отрицательность, т. е. D>=0, заменяем на D>-1, естественно предполагая что целые коэффициенты дадут только целое значение для D, такая замена является корректной.

Пример 25. Истинно ли, что точка с координатой (x,y) лежит во второй четверти в декартовой системе координат. Вторая четверть означает, что x<0, y>0 (равно нулю не берем так как возникает неоднозначность).

: BOOL25 ( X Y -> )
    0 > SWAP 0 < AND
    B.
;
1 1 BOOL25
False  Ok
-1 1 BOOL25
True  Ok
-1 -1 BOOL25
False  Ok
1 -1 BOOL25
False  Ok

Пример 26. Идентичен предыдущему примеру, только проверяем принадлежность четвертой четверти. Четвертая четверть означает, что x>0, y<0.

: BOOL26 ( X Y -> )
    0 < SWAP 0 > AND
    B.
;
1 1 BOOL26
False  Ok
1 -1 BOOL26
True  Ok
-1 1 BOOL26
False  Ok
-1 -1 BOOL26
False  Ok

Пример 27. Аналогично двум предыдущим примерам, проверяем принадлежность второй или третьей координатным четвертям. А это значит x<0, а y-любое.

: BOOL27 ( X Y -> ) DROP 0 < B. ;  \ Y - отбрасываем, проверяем X<0? Печатаем значение булевого переменного на вершине стека.
1 1 BOOL27
False  Ok
1 -1 BOOL27
False  Ok
-1 1 BOOL27
True  Ok
-1 -1 BOOL27
True  Ok

Пример 28. Теперь проверяем принадлежность первой или третьей координатным четвертям. Чуть сложнее предыдущих примеров. Либо x>0 и y>0, либо x<0 и y<0.

: BOOL28 ( X Y -> )
    2DUP 0 < SWAP 0 < AND  \ X Y -> X Y [X<0]AND[Y<0]
    ROT ROT                \ X Y [X<0]AND[Y<0] -> [X<0]AND[Y<0] X Y
    0 > SWAP 0 > AND       \ [X<0]AND[Y<0] X Y -> [X<0]AND[Y<0] [Y>0]AND[X>0]
    OR                     \ [X<0]AND[Y<0] [Y>0]AND[X>0] -> [X<0]AND[Y<0]OR[Y>0]AND[X>0]
    B.
;
1 1 BOOL28
True  Ok
-1 -1 BOOL28
True  Ok
1 -1 BOOL28
False  Ok
-1 1 BOOL28
False  Ok

А теперь «лайвхак», упростим это «безобразие». Систему условий либо (x>0 и y>0), либо (x<0 и y<0) можно заменить на одно x*y>0, т. е. не зависимо от знака аргументов их произведение всегда положительно. Пример для наглядности «10*50>0 и -10*(-50)>0». Перепишем слово BOOL28.

: BOOL28 ( X Y -> )
    * 0 >            \ X*Y>0
    B.
;

Предыдущие тесты дают идентичные результаты, проверяйте самостоятельно.

Вывод: красивое и простое математическое решение дает такой же код.

Пример 29. Входит ли точка в прямоугольник. Даны координаты точки (X,Y) и двух вершин прямоугольника, левой верхней (X1,Y1) и противоположенной ей (X2,Y2), стороны параллельны абсциссе и ординате. Точка находится внутри прямоугольника когда X1<=X<=X2 и Y1<=Y<=Y2. Задача сводится к проверке этих двух двойных неравенств.

Создадим переменные

VARIABLE X VARIABLE X1 VARIABLE X2
VARIABLE Y VARIABLE Y1 VARIABLE Y2

Но пользоваться будем только X1, X2, Y1, Y2.

: BOOL29 ( X Y X1 Y1 X2 Y2 -> )
    Y2 ! X2 ! Y1 ! X1 !          \ X Y X1 Y1 X2 Y2 -> X Y
    DUP Y1 @ >                   \ X Y -> X Y Y>Y1
    IF 2DROP 0 B. EXIT THEN      \ Если Y>Y1 – не внутри «ложь»
    Y2 @ <                       \ X Y -> X Y<Y2
    IF DROP 0 B. EXIT THEN       \ Если Y<Y2 – не внутри «ложь»
    DUP X1 @ <                   \ X -> X X<X1
    IF DROP 0 B. EXIT THEN       \ Если X<X1 – не внутри «ложь»
    X2 @ >                       \ X -> X>X2
    IF 0 B. EXIT THEN            \ Если X>X2 – не внутри «ложь»
    1 B.                         \ Иначе - внутри
;

  1. Первая строка объявление слова со стековой нотацией. Все как обычно.
  2. Во второй мы сохраняем координаты прямоугольника в переменные, дабы не усложнять стековые манипуляции и упростить код.
  3. В третьей сравниваем Y координату точки с ординатой верхней левой точки прямоугольника, если больше, то точка не может входить в него.
  4. В четвертой это сравнение проверяется на истинность. Истина в случае, когда точка не принадлежит прямоугольнику, печатаем ложь с помощью слова «B.» с параметром «0». Затем завершаем программку с помощью оператора «EXIT».
  5. Аналогично третьей строчке проверяем координату точки на принадлежность нижней границе прямоугольника.
  6. Аналогичен четвертой строке.
  7. С седьмой по десятую строки аналогичны строкам с третьей по шестую только относятся к координате X.
  8. Одиннадцатая строка срабатывает, если все остальные условия на не вхождение точки в прямоугольник не удовлетворены. Т. е. точка находится внутри, о чем и сообщает слово «B.» с параметром один, что значит истина.

1 1 10 10 20 5 BOOL29
False  Ok
9 11 10 10 20 5 BOOL29
False  Ok
11 9 10 10 20 5 BOOL29
True  Ok
21 9 10 10 20 5 BOOL29
False  Ok
11 4 10 10 20 5 BOOL29
False  Ok

Пример 30. Проверить равносторонний ли треугольник со сторонами A, B, C. Задача сводится к проверке двойного равенства A=B=C.

: BOOL30 ( A B C -> )
    OVER =             \ A B C -> A B C=B
    ROT ROT = AND      \ A B C=B -> [C=B]AND[A=B]
    B.
;
1 2 3 BOOL30
False  Ok
1 2 2 BOOL30
False  Ok
2 2 1 BOOL30
False  Ok
1 2 1 BOOL30
False  Ok
5 5 5 BOOL30
True  Ok

Пример 31. Проверить равнобедренный ли треугольник со сторонами A, B, C. Проверяется условием A=B или B=C или A=C. Идентична примеру номер 18 без изменений.

: BOOL31 ( A B C -> )
    2DUP =             \ A B C -> A B C B=C
    2SWAP OVER =       \ A B C B=C -> C B=C A B=A
    ROT OR             \ C B=C A B=A -> C A [B=A]OR[B=C]
    ROT ROT = OR       \ C A [B=A]OR[B=C] -> [B=A]OR[B=C]OR[C=A]
    B.
;
1 1 2 BOOL31
True  Ok
1 2 1 BOOL31
True  Ok
1 1 2 BOOL31
True  Ok
1 1 1 BOOL31
True  Ok
1 2 3 BOOL31
False  Ok

Пример 32. Проверить треугольник со сторонами A, B, C прямоугольный? Используя теорему Пифагора проверим 3 равенства A^2=B^2+C^2 или B^2= A^2 +C^2 или C^2= A^2+B^2. Если одно из них выполняется, то ответ положительный, иначе отрицательный.

  1. Первая строчка – описание.
  2. Во второй строчке исходные данные – длины сторон «A B C» превращаем в их квадраты.
  3. Во третьей проверяем первое из равенств: [A^2=C^2+B^2]. Обозначив ее через BooL1 в стековом комментарии, чтобы уменьшить его размер и повысить удобочитаемость.
  4. В четвертой выносим квадраты сторон, и убираем BooL1 по дальше, он нам понадобится в конце.
  5. В пятой проводим сравнение очередной тройки, второе равенство из трех. Получаем BooL
  6. Шестая аналогична четвертой. Готовим для последнего сравнения.
  7. Последнее сравнение.
  8. В восьмой два оператора «OR», логическое или, готовят ответ для девятой строчки.

: BOOL32 ( A B C -> )
    DUP * SWAP DUP * ROT DUP *  \ A B C -> C^2 B^2 A^2
    DUP 2OVER + =               \ C^2 B^2 A^2-> C^2 B^2 A^2  [A^2=C^2+B^2]=BooL1
    SWAP 2SWAP                  \ C^2 B^2 A^2 BooL1-> BooL1 A^2 C^2 B^2
    DUP 2OVER + =               \ BooL1 A^2 C^2 B^2-> BooL1 A^2 C^2 B^2 [B^2=A^2+C^2]=BooL2
    SWAP 2SWAP                  \ BooL1 A^2 C^2 B^2 BooL2-> BooL1 BooL2 B^2 A^2 C^2
    ROT ROT + =                 \ BooL1 BooL2 B^2 A^2 C^2 -> BooL1 BooL2 [C^2=B^2+A^2]= BooL3
    OR OR                       \ BooL1 BooL2 BooL3 -> [BooL1]OR[BooL2]OR[[BooL3]
    B.
;
3 4 5 BOOL32
True  Ok
4 3 5 BOOL32
True  Ok
3 5 4 BOOL32
True  Ok
4 5 3 BOOL32
True  Ok
5 3 4 BOOL32
True  Ok
5 4 3 BOOL32
True  Ok
1 2 3 BOOL32
False  Ok

Пример 33. Существует треугольник со сторонами A, B, C? В треугольнике 0<A<B+C и 0<B<A+C и 0<C<A+B. Напоминает предыдущий, без возведения в квадрат, равенство заменяется неравенством, а логическая дизъюнкция конъюнкцией.

  1. Первая строчка без комментариев.
  2. Со второй по четвертую проверка всех сторон на положительность, в противном случае треугольник не существует.
  3. Пятая если хотя бы одна из сторон не положительна, то результат {[B>0]AND[A>0]AND[C>0]}=0, и проверка «0 =» оставит истину, которая заставит сработать код после «IF», где очистится стек от оставшихся аргументов «DROP 2DROP», код «0 B.» напечатает «False Ok», а оператор «EXIT» закончит выполнение слова.
  4. С шестой по десятую выполняется основная проверка условия задачи.
  5. Одиннадцатая – объединяет в конечный результат, а двенадцатая печатает ответ.

: BOOL33 ( A B C -> )
    DUP 2OVER 0 >      \ A B C -> A B C C A B>0
    SWAP 0 > ROT  0 >  \ A B C C A B>0 -> A B C B>0 A>0 C>0
    AND AND            \ A B C B>0 A>0 C>0 -> A B C {[B>0]AND[A>0]AND[C>0]}
    0 = IF DROP 2DROP 0 B. EXIT THEN
    DUP 2OVER + <      \ A B C -> A B C [C<A+B]=BooL1
    SWAP 2SWAP         \ A B C BooL1 -> BooL1 C A B
    DUP 2OVER + <      \ BooL1 C A B -> BooL1 C A B [B<C+A]=BooL2
    SWAP 2SWAP         \ BooL1 C A B BooL2 -> BooL1 BooL2 B C A
    ROT ROT + <        \ BooL1 BooL2 B C A -> BooL1 BooL2 [A<B+C]=BooL3
    AND AND            \ BooL1 BooL2 BooL3 -> [BooL1]AND[BooL2]AND[BooL3]
    B.
;
1 2 3 BOOL33
False  Ok
2 2 2 BOOL33
True  Ok
10 5 1 BOOL33
False  Ok
5 7 8 BOOL33
True  Ok

Пример 34. Проверить поле на шахматной доске белое? Дано X и Y – координаты (0<[X,Y]<9). Известно, что левое нижнее поле с координатами (1,1) – черное. Сложим координаты X+Y, для поля (1,1) – «1+1=2» четное для соседнего белого нечетное, для верхнего также белого – нечетное. Вывод, если сумма координат нечетное, то поле белое, то есть истина, иначе ложь.

: BOOL34 ( X Y -> )
    + 2 MOD          \ Остаток{[X+Y]/2}
    B.
;
1 1 BOOL34
False  Ok
1 2 BOOL34
True  Ok
2 1 BOOL34
True  Ok
2 2 BOOL34
False  Ok

Пример 35. По координатам двух полей шахматной доски определить одного они цвета или нет? Из предыдущего примера мы выяснили связь цвета с четностью. Одинаковый цвет значит одинаковая четность. Если четность одинаковая, то истина, иначе ложь.

: BOOL35 ( X1 Y1 X2 Y2 -> )
    + 2 MOD    \ X1 Y1 X2 Y2 -> X1 Y1 Остаток{[X2+Y2]/2}
    ROT ROT    \ X1 Y1 Остаток{[X2+Y2]/2} -> Остаток{[X2+Y2]/2} X1 Y1
    + 2 MOD    \ Остаток{[X2+Y2]/2} X1 Y1 -> Остаток{[X2+Y2]/2} Остаток{[X1+Y1]/2}
    =          \ Остаток{[X2+Y2]/2} Остаток{[X1+Y1]/2} -> Остаток{[X2+Y2]/2}=Остаток{[X1+Y1]/2}
    B.
;
1 1 2 2 BOOL35
True  Ok
1 1 1 2 BOOL35
False  Ok

Пример 36. Истинно ли, что ладья за один ход может перейти с поля (X1,Y1) в поле (X2,Y2)? Переход ладьи за один ход возможен только в том случае, если равны «иксы» или «игреки». Потому что ладья ходит либо по горизонтали, либо по вертикали, а это значит, что за один ход изменится либо икс, «либо» «игрек».

: BOOL36 ( X1 Y1 X2 Y2 -> )
    ROT =                    \ X1 Y1 X2 Y2 -> X1 X2 Y2=Y1
    ROT ROT =                \ X1 X2 Y2=Y1 -> Y2=Y1 X1=X2
    OR                       \ Y2=Y1 X1=X2 -> {Y2=Y1}OR{X1=X2}
    B.
;
1 8 3 8 BOOL36
True  Ok
3 5 3 8 BOOL36
True  Ok
1 1 5 5 BOOL36
False  Ok

Пример 37. Может король за один ход перейти с поля (X1,Y1) в поле (X2,Y2)? Так как король за один ход может передвинуться в любую сторону на одну клетку, то это значит, что |X1-X2|<2 (<=1) и |Y1-Y2|<2 (<=1).

: BOOL37 ( X1 Y1 X2 Y2 -> )
    ROT -  ABS 2 <           \ X1 Y1 X2 Y2 -> X1 X2 |Y2-Y1|<2=Bool1
    ROT ROT -  ABS 2 <       \ X1 X2 Bool1 -> Bool1 |X1-X2|<2= Bool2
    AND                      \ Bool1 Bool2 -> [Bool1]AND[Bool2]
    B.
;
1 2 2 1 BOOL37
True  Ok
1 1 2 2 BOOL37
True  Ok
1 2 2 3 BOOL37
True  Ok
1 1 3 3 BOOL37
False  Ok

Пример 38. Может слон за один ход перейти с поля (X1,Y1) в поле (X2,Y2)? Так как слон ходит по диагонали, то переход возможен, если |X1-X2|=|Y1-Y2|. Код получим из предыдущего примера удалением проверки «<2» и замены оператора «AND» на «=».

: BOOL38 ( X1 Y1 X2 Y2 -> )
    ROT -  ABS               \ X1 Y1 X2 Y2 -> X1 X2 |Y2-Y1|
    ROT ROT -  ABS           \ X1 X2 |Y2-Y1|-> |Y2-Y1| |X1-X2|
    =                        \ |Y2-Y1| |X1-X2|-> |Y2-Y1|=|X1-X2|
    B.
;
2 3 4 5 BOOL38
True  Ok
2 3 1 2 BOOL38
True  Ok
2 3 1 4 BOOL38
True  Ok
2 3 3 2 BOOL38
True  Ok
1 1 5 4 BOOL38
False  Ok

Пример 39. Может ферзь за один ход перейти с поля (X1,Y1) в поле (X2,Y2)? Ферзь ходит как ладья и слон вместе взятые. Данный пример является комбинацией примеров 36 и 38.

: BOOL39 ( X1 Y1 X2 Y2 -> )
    2OVER 2OVER              \ X1 Y1 X2 Y2 -> X1 Y1 X2 Y2 X1 Y1 X2 Y2
    ROT =                    \ X1 Y1 X2 Y2 X1 Y1 X2 Y2 -> X1 Y1 X2 Y2 X1 X2 Y2=Y1
    ROT ROT =                \ X1 Y1 X2 Y2 X1 X2 Y2=Y1 -> X1 Y1 X2 Y2 Y2=Y1 X1=X2
    OR                       \ X1 Y1 X2 Y2 Y2=Y1 X1=X2 -> X1 Y1 X2 Y2 {Y2=Y1}OR{X1=X2}
    IF .” True” 2DROP 2DROP EXIT THEN
    ROT -  ABS               \ X1 Y1 X2 Y2 -> X1 X2 |Y2-Y1|
    ROT ROT -  ABS           \ X1 X2 |Y2-Y1|-> |Y2-Y1| |X1-X2|
    =                        \ |Y2-Y1| |X1-X2|-> |Y2-Y1|=|X1-X2|
    B.
;
1 1 8 8 BOOL39
True  Ok
1 1 8 1 BOOL39
True  Ok
1 1 3 4 BOOL39
False  Ok

Итоговый код тривиален.

  1. Первая строка – заголовок с описанием.
  2. Вторая – дублируем параметры для проверки на ход слона или ладьи.
  3. С третьей по пятую строки - проверка равенства либо абсцисс, либо ординат «{Y2=Y1}OR{X1=X2}».
  4. Шестая – если проверка истина, то печатаем «True», удаляем оставшиеся параметры, они больше не пригодятся, так как вторая проверка не требуется, затем выход.
  5. С седьмой по девятую, выполняется, когда первая проверка ложна, тогда мы проверяем равность разности модулей ординат и абсцисс «|Y2-Y1|=|X1-X2|».
  6. Десятая строка стандартная обработка результата второй проверки.

Можно сказать, что здесь реализован аналог «ленивых вычислений», когда ход ферзя похож на ход ладьи, то дальше делать ничего не надо (ход возможен). В противном случае нужно проверить на хода слона, и уже знакомым образом проанализировать результат.

Пример 40. Может ли конь за один ход перейти с поля (X1,Y1) в поле (X2,Y2)? Конь ходит буквой «Г», ее зеркальным отражением и поворотом первых двух вариантов на 90,180 и 270 градусов. Условие для проверки хода коня будет {|Y2-Y1|=1 и |X1-X2|=2} или {|Y2-Y1|=2 и |X1-X2|=1}.

: BOOL40 ( X1 Y1 X2 Y2 -> )
    ROT -  ABS               \ X1 Y1 X2 Y2 -> X1 X2 |Y2-Y1|
    ROT ROT -  ABS           \ X1 X2 |Y2-Y1|-> |Y2-Y1| |X1-X2|
    * 2 =                    \ |Y2-Y1| |X1-X2| -> |Y2-Y1|*|X1-X2|=2
    B.
;

Возможные результаты |Y2-Y1| и |X1-X2| равны от 1 до 7, если считать что X1<>X2 и Y2<>Y1 (иначе от 0 до 7). Нас интересует вариант, когда {|Y2-Y1|=1 и |X1-X2|=2} или {|Y2-Y1|=2 и |X1-X2|=1}. Эту проверку заменим на |X1-X2|*|Y2-Y1|=2. Равенство  {1..7}*{1..7}=2, истинно в единственном случае, когда верно {|Y2-Y1|=1 и |X1-X2|=2} или {|Y2-Y1|=2 и |X1-X2|=1}. Для тех кому это не очевидно, могут перебрать все варианты.

Допустим (X1,Y1)=(3,3), тогда все ходы коня будут: (2;5),(4;5),(5;4),(5;2),(2;1),(4;1),(1;2),(1;4). Проверим работу, написанного слова, на этих данных:

3 3 2 5 BOOL40
True  Ok
3 3 4 5 BOOL40
True  Ok
3 3 5 2 BOOL40
True  Ok
3 3 5 4 BOOL40
True  Ok
3 3 2 1 BOOL40
True  Ok
3 3 4 1 BOOL40
True  Ok
3 3 1 2 BOOL40
True  Ok
3 3 1 4 BOOL40
True  Ok

Самое интересное, что данный алгоритм правильно обрабатывает вариант «3 3 3 3 BOOL40», хоть он и не был предусмотрен в начале. Все остальные ходы, не совпадающие с ходом коня, проверьте самостоятельно. Подтвердите, что результат будет «False  Ok». Таких вариантов будет 5*5 – 8 ходов коня. А чтобы проверить все 64 клетки, можно использовать тест-слово:

: TEST-BOOL40 ( -> )
    9 1 DO
        9 1 DO
            3 3 I J BOOL40 9 EMIT
        LOOP CR
    LOOP
;

Тест-слово “TEST-BOOL40” выводит таблицу слева направо и сверху вниз, а значит, клетка (1;1) левый верхний угол, это нужно учитывать при проверке результатов.

Для красоты можем переписать слово «B.» таким образом:

: B. ( Bool -> )  IF ." К" ELSE ." -" THEN ;

Учтите, что после изменений в слове «B.», нужно заново вводить слова «BOOL40» и «TEST-BOOL40», иначе результат будет тот же самый, без изменений. В итоге увидим на экране следующее:

TEST-BOOL40
-       К       -       К       -       -       -       -
К       -       -       -       К       -       -       -
-       -       -       -       -       -       -       -
К       -       -       -       К       -       -       -
-       К       -       К       -       -       -       -
-       -       -       -       -       -       -       -
-       -       -       -       -       -       -       -
-       -       -       -       -       -       -       -
 Ok