four-clojure-problems / src / four_clojure / answered.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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
(ns four-clojure.answered)

; http://www.4clojure.com/problem/5
; Lists: conj
; When operating on a list, the conj function will return a new list with one or more items "added" to the front.
(= '(1 2 3 4) (conj '(2 3 4) 1))


; http://www.4clojure.com/problem/6
; Intro to Vectors
; Vectors can be constructed several ways. You can compare them with lists.
(= [:a :b :c] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))

; http://www.4clojure.com/problem/7
; Vectors: conj
; When operating on a Vector, the conj function will return a new vector with one or more items "added" to the end.
(= [1 2 3 4] (conj [1 2] 3 4))


; http://www.4clojure.com/problem/8
; Intro to Sets
(= #{:a :b :c :d} (clojure.set/union #{:a :b :c} #{:b :c :d}))

; http://www.4clojure.com/problem/9
; Sets: conj
(= #{1 2 3 4} (conj #{1 4 3} 2))

; http://www.4clojure.com/problem/10
; Intro to Maps
; Maps store key-value pairs. Both maps and keywords can be used as lookup functions. Commas can be used to make maps more readable, but they are not required.
(= 20 (:b {:a 10, :b 20, :c 30}))


; http://www.4clojure.com/problem/11
; Maps: conj
; When operating on a map, the conj function returns a new map with one or more key-value pairs "added".
(= {:a 1, :b 2, :c 3} (conj {:a 1} {:b 2} [:c 3]))

; http://www.4clojure.com/problem/12
; Intro to Sequences
; All Clojure collections support sequencing. You can operate on sequences with functions like first, second, and last.

(= 3 (first '(3 2 1)))
(= 3 (second [2 3 4]))
(= 3 (last (list 1 2 3)))

; http://www.4clojure.com/problem/13
; Sequences: rest
; The rest function will return all the items of a sequence except the first.

(= [20 30 40] (rest [10 20 30 40]))


; http://www.4clojure.com/problem/14
; Intro to Functions
; Clojure has many different ways to create functions.
(= 8 ((fn add-five [x] (+ x 5)) 3))
(= 8 ((fn [x] (+ x 5)) 3))
(= 8 (#(+ % 5) 3))
(= 8 ((partial + 5) 3))


; http://www.4clojure.com/problem/15
; Double Down
; Write a function which doubles a number
(= (* 2 2) 4)
(= (* 2 11) 22)

; http://www.4clojure.com/problem/16
; Hello World
; Write a function which returns a personalized greeting.
(= (#(str "Hello, " % "!") "Dave") "Hello, Dave!")

; http://www.4clojure.com/problem/17
; Sequences: map
; The map function takes two arguments: a function (f) and a sequence (s). Map returns a new sequence consisting of the result of applying f to each item of s. Do not confuse the map function with the map data structure.
(= [6 7 8] (map #(+ % 5) '(1 2 3)))

; http://www.4clojure.com/problem/18
; Sequences: filter
; The filter function takes two arguments: a predicate function (f) and a sequence (s). Filter returns a new sequence consisting of all the items of s for which (f item) returns true.
(= [6 7] (filter #(> % 5) '(3 4 5 6 7)))


; http://www.4clojure.com/problem/35
; Local bindings
; Clojure lets you give local names to values using the special let-form.
(= 7 (let [x 5] (+ 2 x)))

; http://www.4clojure.com/problem/36
; Let it Be
; Can you bind x, y and z so that these are all true?

(= 10 (let [x 7 y 3 z 1] (+ x y)))
(= 4 (let [x 7 y 3 z 1] (+ y z)))
(= 1 (let [x 7 y 3 z 1] z))


; http://www.4clojure.com/problem/37
; Regular Expressions
; Regex patterns are supported with a special reader macro.
(= "ABC" (apply str (re-seq #"[A-Z]+" "bA1B3Ce ")))

; http://www.4clojure.com/problem/64
; Intro to Reduce
; Reduce takes a 2 argument function and an optional starting value. It then applies the function to the first 2 items in the sequence (or the starting value and the first element of the sequence). In the next iteration the function will be called on the previous return value and the next item from the sequence, thus reducing the entire collection to one value. Don't worry, it's not as complicated as it sounds.
(= 15 (reduce + [1 2 3 4 5]))
(=  0 (reduce + []))
(=  6 (reduce + 1 [2 3]))

; http://www.4clojure.com/problem/57
; Simple Recursion
; A recursive function is a function which calls itself. This is one of the fundamental techniques used in functional programming.
(= [5 4 3 2 1] ((fn foo [x] (when (> x 0) (conj (foo (dec x)) x))) 5))

; http://www.4clojure.com/problem/71
; Rearranging Code: ->
; The -> macro threads an expression x through a variable number of forms. First, x is inserted as the second item in the first form, making a list of it if it is not a list already. Then the first form is inserted as the second item in the second form, making a list of that form if necessary. This process continues for all the forms. Using -> can sometimes make your code more readable.
(= (last (sort (rest (reverse [2 5 4 1 3 6]))))
   (-> [2 5 4 1 3 6] reverse rest sort last)
   5)

; http://www.4clojure.com/problem/68
; Recurring Theme
; Clojure only has one non-stack-consuming looping construct: recur. Either a function or a loop can be used as the recursion point. Either way, recur rebinds the bindings of the recursion point to the values it is passed. Recur must be called from the tail-position, and calling it elsewhere will result in an error.
(= [7 6 5 4 3]
  (loop [x 5
         result []]
    (if (> x 0)
      (recur (dec x) (conj result (+ 2 x)))
      result)))

; http://www.4clojure.com/problem/72
; Rearranging Code: ->>
; The ->> macro threads an expression x through a variable number of forms. First, x is inserted as the last item in the first form, making a list of it if it is not a list already. Then the first form is inserted as the last item in the second form, making a list of that form if necessary. This process continues for all the forms. Using ->> can sometimes make your code more readable.
(= (reduce + (map inc (take 3 (drop 2 [2 5 4 1 3 6]))))
   (->> [2 5 4 1 3 6] (drop 2) (take 3) (map inc) (reduce +))
   11)

; http://www.4clojure.com/problem/134
; A nil key
; Write a function which, given a key and map, returns true iff the map contains an entry with that key and its value is nil.
(defn nil-key? [x m]
  (and (contains? m x) (nil? (get m x))))

(true?  (nil-key? :a {:a nil :b 2}))
	
(false? (nil-key? :b {:a nil :b 2}))
	
(false? (nil-key? :c {:a nil :b 2}))

; http://www.4clojure.com/problem/145
; For the win
; Clojure's for macro is a tremendously versatile mechanism for producing a sequence based on some other sequence(s). It can take some time to understand how to use it properly, but that investment will be paid back with clear, concise sequence-wrangling later. With that in mind, read over these for expressions and try to see how each of them produces the same result.
(defn for-the-win [] (range 1 40 4))
(= (for-the-win) (for [x (range 40)
            :when (= 1 (rem x 4))]
        x))
(= (range 1 40 4) (for [x (iterate #(+ 4 %) 0)
            :let [z (inc x)]
            :while (< z 40)]
        z))
(= (range 1 40 4) (for [[x y] (partition 2 (range 20))]
        (+ x y)))

; http://www.4clojure.com/problem/19
; Last Element
; Write a function which returns the last element in a sequence.
; restriction: last

(defn last-element [s] 
  (reduce (fn [x y] y) 
  s))
(= (last-element [1 2 3 4 5]) 5)
(= (last-element '(5 4 3)) 3)
(= (last-element ["b" "c" "d"]) "d")

; http://www.4clojure.com/problem/20
; Penultimate Element
; Write a function which returns the second to last element from a sequence.
(defn penultimate [s]
  ((comp first rest reverse) s))
(= (penultimate (list 1 2 3 4 5)) 4)
(= (penultimate ["a" "b" "c"]) "b")
(= (penultimate [[1 2] [3 4]]) [1 2])

; http://www.4clojure.com/problem/21
; Nth Element
; Write a function which returns the Nth element from a sequence
; restriction: nth
(defn my-nth [a x] (if (= 0 x) (first a) (my-nth (rest a) (- x 1))))
; or 
; #(first (drop %2 %))

(= (my-nth '(4 5 6 7) 2) 6)
(= (my-nth [:a :b :c] 0) :a)
(= (my-nth [1 2 3 4] 1) 2)
(= (my-nth '([1 2] [3 4] [5 6]) 2) [5 6])

; http://www.4clojure.com/problem/22
; Count a Sequence
; Write a function which returns the total number of elements in a sequence
; restriction: count
(defn my-count [s] (reduce (fn [i x] (+ 1 i)) 0 s))

(= (my-count '(1 2 3 3 1)) 5)
(= (my-count "Hello World") 11)
(= (my-count [[1 2] [3 4] [5 6]]) 3)
(= (my-count '(13)) 1)
(= (my-count '(:a :b :c)) 3)

; http://www.4clojure.com/problem/24
; Sum It All Up
; Write a function which returns the sum of a sequence of numbers
(defn sum [s] (reduce + s))

(= (sum [1 2 3]) 6)
(= (sum (list 0 -2 5 5)) 8)
(= (sum #{4 2 1}) 7)
(= (sum '(0 0 -1)) -1)
(= (sum '(1 10 3)) 14)


; http://www.4clojure.com/problem/25
; Find the odd numbers
; Write a function which returns only the odd numbers from a sequence
(defn only-odds [s] (filter odd? s))

(= (only-odds #{1 2 3 4 5}) '(1 3 5))
(= (only-odds [4 2 1 6]) '(1))
(= (only-odds [2 2 4 6]) '())
(= (only-odds [1 1 1 3]) '(1 1 1 3))

; http://www.4clojure.com/problem/23
; Reverse a Sequence
; Write a funciton which reverses a sequence
; restriction: rseq, reverse
(defn my-reverse [s]
    (reduce conj '() s)
  )
; or
; into ()
(= (my-reverse [1 2 3 4 5]) [5 4 3 2 1])
(= (my-reverse (sorted-set 5 7 2 7)) '(7 5 2))
(= (my-reverse [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]])


; http://www.4clojure.com/problem/27
; Palindrome Detector
; Write a function which returns true if the given sequence is a palindrome.
; Hint: "racecar" does not equal '(\r \a \c \e \c \a \r)
(defn palindrome? [s] (= (seq s) (reverse s)))

(false? (palindrome? '(1 2 3 4 5)))
(true? (palindrome? "racecar"))
(true? (palindrome? [:foo :bar :foo]))
(true? (palindrome? '(1 1 3 3 1 1)))
(false? (palindrome? '(:a :b :c)))

; http://www.4clojure.com/problem/26
; Fibonacci Sequence
; Write a function which returns the first X Fibonacci numbers
(defn fibonacci [s] 
  (#(take % (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1]))) s)
  )
(= (fibonacci 3) '(1 1 2))
(= (fibonacci 6) '(1 1 2 3 5 8))
(= (fibonacci 8) '(1 1 2 3 5 8 13 21))


; http://www.4clojure.com/problem/38
; Maximum Value
; Write a function which takes a variable number of parameters and returns a maximum value.
; restrictions: max, max-key
(defn my-max [& xs] 
  (#(reduce (fn [a b] (if (> a b) a b)) xs))
  )
(= (my-max 1 8 3 4) 8)
(= (my-max 30 20) 30)
(= (my-max 45 67 11) 67)

; http://www.4clojure.com/problem/29
; Get the Caps
; Write a function which takes a string and returns a new string containing only the capital letters
(defn all-caps [s] 
  (#(apply str (re-seq #"[A-Z]" s))))

(= (all-caps "HeLlO, WoRlD!") "HLOWRD")
(empty? (all-caps "nothing"))
(= (all-caps "$#A(*&987Zf") "AZ")

; http://www.4clojure.com/problem/48
; Intro to some
; The some function takes a predicate function and a collection. It returns the first logical true value of (predicate x) where x is an item in the collection.
(= 6 (some #{2 7 6} [5 6 7 8]))
(= 6 (some #(when (even? %) %) [5 6 7 8]))

; http://www.4clojure.com/problem/32
; Duplicate a Sequence
; Write a function which duplicates each element of a sequence.

(defn dup-seq [s]
  (#(reverse (reduce (fn [a x] (conj (conj a x) x)) () s))))
; or
; mapcat #(list % %)
; #(interleave % %)

(= (dup-seq [1 2 3]) '(1 1 2 2 3 3))
(= (dup-seq [:a :a :b :b]) '(:a :a :a :a :b :b :b :b))
(= (dup-seq [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4]))
(= (dup-seq [[1 2] [3 4]]) '([1 2] [1 2] [3 4] [3 4]))

; http://www.4clojure.com/problem/47
; Contain Yourself
; The contains? function checks if a KEY is present in a given collection. This often leads beginner clojurians to use it incorrectly with numerically indexed collections like vectors and lists.
(contains? #{4 5 6} 4)
(contains? [1 1 1 1 1] 4)
(contains? {4 :a 2 :b} 4)
(not (contains? '(1 2 4) 4))


; http://www.4clojure.com/problem/34
; Implement range
; Write a funcction which creates a list of all integers in a given range
; restrictions: range
(defn my-range [x y]
  (take (- y x) (iterate inc x)))

(= (my-range 1 4) '(1 2 3))
(= (my-range -2 2) '(-2 -1 0 1))
(= (my-range 5 8) '(5 6 7))


; http://www.4clojure.com/problem/45
; Intro to Iterate
; The iterate function can be used to produce an infinte lazy sequence
(= [1 4 7 10 13] (take 5 (iterate #(+ 3 %) 1)))

; http://www.4clojure.com/problem/28
; Flatten a Sequence
; Write a function which flattens a sequence
; restriction: flatten 

(defn my-flatten [s] 
  (#(filter (complement sequential?) (rest (tree-seq sequential? seq s)))))

(= (my-flatten '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))
(= (my-flatten ["a" ["b"] "c"]) '("a" "b" "c"))
(= (my-flatten '((((:a))))) '(:a))

; http://www.4clojure.com/problem/42
; Factorial Fun
; Write a function which calculates factorials.
(defn ! [x] (if (= 1 x) 1 (* x (! (dec x)))))
; or
; #(apply * % (range 2 %))
;
(= (! 1) 1)
(= (! 3) 6)
(= (! 5) 120)
(= (! 8) 40320)

; http://www.4clojure.com/problem/30
; Compress a sequence 
; Write a function which removes consecutive duplicates from a sequence
(defn compress-seq [s]
            (map first (partition-by identity s)))

(= (apply str (compress-seq "Leeeeeerrroyyy")) "Leroy")
(= (compress-seq [1 1 2 3 3 2 2 3]) '(1 2 3 2 3))
(= (compress-seq [[1 2] [1 2] [3 4] [1 2]]) '([1 2] [3 4] [1 2]))

; http://www.4clojure.com/problem/33
; Replicate a Sequence
; Write a function which replicates each element of a sequence a variable number of times.
(defn my-replicate [s n] (mapcat #(repeat n %) s))
; or
; partial can be used to get a 2nd anon function
; #(mapcat (partial repeat %2) %)

(= (my-replicate [1 2 3] 2) '(1 1 2 2 3 3))
(= (my-replicate [:a :b] 4) '(:a :a :a :a :b :b :b :b))
(= (my-replicate [4 5 6] 1) '(4 5 6))
(= (my-replicate [[1 2] [3 4]] 2) '([1 2] [1 2] [3 4] [3 4]))
(= (my-replicate [44 33] 2) [44 44 33 33])

; http://www.4clojure.com/problem/39
; Interleave Two Seqs
; Write a function which takes two sequences and returns the first item from each, then the second item from each, then the third, etc.
; restriction: interleave

(defn my-interleave ([x y]
        (and (seq x) (seq y) (cons (first x) (cons (first y) 
                                 (my-interleave (rest x) (rest y)))))))
; or
; mapcat list
  

(= (my-interleave [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))
(= (my-interleave [1 2] [3 4 5 6]) '(1 3 2 4))
(= (my-interleave [1 2 3 4] [5]) [1 5])
(= (my-interleave [30 20] [25 15]) [30 25 20 15])

; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;


; http://www.4clojure.com/problem/
;
;




(println "done")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.