Малки контролни от лекции
Защото малките неща в живота ни радват най-много.
Първо малко контролно
Група I
Оценете в глобалната среда:
а.)
(define (f x y)
(define (g x)
(+ x y)
)
(+ (g x) y )
)
б.) (f 3 4)
в.) (g 5)
Като за начало - какво означава условието на задачата.
"Оценете в глобалната среда." означава кажете каква е стойността която се получава след оценяването на дадения списък(Би трябвало да знаете какво е списък и среда, ако не - погледнете лекциите и ще разберете, не е страшно).
В а.) имаме дефиниция на функция "f" приемаща 2 аргумента, в средата на тази фунцкия имаме дефиниция на друга функция "g", която приема един аргумент, но използва и 2-я аргумент от "f". "g" може да направи това, защото е в средата на "f". "f" връща сбора на двата аргумента + втория аргумент, реално стойноста "x+2*y". И така имаме отговора на първата и втората подточки:
Все пак, за да е валидно решението, трябва или да бъде споменат горният текст, или с картинка да бъде илюстрирано коя функция в коя среда е.
Ако изпълним
в.) :
> (g 5)
reference to undefined identifier: g
имплементаторът ни дава грешка - "g" е функция, която не се вижда от глобалнаа среда, тя съществува само за средата на фунцкията "f".
Група II
Оценете в глобалната среда:
а.)
(define (f x y)
(define (g x)
(+ x y)
)
(+ (g x) y )
)
б.) (f 2 4)
в.) (g 4)
Решенията за тази група са напълно еквивалентни на тези за предишната. Отговорът на б.) е 48.
Второ малко контролно
Да се реализира функция, приемаща два аргумента - х и N и изчислява приближение на степен на неперовото число $e^x$ по следната формула:
(1)
\begin{align} a_n = 1 + \cfrac{x}{1} + \cfrac{x^2}{2!} + \cfrac{x^3}{3!} + \cdots + \cfrac{x^n}{n!} \end{align}
I група
С рекурсия.
II група
С итерация.
Рекурсия:
Единият вариант е да използваме функциите за повдигане на N-та степен и намиране на N!:
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)) )
)
)
(define (power x n)
(if (= n 0)
1
(* x (power x (- n 1)) )
)
)
(define (approximate_e n x)
(if (= n 0)
1
(+
(/ (power x n ) (fact n))
(approximate_e (- n 1) x)
)
)
)
Итерация. Тръгваме отзад напред.
На всяка стъпка
n умножаваме целият текущ резултат по
$\cfrac{x}{n}$ и отиваме в стъпка
n-1. По този начин всички членове ще се умножат по точната степен на X и ще се разделят на точно колкото трябва факториел :)
(define (a_e x n current_term)
(if (= n -1)
current_term
(a_e
x
(- n 1)
(+
(* current_term (/ x (+ n 1)) )
1
)
)
)
)
(define (approximate_e n x)
(a_e x n 1)
)
Пето малко контролно
Това контролно е лесно и проверява уменията за създаване на списък и достъпване на елементите му.
1. Списъкът l има вида ((a b (c)) (d) e)
Като използвате единствено процедурите car и cdr достигнете до елементите a,b,c,d,e. Естествено, композиции от рода на cadr, caddr също са позволени.
Тук всичко е лесно и няма скрити изненади. Естествено, има два начина да се решат задачите. Единият е верен и трудоемък, другият е верен и мързелив.
a = (caar l)
;(car (car l))
b = (cadar l)
;(car (cdr (car l)))
c = (caadr (cdar l))
;(car (car (cdr (cdr (car l)))))
d = (caadr l)
;(car (car (cdr l)))
e = (caddr l)
;(car (cdr (cdr l)))
2. Списъкът l= (all these problems) е даден. Да се състави списък със следния вид:
- ((all) these problems)
- (all ((these) problems))
- (all (these problems))
- ((all) (these) (problems))
Позволено е да се използват car, cdr, cons, list. В условието не пише за list, но може.
Положението отново е същото. Няма нищо трудно, но все пак е по-добре да не си чупим ръцете, пишейки решението.
all = (car l)
these = (cadr l)
problems = (caddr l)
((all) these problems) = (list (list (car l)) (cadr l) (caddr l))
(all ((these) problems)) = (list (car l) (list (list (cadr l)) (caddr l)))
(all (these problems)) = (list (car l) (cdr l))
((all) (these) (problems)) = (list (list (car l)) (list (cadr l)) (list (caddr l)))
Шесто малко контролно
В това контролно се проверява доколко са усвоени функциите за работа със списъци. Могат да се използват всички неща, дадени до момента, включително map/filter/reduce/accumulate.
Даден е списък от списъци. Всеки елемент на този списък представлява данни за ученик в следния формат:
(Име среден_успех брой_отсъствия)
Да се напише процедура, която да връща тези ученици, които имат успех по-голям или равен на средния и отсъствия не повече от средните.
Пример:
Входни данни:
(
(Георги 6 0)
(Иван 4 4)
(Пешо 5 2)
)
Резултат:
(
(Георги 6 0)
(Пешо 5 2)
)
Нищо сложно, щом имаме filter и map. С няколко let-а ще си направим живота по-лесно четим.
fist, second, third са еквивалентни на car, cadr, caddr
(define (best_students list)
(let (
(avg_marks (/
(reduce (lambda (x y) (+ (second x) y)) 0 list)
(len list)
)
)
(avg_abscences (/
(reduce (lambda (x y) (+ (third x) y)) 0 list)
(len list)
)
)
)
#|Тук се връща резултатът от смятането.|#
(filter
(lambda (l)
(and
(>= (second l) avg_marks)
(<= (third l) avg_abscences)
)
)
list
)
)
)
Х'то малко контролно
Да се генерира поток:
(2)
\begin{align} x , -\frac{x^3}{3!} , \frac{x^5}{5!} , -\frac{x^7}{7!}, \cdots, (-1)^n\frac{x^{2n+1}}{(2n+1)!}, \cdots \end{align}
(define (xterm crnt x n)
(* crnt x x -1 (/ 1 (+ n 1) (+ n 2))))
(define (xfrom crnt x n)
(cons crnt (delay (xfrom (xterm crnt x n) x (+ n 2)))))
(define (xstream x) (xfrom x x 1))