Книга: ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ ПРОЛОГ
7.10. Просеивай Двойки, Просеивай Тройки
7.10. Просеивай Двойки, Просеивай Тройки
Простое число – это целое положительное число, которое делится нацело только на 1 и на само себя. Например, число 5 – простое, а число 15 – нет, поскольку оно делится на 3. Один из методов построения простых чисел называется «решетом Эратосфена». Этот метод, «отсеивающий» простые числа, не превышающие N, работает следующим образом:
1. Поместить все числа от 2 до N в решето.
2. Выбрать и удалить из решета наименьшее число.
3. Включить это число в список простых.
4. Просеять через решето (удалить) все числа, кратные этому числу.
5. Если решето не пусто, то повторить шаги 2-5.
Чтобы перевести эти правила на Пролог, мы определим предикат целые для получения списка целых чисел, предикат отсеять для проверки каждого элемента решета и предикат удалить для создания нового содержимого решета путем удаления из старого всех чисел, кратных выбранному числу. Это новое содержимое опять передается предикату отсеять. Предикат простые - это предикат самого верхнего уровня, такой что простые(N, L) конкретизирует L списком простых чисел, заключенных в диапазоне от 1 до N включительно.
простые(Предел,Рs):- целые(2,Предел,Is),отсеять(Is,Рs).
целые (Min,Max,[Min|Oct]):-Min=‹Max,!, М is Min+1,целые(М,Мах,Ост).
целые(_,_,[]).
отсеять([],[]).
отсеять([I|Is],[I|Ps]):-удалить(I,Is,Нов),отсеять(Нов,Рs).
удалить(Р,[],[]).
удалить (P,[I|Is],[I|Nis]):-not(0 is I mod Р),!,удалить(Р,Is,Nis).
удалить (P,[I|Is],Nis):-0 is I mod Р,!,удалить(Р,Is,Nis).
Продолжая эту арифметическую тему, рассмотрим Пролог-программу, реализующую рекурсивную формулировку алгоритма Евклида для нахождения наибольшего общего делителя (НОД) и наименьшего общего кратного (НОК) двух чисел. Целевое утверждение нод(I,J,K) доказуемо, если K является наибольшим общим делителем чисел I и J. Целевое утверждение нок(I,J,K) доказуемо, если K является наименьшим общим кратным чисел I и J:
нод(I,0,I).
нод(I,J,K):- R is I mod J, нод(J,R,K).
нок(I,J,K):- нод(I,J,R), K is (I*J)/R.
Заметим, что из-за особенностей способа вычисления остатка эти предикаты не являются «обратимыми». Это означает, что для того чтобы они работали, необходимо заблаговременно конкретизировать переменные I и J.
Упражнение 7.10. Если числа X, Y и Z таковы, что квадрат Z равен сумме квадратов X и Y (т. е. если Z?=X?+Y?), то про такие числа говорят, что они образуют Пифагорову тройку. Напишите программу, порождающую Пифагоровы тройки. Определите предикат pythag такой что, задав вопрос
?- pythag(X,Y,Z).
и запрашивая альтернативные решения, мы получим столько разных Пифагоровых троек, сколько пожелаем. Подсказка: используйте предикаты, подобные целое_число из гл. 4.
- 7.1. Словарь в виде упорядоченного дерева
- 7.2. Поиск в лабиринте
- 7.3. Ханойские башни
- 7.4. Справочник комплектующих деталей
- 7.5. Обработка списков
- 7.6. Представление и обработка множеств
- 7.7. Сортировка
- 7.8. Использование базы данных: random, генатом, найтивсе
- 7.9. Поиск по графу
- 7.10. Просеивай Двойки, Просеивай Тройки
- 7.11. Символьное дифференцирование
- 7.12. Отображение структур и преобразование деревьев
- 7.13. Применение предикатов clause и retract
- 2.5.3. Настройки панели задач и меню Пуск
- Описание программы настройки BIOS
- Настройки по умолчанию
- Настройки чипсета в BIOS
- Настройки ЦП
- Программы для диагностики и настройки видеокарты
- Почему в ноутбуке пропали системные звуки? При этом звуковые файлы воспроизводятся только в Winamp. Переустанавливал дра...
- 2.10.2. Настройки по умолчанию
- Листинг 3.2. Файл настройки программы inittab
- 3.2.4. Интересные настройки загрузки
- 3.6.4. Базовые настройки сети
- 6.1.1. Основные настройки