Домашнее задание № 7
Для выполнения задания найди ссылку-приглашение в онлайн чате, получи доступ к репозиторию с файлом-заготовкой и заполни пропуски в нём. Фиксируй изменения (делай коммиты) после решения каждой задачи. Оставь название файла неизменным, иначе робот-проверятель не найдёт твои ответы. Отправить решения на GitHub нужно до истечения установленного срока. |
Интерпретатор Scheme уже находится в репозитории — файл scheme
. Для запуска используй:
python3 scheme
Для загрузки в интерпретатор файла (например, hw_07.scm
) используй
python3 scheme -load hw_07.scm
Вопрос 1
Определи процедуры cadr
и caddr
, которые возвращают второй и третий элементы списка соответственно:
(define (cddr s)
(cdr (cdr s)))
(define (cadr s)
; ТВОЙ КОД ЗДЕСЬ
nil
)
(define (caddr s)
; ТВОЙ КОД ЗДЕСЬ
nil
)
В этот раз тесты
|
Условные выражения
Специальная форма cond
— это обобщенное условное выражение, похожее на условное выражение в Python с несколькими предложениями. Обобщенное условное выражение выглядит так:
(cond
(<p1> <e1>)
(<p2> <e2>)
...
(<pn> <en>)
(else <выражение-else>))
Оно состоит из символа cond
, за которым следуют пары выражений (<p> <e>)
, называемые предложениями. Первое выражение в каждой паре — предикат (выражение, значение которого интерпретируется как true
или false
).
В Scheme все значения, за исключением специального булевого значения False
(исторически называемого #f
) интерпретируются как истинные. Также существует булево значение True
(исторически называемого #t
). В твоей версии Scheme False
и #f
могут использоваться взаимозаменяемо.
Условные выражения обрабатываются следующим образом. Сначала вычисляется значение предиката <p1>
. Если его значение ложно (false
), то вычисляется <p2>
. Если значение <p2>
также ложно, то вычисляется значение <p3>
. Этот процесс продолжается, пока не будет найден предикат со значением true
. После этого интерпретатор возвращает значение соответствующего выражения <e>
в качестве результата всего условного выражения. Если ни один из предикатов <p>
не имеет значение true
, интерпретатор возвращает значение <выражение-else>
в качестве результата всего условного выражения.
Слово «предикат» используется как для процедур, возвращающих true
или false
, так и для выражений.
Вопрос 2
Используя выражение cond
, определи процедуру sign
, которая принимает один параметр x
и возвращает -1
при отрицательном аргументе, 0
при нулевом и 1
при положительном:
(define (sign x)
; ТВОЙ КОД ЗДЕСЬ
nil
)
Вопрос 3
Реализуй процедуру pow
для возведения числа b
в целую неотрицательную степень n
, которая имеет временной порядок роста \(\Theta (\log n)\).
Обдумай вот что:
Используй встроенные предикаты |
(define (square x) (* x x))
(define (pow b n)
; ТВОЙ КОД ЗДЕСЬ
nil
)
Вопрос 4
Напиши процедуру (предикат) ordered?
, которая принимает список чисел и возвращает true
, если числа расположены в неубывающем порядке, иначе false
. Предикат — это процедура, результат выполнения которой либо true
, либо false
. Неубывающий порядок означает, что каждый следующий элемент больше или равен предыдущего. То есть 1 2 3 3 4 ` — не убывает, `1 2 3 3 2
— убывает.
тебе может пригодиться встроенный предикат null? , который проверяет аргумент на равенство nil .
|
(define (ordered? s)
; ТВОЙ КОД ЗДЕСЬ
nil
)
Множества на упорядоченных списках
Множество — это коллекция, которая содержит уникальные элементы. Основная операция для коллекции — проверка принадлежности элемента множеству.
Встроенного в Scheme типа данных для представления множеств не существует, однако одним из способов организации множества является представление его упорядоченным списком (упорядочивание нужно, чтобы вычисление объединений union
и перечислений intersection
были проще). Следующие вопросы развивают эту идею. Таким образом, представляй множество упорядоченным от меньшего к большему списком без повторяющихся элементов.
Вопрос 5
Сперва определи процедуру add
, которая принимает множество s
и значение v
. Процедура должна возвращать представление множества, содержащее все элементы исходного s
вместе со значением v
. Результат не должен содержать одинаковые элементы.
(define (empty? s) (null? s))
(define (add s v)
; ТВОЙ КОД ЗДЕСЬ
nil
)
Вопрос 6
Теперь определи процедуру contains?
, которая проверяет принадлежность значения v
множеству s
. Реализация этой процедуры на Python приведена для удобства.
(define (contains? s v)
; ТВОЙ КОД ЗДЕСЬ
nil
)
Вопрос 7
Наконец, создай процедуру intersect
(пересечение), которая возвращает множество элементов, входящих одновременно и в множество s
, и в множество t
.
Также определи процедуру union
(объединение), которая возвращает множество элементов, принадлежащих любому из множеств s
или t
.
Реализация обеих процедур должна требовать линейного времени от длины исходных множеств.
(define (contains? s v)
; ТВОЙ КОД ЗДЕСЬ
nil
)