mail-alt git-squared

~/abhirag

My 4Clojure Solutions(1 to 50)

All the code snippets below are live and interactive. You can modify the code and it will be evaluated in your browser as you type.

(ns solutions-uno
  (:require [cljs.core.match :refer-macros [match]]))

1. Nothing but the Truth

(= true true)

2. Simple Math

(= (- 10 (* 2 3)) 4)

3. Intro to Strings

(= "HELLO WORLD" (.toUpperCase "hello world"))

4. Intro to Lists

(= (list :a :b :c) '(:a :b :c))

5. Lists: conj

(= '(1 2 3 4) (conj '(2 3 4) 1))
(= '(1 2 3 4) (conj '(3 4) 2 1))

6. Intro to Vectors

(= [:a :b :c] (list :a :b :c) (vec '(:a :b :c)) (vector :a :b :c))

7. Vectors: conj

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

8. Intro to Sets

(= #{:a :b :c :d} (set '(:a :a :b :c :c :c :c :d :d)))
(= #{:a :b :c :d} (clojure.set/union #{:a :b :c} #{:b :c :d}))

9. Sets: conj

(= #{1 2 3 4} (conj #{1 4 3} 2))

10. Intro to Maps

(= 20 ((hash-map :a 10, :b 20, :c 30) :b))
(= 20 (:b {:a 10, :b 20, :c 30}))

11. Maps: conj

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

12. Intro to Sequences

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

13. Sequences: rest

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

14. Intro to Functions

(= 8 ((fn add-five [x] (+ x 5)) 3))
(= 8 ((fn [x] (+ x 5)) 3))
(= 8 (#(+ % 5) 3))
(= 8 ((partial + 5) 3))

15. Double Down

(defn double-down [x] 
  (* x 2))

  (= (double-down 3) 6)

16. Hello World

(= (#(str "Hello, " % "!") "Dave")
   "Hello, Dave!")

17. Sequences: map

(= '(6 7 8) (map #(+ % 5) '(1 2 3)))

18. Sequences: filter

(= '(6 7) (filter #(> % 5) '(3 4 5 6 7)))

19. Last Element

(= (-> [1 2 3 4 5]
       reverse
       first) 5)
     
(defn last-elem [[head & tail]]
  (if (seq tail) 
    (recur tail)
    head))
    
    (= (last-elem [1 2 3 4 5]) 5)

20. Penultimate Element

(= (-> '(1 2 3 4 5) 
       reverse 
       rest 
       first) 4)
(defmulti penultimate
          (fn [input]
            (= (count input) 1)))

(defmethod penultimate true [input] nil)

(defmethod penultimate false [[head after_head & tail :as input]]
  (if (seq tail)
    (recur (rest input))
    head))

    (println (= (penultimate '(1 2 3 4 5)) 4))
    (println (= (penultimate '(1)) nil))
    (println (= (penultimate '()) nil))

21. Nth Element

(defn my-nth [input_seq n]
  {:pre [(>= n 0)]}
  (loop [counter 0
         input input_seq]
    (if (= counter n)
      (first input)
      (recur (inc counter) (rest input)))))

      (println (= (my-nth '(4 5 6 7) 2) 6))
      (my-nth '(4 5 6 7) -1)
(= (#(->> %1
      (drop %2)
      first) '(4 5 6 7) 2) 6)

22. Count a Sequence

(defn my-count [input_seq]
  (apply +
         (for [elem input_seq] 1)))

         (println (= (my-count '(1 2 3 3 1)) 5))
         (println (= (my-count "Hello World") 11))

23. Reverse a Sequence

(= (#(into '() %) [1 2 3 4 5]) 
   [5 4 3 2 1])

24. Sum It All Up

(= (#(apply + %) [1 2 3]) 6)

25. Find the odd numbers

(= (#(filter odd? %) [4 2 1 6]) '(1))

26. Fibonacci Sequence

(defn fib [n]
  (->> (iterate (fn [[a b]] [b (+ a b)]) [1 1]) 
       (map first)
       (take n)))

       (= (fib 8) '(1 1 2 3 5 8 13 21))

27. Palindrome Detector

(defn palindrome? [[head & tail :as input_seq]] 
  (cond
    (= (count input_seq) 1) true
    (empty? input_seq) true
    :else (and (= head (last tail)) (recur (butlast tail)))))
    
    (true? (palindrome? "racecar"))

28. Flatten a Sequence

(defn- my-flatten-helper [[head & tail :as input_seq] result]
  (cond 
    (empty? input_seq) result
    (sequential? head) (recur tail (concat (my-flatten-helper head '()) result))
    :else (recur tail (conj result head))))

    (defn my-flatten [input-seq]
  (reverse (my-flatten-helper input-seq '())))
  
  (println (= (my-flatten '((1 2) 3 [4 [5 6]])) '(1 2 3 4 5 6)))
  (println (= (my-flatten ["a" ["b"] "c"]) '("a" "b" "c")))
  (println (= (my-flatten '((((:a))))) '(:a)))

29. Get the Caps

(defn is-upper? [input_char]
  (contains?
    (set "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    input_char))

    (defn get-caps [input_string]
  (apply str (filter is-upper? input_string)))

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

30. Compress a Sequence

(defn compress [input_seq]
  (loop [[head & tail :as input] input_seq
         result '()]
    (cond
      (empty? input) (reverse result)
      (= head (first result)) (recur tail result)
      :else (recur tail (cons head result)))))

      (= (apply str (compress "Leeeeeerrroyyy")) "Leroy")

31. Pack a Sequence

(defn pack [input_seq]
  (loop [[head & tail :as input] input_seq
         [result_head & result_tail :as result] '()]
    (cond
      (empty? input) (reverse result)
      (= head (first result_head)) (recur tail (cons (cons head result_head) result_tail))
      :else (recur tail (cons (list head) result)))))

      (= (pack [1 1 2 1 1 1 3 3]) '((1 1) (2) (1 1 1) (3 3)))

32. Duplicate a Sequence

(defn duplicate [input_seq]
  (loop [[head & tail :as input] input_seq
         result '()]
    (if (empty? input) 
      (reverse result)
      (recur tail (conj result head head)))))

      (= (duplicate [1 2 3]) '(1 1 2 2 3 3))

33. Replicate a Sequence

(defn replicate [input_seq n]
  (loop [[head & tail :as input] input_seq
         result '()]
    (if (empty? input)
      (reverse result)
      (recur tail (concat (repeat n head) result)))))
      
      (= (replicate [1 2 3] 2) '(1 1 2 2 3 3))

34. Implement range

(defn my-range [start end]
  (loop [counter start
         result '()]
    (if (= counter end) 
      (reverse result)
      (recur (inc counter) (conj result counter)))))
      
      (= (my-range 1 4) '(1 2 3))

35. Local bindings

(= 7 (let [x 5] (+ 2 x)))
    (= 7 (let [x 3, y 10] (- y x)))
    (= 7 (let [x 21] (let [y 3] (/ x y))))

36. Let it Be

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

37. Regular Expressions

(= "ABC" (apply str (re-seq #"[A-Z]+" "bA1B3Ce ")))

38. Maximum value

(defn my-max [& args]
  (loop [[head & tail :as input] args
         result head]
    (cond 
      (empty? input) result
      (> head result) (recur tail head)
      :else (recur tail result))))

      (= (my-max 45 67 11) 67)

39. Interleave Two Seqs

(defn my-interleave [seq1 seq2]
  (loop [[head1 & tail1 :as s1] seq1
         [head2 & tail2 :as s2] seq2
         result '()]
    (cond 
      (or (empty? s1) (empty? s2)) (reverse result)
      :else (recur tail1 tail2 (conj result head1 head2)))))
      
      (= (my-interleave [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))

40. Interpose a Seq

(defn my-interpose [elem input_seq]
  (loop [[head & tail :as input] input_seq
         result '()]
    (if (empty? input)
      (butlast (reverse result))
      (recur tail (conj result head elem)))))

      (= (my-interpose :z [:a :b :c :d]) [:a :z :b :z :c :z :d])

41. Drop Every Nth Item

(defn drop-nth [input_seq n]
  (loop [[head & tail :as input] input_seq
         counter 1
         result '()]
    (cond 
      (empty? input) (reverse result)
      (= counter n) (recur tail 1 result)
      :else (recur tail (inc counter) (conj result head)))))
      
      (= (drop-nth [1 2 3 4 5 6] 4) [1 2 3 5 6])

42. Factorial Fun

(def factorial (memoize (fn [n]
                          {:pre [(>= n 0)]}
                          (condp = n
                            0 1
                            (* n (factorial (dec n)))))))

                            (= (factorial 8) 40320)

43. Reverse Interleave

(defn reverse-interleave [input_seq n]
  (loop [input input_seq
         result (vec (repeat n []))
         counter 0]
    (match [input counter]
           [([] :seq) _]                  result
           [_ n]                          (recur input result 0)
           [([head & tail] :seq) counter] (recur tail
                                                 (update-in result [counter] #(conj % head))
                                                 (inc counter)))))

(println (= (reverse-interleave [1 2 3 4 5 6] 2) '((1 3 5) (2 4 6))))
(println (= (reverse-interleave (range 9) 3) '((0 3 6) (1 4 7) (2 5 8))))
(println (= (reverse-interleave (range 10) 5) '((0 5) (1 6) (2 7) (3 8) (4 9))))

44. Rotate Sequence

(defn- rotate-left [n input_seq]
  {:pre [(>= n 0)]}
  (loop [result input_seq
         counter (mod n (count input_seq))]
    (let [head (first result)
          tail (vec (rest result))]
      (if (= counter 0)
        result
        (recur (conj tail head) (dec counter))))))

(defn- rotate-right [n input_seq]
  {:pre [(>= n 0)]}
  (->> input_seq
       (reverse)
       (rotate-left n)
       (reverse)))

(defn rotate [n input_seq]
  (cond
    (= n 0) input_seq
    (> n 0) (rotate-left n input_seq)
    (< n 0) (rotate-right (* -1 n) input_seq)))
    
(println (= (rotate 2 [1 2 3 4 5]) '(3 4 5 1 2)))
(println (= (rotate -2 [1 2 3 4 5]) '(4 5 1 2 3)))
(println (= (rotate 6 [1 2 3 4 5]) '(2 3 4 5 1)))
(println (= (rotate 1 '(:a :b :c)) '(:b :c :a)))
(println (= (rotate -4 '(:a :b :c)) '(:c :a :b)))

45. Intro to Iterate

(= [1 4 7 10 13] (take 5 (iterate #(+ 3 %) 1)))

46. Flipping out

(defn flip [f]
  (fn [& args]
    (apply f (reverse args))))

(= [1 2 3] ((flip take) [1 2 3 4 5] 3))

47. Contain Yourself

(println (contains? #{4 5 6} 4))
(println (contains? [1 1 1 1 1] 4))
(println (contains? {4 :a 2 :b} 4))
(println (not (contains? [1 2 4] 4)))

48. Intro to some

(println (= 6 (some #{2 7 6} [5 6 7 8])))
(println (= 6 (some #(when (even? %) %) [5 6 7 8])))

49. Split a sequence

(defn my-split [n input_seq]
  [(subvec input_seq 0 n) (subvec input_seq n)])

(println (= (my-split 3 [1 2 3 4 5 6]) [[1 2 3] [4 5 6]]))
(println (= (my-split 1 [:a :b :c :d]) [[:a] [:b :c :d]]))
(println (= (my-split 2 [[1 2] [3 4] [5 6]]) [[[1 2] [3 4]] [[5 6]]]))

50. Split by Type

(defn- split-by-type-helper [t input_seq]
  (filterv #(instance? t %) input_seq))

(defn split-by-type [input_seq]
  (let [types (set (map type input_seq))]
    (set (for [t types]
       (split-by-type-helper t input_seq)))))