/
core.clj
322 lines (254 loc) · 7.03 KB
/
core.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
(ns EssentialsOfProgrammingLanguages.core)
(defn timetester [lst f]
(dotimes [_ 5] (time (f lst))))
;1.2.1 list-lengh
(defn list-length [lst]
(if (empty? lst) 0 (+ 1 (list-length (rest lst)))))
;my
(defn clj-list-length [lst]
(loop [xs lst n 0]
(if (empty? xs)
n
(recur (rest xs) (inc n)))))
;1.2.2 nth
(defn clj-nth [lst n]
(if (zero? n)
(first lst)
(recur (next lst) (dec n))))
(defn scheme-nth [lst n]
(if (empty? lst)
(throw "to short")
(if (zero? n)
(first lst)
(recur (rest lst) (dec n)))))
;1.2.3
(defn scheme-remove-first [syb lst]
(if (empty? lst)
'()
(if (= (first lst) syb)
(rest lst)
(cons (first lst) (scheme-remove-first syb (rest lst))))))
(defn clj-remove-first [item coll]
(let [[pre post] (split-with #(not= % item) coll)]
(concat pre (rest post))))
;bonus
(defn clj-remove-all [item lst]
(filter (comp not #(= item %)) lst))
;1.2.4
;dont understand that! Don't know how to implement in clojure will be
;remet later in the book
(defn occurs-free? [var exp]
(cond
((symbol? exp) (= var exp))
((= (first exp) 'fn)
(and
(not (= var (first (second exp))))
(occurs-free? var (nth exp 2))))
:else
(or
(occurs-free? var (first exp))
(occurs-free? var (second exp)))))
;1.2.5 subst
(declare subst-in-s-exp subst)
(defn subst [new old slist]
(if (empty? slist)
'()
(lazy-seq (cons
(subst-in-s-exp new old (first slist))
(subst new old (rest slist))))))
(defn subst-in-s-exp [new old sexp]
(if (symbol? sexp)
(if (= sexp old) new sexp)
(subst new old sexp)))
;1.3 Auxiliary Procedures and context arguments
(defn scheme-number-elements-form [coll n]
(if (seq coll)
(cons (list n (first coll))
(scheme-number-elements-form (rest coll) (inc n)))
'()))
(defn number-elements [coll]
(scheme-number-elements-form coll 0))
;clj
(defn clj-number-elements-form
([coll] (clj-number-elements-form coll 0))
([coll n] (map (fn [a b] [a b]) (iterate inc n) coll)))
;scheme sum 1
(defn scheme-list-sum [loi]
(if (seq loi)
(+ (first loi)
(scheme-list-sum (rest loi)))
0))
;scheme sum 2
(defn partial-vector-sum [v n]
(if (zero? n)
(nth v 0)
(+ (nth v n)
(partial-vector-sum v (dec n)))))
(defn vector-sum [v]
(let [n (count v)]
(if (zero? n)
0
(partial-vector-sum v (dec n)))))
;clj idiomatic (dosn't make the point of this chapter)
(defn sum-of-vec [v]
(reduce + v))
;1.4
;1.15
(defn duple [mal x]
(loop [lst '() mal mal]
(if (zero? mal) lst (recur (conj lst x) (dec mal)))))
;1.16
(defn invert [coll]
(loop [coll coll newcoll []]
(if (seq coll)
(recur (vec (rest coll))
(conj newcoll (vec (reverse (first coll)))))
newcoll)))
;1.17
(defn down [coll]
(loop [newlist [] n 0]
(if (= (count coll) n)
newlist
(recur (conj newlist (list (nth coll n))) (inc n)))))
;1.18
(defn clj-swaper [lst c1 c2]
(loop [coll lst output []]
(if (seq coll)
(recur (rest coll)
(conj output (if (= c1 (first coll))
c2
(first coll))))
output)))
;1.19
(defn clj-coll-set [coll index x]
(loop [coll coll output [] i 0]
(if (seq coll)
(recur (rest coll) (conj output (if (= i index) x (first coll))) (inc i))
output)))
;1.2
(defn count-occurrences [item coll]
(cond
(empty? coll) 0
(seq? (first coll)) (+ (count-occurrences item (first coll))
(count-occurrences item (rest coll)))
(= item (first coll)) (inc (count-occurrences item (rest coll)))
:else (+ 0 (count-occurrences item (rest coll)))))
(defn count-occurrences-tail-call [item coll]
(count (filter (partial = item) (flatten coll))))
;;1.21
(defn product [sos1 sos2]
(mapcat (fn [item1]
(map (fn [item2]
[item1 item2]) sos2)) sos1))
;;1.22
(defn clj-filter-in [pred coll]
(loop [coll coll output []]
(if (seq coll)
(if (pred (first coll))
(recur (rest coll) (conj output (first coll)))
(recur (rest coll) output))
output)))
;;1.23
(defn coll-index [pred coll]
(count (take-while #(not (number? %)) coll)))
;;1.24
(defn -every? [pred coll]
(loop [coll coll]
(if (empty? coll)
true
(if (pred (first coll))
(recur (rest coll))
false))))
;;1.25
(def -exists? (complement -every?))
;;1.26
(defn up [coll]
(println coll)
(cond
(empty? coll) coll
(seq? (first coll)) (concat (first coll) (up (rest coll)))
:else (conj (up (rest coll)) (first coll))))
;;1.27
(defn -flatten [coll]
(cond
(empty? coll) coll
(seq? (first coll)) (concat (flatten (first coll)) (flatten (rest coll)))
:else (conj (rest coll) (first coll))))
;;1.28 merge
(defn -merge [coll1 coll2]
(sort (concat coll1 coll2)))
;1.31
(def tree1 '(bar 1 (foo 1 2)))
(def tree2
'(baz
(bar 1 (foo 1 2))
(biz 4 5)))
(def leaf identity)
(defn interior-node [sym branch1 branch2]
(conj (list branch1 branch2) sym))
(defn leaf? [bintree]
(when-not (seq? bintree)
true))
(defn lson [node]
(nth node 1))
(defn rson [node]
(nth node 2 ))
(defn contents-of [elem]
(if (leaf? elem)
elem
(first elem)))
(defn double-tree [tree]
(if (leaf? tree)
(* 2 (contents-of tree))
(cons (contents-of tree) (map double-tree [(lson tree) (rson tree)]))))
#_(define (red-depth tree depth)
(if (leaf? tree)
depth
(if (eq? (contents-of tree) 'red)
(cons (contents-of tree)
(list (red-depth (lson tree) (+ 1 depth))
(red-depth (rson tree) (+ 1 depth))))
(cons (contents-of tree)
(list (red-depth (lson tree) depth)
(red-depth (rson tree) depth))))))
(defn mark-leaves-with-red-depth
([tree] (mark-leaves-with-red-depth tree 0))
([tree depth]
(if (leaf? tree)
depth
(cons (contents-of tree)
(if (= (contents-of tree) 'red)
[(mark-leaves-with-red-depth (lson tree) (inc depth))
(mark-leaves-with-red-depth (rson tree) (inc depth))]
[(mark-leaves-with-red-depth (lson tree) depth)
(mark-leaves-with-red-depth (rson tree) depth)])))))
(def searchtree '(14 (7 () (12 () ()))
(26 (20 (17 () ())
())
(31 () ()))))
(def easysearchtree '(14 (17 () (12 () ()))
(26 () ())))
(defn scheme-path [n bst]
(if (empty? bst)
false
(if (= (first bst) n)
[]
(let [left (scheme-path n (nth bst 1))
right (scheme-path n (nth bst 2))]
(if (false? left)
(if (false? right)
false
(cons 'right right))
(cons 'left left))))))
(defn spath [n tree way]
(cond
(empty? tree) []
(= n (first tree)) way
:else [(spath n (lson tree) (conj way 'left))
(spath n (rson tree) (conj way 'right))]))
(defn path [n tree]
(flatten (spath n tree [])))
;2 Data Abstruction
2.1
(def base 16)
-