
3.5. Потоки
311
либо оно простое (а в таком случае, имеется уже сгенерированное простое число — то
есть, простое число меньше n , — большее
√
n
63
.
Упражнение 3.53.
Не запуская программу, опишите элементы потока, порождаемого
(define s (cons-stream 1 (add-streams s s)))
Упражнение 3.54.
Определите процедуру mul-streams, аналогичную add-streams, которая порождает поэлемент-
ное произведение двух входных потоков. С помощью нее и потока integers закончите следующее
определение потока, n-й элемент ко торого (начиная с 0) равен факториалу n + 1:
(define factorials (cons-stream 1 (mul-streams h??i h??i)))
Упражнение 3.55.
Определите процедуру partial-sums, которая в качестве аргумента берет поток S, а возвра-
щает поток, элементы которого равны S
0
, S
0
+ S
1
, S
0
+ S
1
+ S
2
, . . .. Например, (partial-sums
integers) должно давать поток 1, 3, 6, 10, 15 . . .
Упражнение 3.56.
Существует знаменитая задача, впервые сформулированная Р. Хэммингом: породить в возраста-
ющем порядке и без повторений все положительные целые числа, у которых нет других простых
делителей, кроме 2, 3 и 5. Очевидно е решение состоит в том, чтобы перебирать все натуральные
числа по очереди и проверять, есть ли у них простые множители помимо 2, 3 и 5. Однако эта
процедура весьма неэффективна, поскольку чем больше числа, тем меньшая их доля соответствует
условию. Применим альтернативный подход: назовем искомый поток чисел S и обратим внимание
на следующие факты:
• S начинается с 1.
• Элементы (scale-streams 2) также принадлежат S
• То же верно и для (scale-stream S 3) и (scale-stream S 5).
• Других элементов S нет.
Теперь требуется только соединить элементы из этих источников. Для этого мы определяем
процедуру merge, которая сливает два упорядоченных потока в один упорядоченный поток, убирая
при этом повторения:
(define (merge s1 s2)
(cond ((stream-null? s1) s2)
((stream-null? s2) s1)
(else
(let ((s1car (stream-car s1))
(s2car (stream-car s2)))
63
Это тонкая деталь, которая основана на том, что p
n+1
≤ p
2
n
(Здесь p
k
обозначает k-е простое число.) Такие
оценки достаточно трудно доказать. Античное доказательство Евклида показывает, что имеется бесконечное
количество простых чисел, и что p
n+1
≤ p
1
p
2
···p
n
+ 1. Никакого существенно лучшего результата не
было найдено до 1851 года, когда русский математик П. Л. Чебышев доказал, что для всех n, p
n+1
≤ 2p
n
.
Предположение, что это так, было высказано в 1 845 году и известно как гипотеза Бертрана (Bertrand’s
hypothesis). Доказательство можно найти в разделе 22.3 в книге Hardy and Wright 1960.