User Tools

Site Tools


lecture:4clojure:core_function_4clojure_problem

Core function 4Clojure problem

1. Maximum Value

문제 위치 : http://www.4clojure.com/problem/38

문제

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

문제 위치 : http://www.4clojure.com/problem/34

문제

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

문제 위치 : http://www.4clojure.com/problem/28

문제

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

문제 위치 : http://www.4clojure.com/problem/39

문제

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] [5]) [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

문제 위치 : http://www.4clojure.com/problem/40

문제

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

문제 위치 : http://www.4clojure.com/problem/19

문제

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

문제 위치 : http://www.4clojure.com/problem/21

문제

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}
   :added "1.0"}
  ([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

문제 위치 : http://www.4clojure.com/problem/22

문제

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)))
   :added "1.0"}
  [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

문제 위치 : http://www.4clojure.com/problem/23

문제

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

문제 위치 : http://www.4clojure.com/problem/49

문제

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

문제 위치 : http://www.4clojure.com/problem/62

문제

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

문제 위치 : http://www.4clojure.com/problem/63

문제

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] [1 2] [3] [1 2 3] [2 3]])
   {1 [[1] [3]], 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

문제 위치 : http://www.4clojure.com/problem/55

문제

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

문제 위치 : http://www.4clojure.com/problem/56

문제

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

문제 위치 : http://www.4clojure.com/problem/54

문제

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))))))))
  ([n step pad coll]
     (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

문제 위치 : http://www.4clojure.com/problem/60

문제

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 [1] [2 3 4]) [[1] [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

문제 위치 : http://www.4clojure.com/problem/61

문제 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

문제 위치 : http://www.4clojure.com/problem/58

문제

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

문제 위치 : http://www.4clojure.com/problem/59

문제

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

문제 위치 : http://www.4clojure.com/problem/118

문제 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))))))
lecture/4clojure/core_function_4clojure_problem.txt · Last modified: 2019/02/04 14:26 (external edit)