# DokuWiki

### Sidebar

• Lectures
• Study
• Tips
lecture:4clojure:core_function_4clojure_problem

# Core function 4Clojure problem

## 1. Maximum Value

문제

Difficulty: Easy

Topics: core-functions

Write a function which takes a variable number of parameters and returns the maximum value.

```(= (__ 1 8 3 4) 8)

(= (__ 30 20) 30)

(= (__ 45 67 11) 67)
```

Source clojure/contrib/generic/comparison.clj:200

```(fn max
([x] x)
([x y] (if (> x y) x y))
([x y & more]
(reduce max1 (max1 x y) more)))```

maximental's solution:

`#(last (sort %&))`

psk810's solution:

`(fn [& args] (reduce #(if (> %1 %2) %1 %2) args))`

## 2. Implement range

문제

Difficulty: Easy

Topics: seqs core-functions

Write a function which creates a list of all integers in a given range.

```(= (__ 1 4) '(1 2 3))

(= (__ -2 2) '(-2 -1 0 1))

(= (__ 5 8) '(5 6 7))```

Source clojure/core.clj:882

```(fn range
([] (range 0 Double/POSITIVE_INFINITY 1))
([end] (range 0 end 1))
([start end] (range start end 1))
([start end step]
(lazy-seq
(let [b (chunk-buffer 32)
comp (if (pos? step) < >)]
(loop [i start]
(if (and (< (count b) 32)
(comp i end))
(do
(chunk-append b i)
(recur (+ i step)))
(chunk-cons (chunk b)
(when (comp i end)
(range i end step)))))))))```

maximental's solution:

`#(take (- %2 %) (iterate inc %))`

psk810's solution:

`(fn [s e] (take-while #(< % e) (iterate inc s)))`

## 3. Flatten a Sequence

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which flattens a sequence.

```(= (__ '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6))

(= (__ ["a" ["b"] "c"]) '("a" "b" "c"))

(= (__ '((((:a))))) '(:a))```

Source clojure/core.clj:6218(=psk810)

```(fn  [x]
(filter (complement sequential?)
(rest (tree-seq sequential? seq x))))```

maximental's solution:

```(fn f [[h & t]]
(if h
(if (coll? h)
(concat (f h) (f t))
(cons h (f t)))))```

## 4. Interleave Two Seqs

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which takes two sequences and returns the first item from each, then the second item from each, then the third, etc.

```(= (__ [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))

(= (__ [1 2] [3 4 5 6]) '(1 3 2 4))

(= (__ [1 2 3 4] ) [1 5])

(= (__ [30 20] [25 15]) [30 25 20 15])```

Source clojure/core.clj:3820

```(fn interleave
([c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
(when (and s1 s2)
(cons (first s1) (cons (first s2)
(interleave (rest s1) (rest s2))))))))
([c1 c2 & colls]
(lazy-seq
(let [ss (map seq (conj colls c2 c1))]
(when (every? identity ss)
(concat (map first ss) (apply interleave (map rest ss))))))))```

maximental's solution:

`mapcat list`

psk810's solution:

`(fn [m1 m2] (mapcat #(vector %1 %2) m1 m2))`

## 5. Interpose a Seq

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which separates the items of a sequence by an arbitrary value.

```(= (__ 0 [1 2 3]) [1 0 2 0 3])

(= (apply str (__ ", " ["one" "two" "three"])) "one, two, three")

(= (__ :z [:a :b :c :d]) [:a :z :b :z :c :z :d])```

Source clojure/core.clj:4540

```(fn interpose
[sep coll] (drop 1 (interleave (repeat sep) coll)))```

maximental's solution:

`#(butlast (interleave %2 (repeat %1)))`

psk810's solution:

`(fn [a s] (butlast (mapcat #(vector % a) s)))`

## 6. Last Element

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which returns the last element in a sequence.

```(= (__ [1 2 3 4 5]) 5)

(= (__ '(5 4 3)) 3)

(= (__ ["b" "c" "d"]) "d")```

Source clojure/core.clj:242

```(fn last [s]
(if (next s)
(recur (next s))
(first s)))```

maximental's solution:

`#(-> % reverse first)`

psk810's solution:

```(fn [lst] (first (take 1
(for [i (iterate #(rest %) lst) :when (= 1 (count i))] (first i)))))```

## 7. Nth Element

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which returns the Nth element from a sequence.

```(= (__ '(4 5 6 7) 2) 6)

(= (__ [:a :b :c] 0) :a)

(= (__ [1 2 3 4] 1) 2)

(= (__ '([1 2] [3 4] [5 6]) 2) [5 6])```

Source clojure/core.clj:824

```(defn nth
"Returns the value at the index. get returns nil if index out of
bounds, nth throws an exception unless not-found is supplied.  nth
also works for strings, Java arrays, regex Matchers and Lists, and,
in O(n) time, for sequences."
{:inline (fn  [c i & nf] `(. clojure.lang.RT (nth ~c ~i ~@nf)))
:inline-arities #{2 3}
([coll index] (. clojure.lang.RT (nth coll index)))
([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))```

solution 1:

`(fn nth-elem [s x] (last (take (inc x) s)))`

solution 2:

`#(first (drop %2 %1))`

## 8. Count a Sequence

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which returns the total number of elements in a sequence.

```(= (__ '(1 2 3 3 1)) 5)

(= (__ "Hello World") 11)

(= (__ [[1 2] [3 4] [5 6]]) 3)

(= (__ '(13)) 1)

(= (__ '(:a :b :c)) 3)```

Source clojure/core.clj:809

```(defn count
"Returns the number of items in the collection. (count nil) returns
0.  Also works on strings, arrays, and Java Collections and Maps"
{
:inline (fn  [x] `(. clojure.lang.RT (count ~x)))
[coll] (clojure.lang.RT/count coll))```

solution 1:

`#(reduce + (map (fn [x] 1) %))`

maximental's solution:

`reduce #(or (+ % 1) %2) 0`

psk810's solution:

```#(loop [lst % c 0]
(if (empty? lst)
c
(recur (rest lst) (inc c))))```

## 9. Reverse a Sequence

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which reverses a sequence.

```(= (__ [1 2 3 4 5]) [5 4 3 2 1])

(= (__ (sorted-set 5 7 2 7)) '(7 5 2))

(= (__ [[1 2][3 4][5 6]]) [[5 6][3 4][1 2]])```

Source clojure/contrib/generic/comparison.clj:200

```(fn reverse
[coll]
(reduce conj () coll))```

maximental's solution:

`into () `

psk810's solution:

`reduce #(cons %2 %1) []`

## 10. Split a sequence

문제

Difficulty: Easy Topics: seqs core-functions

Write a function which will split a sequence into two parts.

```(= (__ 3 [1 2 3 4 5 6]) [[1 2 3] [4 5 6]])

(= (__ 1 [:a :b :c :d]) [[:a] [:b :c :d]])

(= (__ 2 [[1 2] [3 4] [5 6]]) [[[1 2] [3 4]] [[5 6]]])```

Source clojure/core.clj:2564

```(fn split-at
[n coll]
[(take n coll) (drop n coll)])```

maximental's solution:

`(juxt take drop)`

psk810's solution:

`(fn [n col] (vector (take n col) (take-last (- (count col) n) col)))`

## 11. Re-implement Iterate

문제

Difficulty: Easy Topics: seqs core-functions

Given a side-effect free function f and an initial value x write a function which returns an infinite lazy sequence of x, (f x), (f (f x)), (f (f (f x))), etc.

```(= (take 5 (__ #(* 2 %) 1)) [1 2 4 8 16])

(= (take 100 (__ inc 0)) (take 100 (range)))

(= (take 9 (__ #(inc (mod % 3)) 1)) (take 9 (cycle [1 2 3])))```

Source clojure/core.clj:2592

```(fn iterate2
[f x] (cons x (lazy-seq (iterate2 f (f x)))))```

maximental's solution:

```(fn i [f x]
(lazy-seq
(cons x (i f (f x)))))```

psk810's solution:

`(fn my-iter [f x] (cons x (lazy-seq (my-iter f (f x)))))`

## 12. Group a sequence

문제

Difficulty: Easy Topics: core-functions

Given a function f and a sequence s, write a function which returns a map. The keys should be the values of f applied to each item in s. The value at each key should be a vector of corresponding items in the order they appear in s.

```(= (__ #(> % 5) [1 3 6 8]) {false [1 3], true [6 8]})

(= (__ #(apply / %) [[1 2] [2 4] [4 6] [3 6]])
{1/2 [[1 2] [2 4] [3 6]], 2/3 [[4 6]]})

(= (__ count [ [1 2]  [1 2 3] [2 3]])
{1 [ ], 2 [[1 2] [2 3]], 3 [[1 2 3]]})```

Source clojure/core.clj:6228

```(fn group-by1
[f coll]
(persistent!
(reduce
(fn [ret x]
(let [k (f x)]
(assoc! ret k (conj (get ret k []) x))))
(transient {}) coll)))```

maximental's solution:

```(fn [f c]
(reduce #(assoc %
(f %2)
(conj (get % (f %2) []) %2))
{}
c))```

psk810's solution:

```(fn [f col]
(reduce
#(let [m %1 v %2 k (f %2) lst (m k)]
(assoc m k (if lst (conj lst v) [v]))) {} col))
```

## 13. Count Occurrences

문제

Difficulty: Medium Topics: seqs core-functions

Write a function which returns a map containing the number of occurences of each distinct item in a sequence.

```(= (__ [1 1 2 3 2 1 1]) {1 4, 2 2, 3 1})

(= (__ [:b :a :b :a :b]) {:a 2, :b 3})

(= (__ '([1 2] [1 3] [1 3])) {[1 2] 1, [1 3] 2})
```

Source clojure/core.clj:6255

```(fn [coll]
(persistent!
(reduce (fn [counts x]
(assoc! counts x (inc (get counts x 0))))
(transient {}) coll)))```

maximental's solution:

```(comp (partial apply zipmap)
(juxt keys (comp (partial map count) vals))
(partial group-by identity))

;; reduce #(assoc % %2 (+ 1 (% %2 0))) {}```

psk810's solution:

```(fn [v]
(reduce
#(assoc % %2 (inc (if (% %2) (% %2) 0) )) {} v))
```

## 14. Find Distinct Items

문제

Difficulty: Medium Topics: seqs core-functions

Write a function which removes the duplicates from a sequence. Order of the items must be maintained.

```(= (__ [1 2 1 3 1 2 4]) [1 2 3 4])

(= (__ [:a :a :b :b :c :c]) [:a :b :c])

(= (__ '([2 4] [1 2] [1 3] [1 3])) '([2 4] [1 2] [1 3]))

(= (__ (range 50)) (range 50))```

Source clojure/core.clj:4413

```(fn distinct1
[coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[f :as xs] seen]
(when-let [s (seq xs)]
(if (contains? seen f)
(recur (rest s) seen)
(cons f (step (rest s) (conj seen f))))))
xs seen)))]
(step coll #{})))```

maximental's solution:

`reduce #({%2 %} ((set %) %2) (conj % %2)) []`

psk810's solution:

```(fn [v]
(reduce #(if (some #{%2} %) % (conj % %2)) [] v))
```

## 15. Partition a sequence

문제

Difficulty: Medium Topics: seqs core-functions

Write a function which returns a sequence of lists of x items each. Lists of less than x items should not be returned.

```(= (__ 3 (range 9)) '((0 1 2) (3 4 5) (6 7 8)))

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

(= (__ 3 (range 8)) '((0 1 2) (3 4 5)))```

Source clojure/core.clj:2765

```(fn partition1
([n coll]
(partition1 n n coll))
([n step coll]
(lazy-seq
(when-let [s (seq coll)]
(let [p (doall (take n s))]
(when (= n (count p))
(cons p (partition1 n step (nthrest s step))))))))
(lazy-seq
(when-let [s (seq coll)]
(let [p (doall (take n s))]
(if (= n (count p))
(cons p (partition1 n step pad (nthrest s step)))
(list (take n (concat p pad)))))))))```

maximental's solution:

```(fn p [n x]
(if (>= (count x) n)
(cons (take n x) (p n (drop n x)))))```

psk810's solution:

```(fn my-partition [n col]
(let [s (take n col)]
(if (= n (count s))
(cons s (my-partition n (drop n col))))))
```

## 16. Sequence Reductions

문제

Difficulty: Medium Topics: seqs core-functions

Write a function which behaves like reduce, but returns each intermediate value of the reduction. Your function must accept either two or three arguments, and the return sequence must be lazy.

```(= (take 5 (__ + (range))) [0 1 3 6 10])

(= (__ conj  [2 3 4]) [ [1 2] [1 2 3] [1 2 3 4]])

(= (last (__ * 2 [3 4 5])) (reduce * 2 [3 4 5]) 120)```

Source clojure/core.clj:6266

```(fn reductions1
([f coll]
(lazy-seq
(if-let [s (seq coll)]
(reductions1 f (first s) (rest s))
(list (f)))))
([f init coll]
(cons init
(lazy-seq
(when-let [s (seq coll)]
(reductions1 f (f init (first s)) (rest s)))))))```

maximental's solution:

```(fn g
([f [x & s]] (g f x s))
([f a [x & s]]
(lazy-seq
(cons a (if x (g f (f a x) s))))))```

## 17. Map Construction

문제 Difficulty: Easy Topics: core-functions

Write a function which takes a vector of keys and a vector of values and constructs a map from them.

```(= (__ [:a :b :c] [1 2 3]) {:a 1, :b 2, :c 3})

(= (__ [1 2 3 4] ["one" "two" "three"]) {1 "one", 2 "two", 3 "three"})

(= (__ [:foo :bar] ["foo" "bar" "baz"]) {:foo "foo", :bar "bar"})```

Source clojure/core.clj:2651

```(fn
[keys vals]
(loop [map {}
ks (seq keys)
vs (seq vals)]
(if (and ks vs)
(recur (assoc map (first ks) (first vs))
(next ks)
(next vs))
map)))```

maximental's solution:

`#(into {} (map vector % %2))`

psk810's solution:

`#(apply hash-map (interleave %1 %2))`

## 18. Function Composition

문제

Difficulty: Medium Topics: higher-order-functions core-functions

Write a function which allows you to create function compositions. The parameter list should take a variable number of functions, and create a function applies them from right-to-left.

```(= [3 2 1] ((__ rest reverse) [1 2 3 4]))

(= 5 ((__ (partial + 3) second) [1 2 3 4]))

(= true ((__ zero? #(mod % 8) +) 3 5 7 9))

(= "HELLO" ((__ #(.toUpperCase %) #(apply str %) take) 5 "hello world"))```

Source clojure/core.clj:2265

```(fn
([] identity)
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g h]
(fn
([] (f (g (h))))
([x] (f (g (h x))))
([x y] (f (g (h x y))))
([x y z] (f (g (h x y z))))
([x y z & args] (f (g (apply h x y z args))))))
([f1 f2 f3 & fs]
(let [fs (reverse (list* f1 f2 f3 fs))]
(fn [& args]
(loop [ret (apply (first fs) args) fs (next fs)]
(if fs
(recur ((first fs) ret) (next fs))
ret))))))```

maximental's solution:

```(fn [& s]
#(reduce (fn [c f] (f c))
(apply (last s) %&)
(rest (reverse s))))```

psk810's solution:

```(fn [& fs]
(fn [& args]
(reduce #(%2 %)
(apply (last fs) args) (rest (reverse fs)))))```

## 19. Juxtaposition

문제

Difficulty: Medium Topics: higher-order-functions core-functions

Take a set of functions and return a new function that takes a variable number of arguments and returns a sequence containing the result of applying each function left-to-right to the argument list.

```(= [21 6 1] ((__ + max min) 2 3 5 1 6 4))

(= ["HELLO" 5] ((__ #(.toUpperCase %) count) "hello"))

(= [2 6 4] ((__ :a :c :b) {:a 2, :b 4, :c 6, :d 8 :e 10}))```

Source clojure/core.clj:2296

```(fn juxt1
([f]
(fn
([] [(f)])
([x] [(f x)])
([x y] [(f x y)])
([x y z] [(f x y z)])
([x y z & args] [(apply f x y z args)])))
([f g]
(fn
([] [(f) (g)])
([x] [(f x) (g x)])
([x y] [(f x y) (g x y)])
([x y z] [(f x y z) (g x y z)])
([x y z & args] [(apply f x y z args) (apply g x y z args)])))
([f g h]
(fn
([] [(f) (g) (h)])
([x] [(f x) (g x) (h x)])
([x y] [(f x y) (g x y) (h x y)])
([x y z] [(f x y z) (g x y z) (h x y z)])
([x y z & args] [(apply f x y z args) (apply g x y z args) (apply h x y z args)])))
([f g h & fs]
(let [fs (list* f g h fs)]
(fn
([] (reduce #(conj %1 (%2)) [] fs))
([x] (reduce #(conj %1 (%2 x)) [] fs))
([x y] (reduce #(conj %1 (%2 x y)) [] fs))
([x y z] (reduce #(conj %1 (%2 x y z)) [] fs))
([x y z & args] (reduce #(conj %1 (apply %2 x y z args)) [] fs))))))```

maximental's solution:

```(fn [& f]
(fn [& x] (map #(apply % x) f)))```

## 20. Re-implement Map

문제 Difficulty: Easy Topics: core-seqs

Map is one of the core elements of a functional programming language. Given a function f and an input sequence s, return a lazy sequence of (f x) for each element x in s.

```(= [3 4 5 6 7]
(__ inc [2 3 4 5 6]))

(= (repeat 10 nil)
(__ (fn [_] nil) (range 10)))

(= [1000000 1000001]
(->> (__ inc (range))
(drop (dec 1000000))
(take 2)))```

Source clojure/core.clj:2414 (execution timeout)

```(fn map1
([f coll]
(lazy-seq
(when-let [s (seq coll)]
(if (chunked-seq? s)
(let [c (chunk-first s)
size (int (count c))
b (chunk-buffer size)]
(dotimes [i size]
(chunk-append b (f (.nth c i))))
(chunk-cons (chunk b) (map1 f (chunk-rest s))))
(cons (f (first s)) (map1 f (rest s)))))))
([f c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
(when (and s1 s2)
(cons (f (first s1) (first s2))
(map1 f (rest s1) (rest s2)))))))
([f c1 c2 c3]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2) s3 (seq c3)]
(when (and  s1 s2 s3)
(cons (f (first s1) (first s2) (first s3))
(map1 f (rest s1) (rest s2) (rest s3)))))))
([f c1 c2 c3 & colls]
(let [step (fn step [cs]
(lazy-seq
(let [ss (map1 seq cs)]
(when (every? identity ss)
(cons (map1 first ss) (step (map1 rest ss)))))))]
(map1 #(apply f %) (step (conj colls c3 c2 c1))))))``` 