Решение упражнения 1.12 из SICP
Будем адресовать элементы треугольника Паскаля двумя числами: номером строки (строки нумеруются сверху вниз) и порядковым номером элемента в этой строке (число элементов растет с движением от более высоких строк к более низким и равно номеру строки). Нумеровать строки и элементы будем начиная с единицы.
Запишем функцию, вычисляющую заданный элемент в заданной строке треугольника Паскаля:
(define (pascal row element)
(cond ((or (= element 1) (= element row)) 1)
((and (> element 1) (< element row)) (+ (pascal (- row 1) (- element 1))
(pascal (- row 1) element)))))
Нужно учесть, что значение, которое возвращает процедура, неопределено для некорректных значений номеров строки и элемента, например для неположительных их значений или для номеров элемента больших номера строки.
Comments
Comment from Vitaly
Date: October 5, 2007, 1:48 am
Не совсем понял условие с and, для чего оно?
У меня вот такое решение:
(define (f x y)
(cond ((or (= x 1) (= y 1)) 1)
(else (+ (f x (- y 1))
(f (- x 1) y)))))
Comment from Sergey Khenkin
Date: October 5, 2007, 10:11 am
Виталий,
спасибо за комментарий.
У нас в решениях немного разные системы координат.
Я располагаю треугольник Паскаля основанием вниз и вершиной вверх. Далее первый параметр задает номер горизонтального ряда чисел (строку), а второй - номер элемента в этой строке. Количество элементов в строках разное и увеличивается. Оно равно номеру строки.
Условие с and - это проверка на выход номера элемента за границы допустимых значений (от 1 до номера строки).
По-хорошему, нужно добавить еще одну глобальную проверку на то, чтобы номер строки был не меньше 1.
В твоем (ничего, что я на ты?) решении система координат такова, что оси x и y направлены параллельно ребрам треугольника. В этом случае область допустимых значений параметров - все пары натуральных чисел. Поэтому проверка, подобная моей с and, не нужна.
Кстати, очень симпатичное и компактное решение. Мне нравится!
Comment from eugene0
Date: January 16, 2009, 10:24 am
Мой вариант:
(define (triangle row num)
(cond ((or ( num row)) 0)
((= row 1) 1)
(else (+
(triangle (- row 1) (- num 1))
(triangle (- row 1) num)
)
)
)
)
Плюсы этого решения:
- при некорректных аргументах всегда возвращается 0,
- за счет того, что в “неправильных” местах треугольника теперь нули, экономим на проверке условия о том, что крайний элемент ряда равен 1, это получится автоматически.
Comment from eugene0
Date: January 16, 2009, 10:25 am
Упс, извините, что такой странный код получился, к сожалению, не нашел возможности предпросмотра.
Comment from синдикат
Date: January 21, 2010, 5:12 pm
(define (paskal row col)
(if (or (= col 1) (= row col))
1
(+ (paskal (- row 1) col)
(paskal (- row 1) (- col 1)))))
Принципиально не отличается (=
Comment from Anonymous
Date: February 21, 2010, 10:24 am
(define (f x y)
(cond ((or (> y x) (< y 1)) 0)
((or (= x 1) (= y 1)) 1)
(else (+ (f (- x 1) (- y 1)) (f (- x 1) y))))
Write a comment