-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1_2_functions.clj
91 lines (88 loc) · 2.66 KB
/
1_2_functions.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(chapter "Custom Functions")
(section "Simple Functions")
(example "Define function"
(defn square [x] (* x x)))
(example "Use function"
(square 8))
(example "Multi-arg functions"
(defn mul-add [a b c] (+ (* a b) c))
(mul-add 3 10 5))
(example "Nullary function"
(defn nullary [] 10)
(nullary))
(example "Anonymous functions"
((fn [x] (+ x x)) 10)
(#(+ % %) 10)
(#(+ %1 %2) 10 20))
(example "Functions as values"
(defn twice [f] (fn [a] (f (f a))))
((twice square) 3))
(section "Recursive Functions")
(example "Recursive Fibonacci"
(defn rec-fib [n]
(cond
(== 0 n) 1
(== 1 n) 1
:else (+ (rec-fib (- n 1))
(rec-fib (- n 2)))))
(rec-fib 40))
(example "Memoized Fibonacci"
(def mem-fib
(memoize
(fn [n]
(cond
(== 0 n) 1
(== 1 n) 1
:else (+ (mem-fib (- n 1)) (mem-fib (- n 2)))))))
(mem-fib 90))
(example "Tail-recursive Fibonacci"
(defn iter-fib [n]
(letfn [(iter-fib' [n a b]
(if (== 0 n)
a
(iter-fib' (- n 1) b (+' a b))))]
(iter-fib' n 1 1)))
(iter-fib 90)
(iter-fib 10000)
(defn iter-fib-recur [n]
(letfn [(iter-fib' [n a b]
(if (== 0 n)
a
(recur (- n 1) b (+' a b))))]
(iter-fib' n 1 1)))
(iter-fib-recur 10000))
(example "Explicit loop Fibonacci"
(defn loop-fib [n]
(loop [n n a 1 b 1]
(if (== 0 n)
a
(recur (- n 1) b (+ a b)))))
(loop-fib 90))
(section "Pre and Post conditions")
(example "Fast power"
(defn power
"Raises a to the b-th power"
[a b]
{:pre [(<= 0 b)]
:post [(or (zero? b) (zero? a) (zero? (rem % a)))]}
(cond
(zero? b) 1
(even? b) (power (* a a) (quot b 2))
(odd? b) (* a (power a (dec b))))))
(example "Pre and postconditions ok"
(power 2 5)
(power 2 0)
(power 0 2))
(example "Precondition violated"
(power 2 -5))
(example "Invalid postcondition"
(defn ipower
[a b]
{:pre [(<= 0 b)]
:post [(= 0 (rem % a)) (<= 0 %)]}
(power a b)))
(example "First part of invalid postcondition violated"
(ipower 2 0)
(power -2 3))
(example "Second part of invalid postcondition violated"
(ipower -2 3))