Category: Решения упражнений

Решение упражнения 2.47 из SICP

4 February, 2008 (21:36) | Решения упражнений | No comments

Итак, селекторы для первого варианта представления рамки записываются следующим образом:
(define (origin-frame frame)
(car frame))

(define (edge1-frame frame)
(cadr frame))

(define (edge2-frame frame)
(caddr frame))
Селекторы для второго варианта выглядят так:
(define (origin-frame frame)
(car frame))

(define (edge1-frame frame)
(cadr frame))

(define (edge2-frame frame)
(cddr frame))
Как видим, отличие лишь в последнем селекторе, что легко пояснить тем, […]

Решение упражнения 2.46 из SICP

4 February, 2008 (21:15) | Решения упражнений | 1 comment

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

Решение упражнения 2.45 из SICP

4 February, 2008 (20:56) | Решения упражнений | No comments

У процедур right-split и up-split есть очень много общего. По сути, они отличаются лишь порядком вызова операций beside и below. Таким образом мы можем ввести обобщенную операцию generic-split, которая будет задавать схему работы, общую для right-split и up-split, и процедуру высшего порядка split, которая с помощью generic-split по заданным операциям (главной и вложенной) будет генерировать конкретную […]

Решение упражнения 2.44 из SICP

4 February, 2008 (20:19) | Решения упражнений | No comments

Процедура up-split очень похожа на приводящуюся в книге right-split. Если right-split оставляет в левой части рамки старую рисовалку (ох и перевод!), а правую делит на две расположенные одна под другой части и вызывает себя для них рекурсивно, то up-split оставляет старую рисовалку в нижней половине рамки, а верхнюю делит на две части, расположенные рядом по […]

Решение упражнения 2.43 из SICP

3 February, 2008 (14:21) | Решения упражнений | 1 comment

Переставив фрагменты программы, Хьюго внес рекурсивный вызов queen-cols внутрь итерации по номерам строк, то есть если ранее при решении задачи для доски NxN решение задачи для доски (N-1)x(N-1) вычислялось один раз, то теперь это происходит N раз. Таким образом здесь пахнет экспоненциальным ухудшением производительности.
Примем упрощенно, что обработка очередной позиции (добавление одного ферзя и проверка на […]

Решение упражнения 2.42 из SICP

3 February, 2008 (12:47) | Решения упражнений | 8 comments

Задача о восьми ферзях - это классический пример проблемы, которая решается перебором вариантов. Задача сама по себе, как и задача о Ханойских башнях, весьма интересна, а ее решение показывает несколько важных алгоритмических приемов.
Каркас процедуры решения за нас уже определили заботливые авторы, нам же осталось только задать представление позиций на доске константой empty-board и процедурой adjoin-position, […]

Решение упражнения 2.41 из SICP

31 January, 2008 (22:59) | Решения упражнений | 1 comment

Определим сначала процедуру, генерирующую все наборы различных троек. Она строится аналогично процедуре, генерирующей все уникальные пары из прошлого упражнения (можно даже использовать unique-pairs в реализации, но я этого не буду делать:
(define (unique-triples n)
    (flatmap (lambda (i)
          (flatmap (lambda (j)
                (map (lambda (k) (list i j k))
                     (enumerate-interval 1 (- j 1))))
                   (enumerate-interval 1 (- i […]

Решение упражнения 2.40 из SICP

31 January, 2008 (22:45) | Решения упражнений | 1 comment

Процедура unique-pairs определяется способом, описанным в тексте параграфа:
(define (unique-pairs n)
  (flatmap (lambda (i) (map (lambda (j) (list i j))
                            (enumerate-interval 1 (- i 1))))
           (enumerate-interval 1 (- n 1))))
Теперь процедуру prime-sum-pairs легко определить таким образом, чтобы она генерировала все уникальные пары, фильтровала их, оставляя только пары с простой суммой, а затем строила тройки (слагаемое, слагаемое, сумма) по этим […]

Решение упражнения 2.39 из SICP

31 January, 2008 (21:11) | Решения упражнений | 1 comment

Определить reverse через свертки можно таким образом:
(define (reverse sequence)
  (fold-right (lambda (x y) (append y (list x))) nil sequence))
(define (reverse sequence)
  (fold-left (lambda (x y) (cons y x)) nil sequence))
Определения получаются путем анализа процесса вычислений сверток.
Хочу отметить, что использование для реверсирования последовательности левой свертки более видится более эффективным, поскольку задействованные операции более простые, а процесс […]

Решение упражнения 2.38 из SICP

31 January, 2008 (20:41) | Решения упражнений | 3 comments

Результаты, получаемые каждой из функций свертки, приведены ниже. Сначала я показываю ответ, а затем ход его построения для наглядности:
(fold-right / 1 (list 1 2 3))

(/ 1 (/ 2 (/ 3 1)))
(fold-left / 1 (list 1 2 3))
1/6
(/ (/ (/ 1 1) 2) 3)
(fold-right list nil (list 1 2 3))
(1 (2 (3 ())))
(list 1 (list 2 […]