Skip to content

Instantly share code, notes, and snippets.

@kmxz
Last active August 29, 2015 14:22
Show Gist options
  • Save kmxz/771cfb9d21626e403898 to your computer and use it in GitHub Desktop.
Save kmxz/771cfb9d21626e403898 to your computer and use it in GitHub Desktop.
99 Problems in Clojure
; P01 - general version for lists and vectors
(defn p01 [l]
(let [n (next l)]
(if (nil? n) (first l) (recur n))
)
)
; P01 - use destructing assignment, works for lists and vectors
(defn p01' [l]
(let [[head & rest] l]
(if (nil? rest) head (recur rest))
)
)
; P01 - version works only for vectors
(defn p01'' [l]
(get l (- (count l) 1))
)
; P02 - modified from p01'; works for lists; slightly modification needed to work with vectors
(defn p02 [l]
(let [[first second & rest] l]
(if (nil? rest) (into (empty l) [second first]) (recur (next l)))
)
)
; P03 - general version for lists and vectors
(defn p03 [l n]
(if (= n 1) (first l) (recur (next l) (- n 1)))
)
; P03 - version works only for vectors
(def p03' #(% (- %2 1)))
; P04 - recursive version, for lists and vectors
(defn p04 [l]
(if (nil? l) 0 (+ 1 (p04 (next l))))
)
; P04 - tail recursive version, for lists and vectors
(defn p04'
([l n] (if (nil? l) n (recur (next l) (inc n))))
([l] (p04 l 0))
)
; P04 - built-in version
(def p04'' count)
; P05 - tail recursive lisp-style, for lists and vectors, though it will reverses a vector to a list
(defn p05
([l acc] (if (nil? l)
acc
(recur (next l) (cons (first l) acc))
))
([l] (p05 l nil))
)
; P05 - built-in version, it will also reverses a vector to a list
(def p05' reverse)
; P06 - simple version using P05: only works for lists
(def p06 #(= % (reverse %)))
; P07 - based on P05; only works for lists
(defn p07
([l acc] (if (nil? l)
acc
(if (list? l)
(recur (next l) (p07 (first l) acc))
(cons l acc)
)
))
([l] (reverse (p07 l nil)))
)
(def p07' flatten)
; P08 - based on P05; only works for lists
(defn p08
([l acc] (if (nil? l)
acc
(recur (next l)
(if (= (first l) (first acc))
acc
(cons (first l) acc)
)
)
))
([l] (reverse (p08 l nil)))
)
; P09 - based on P05; only works for lists
(defn p09
([l acc] (if (nil? l)
acc
(recur (next l)
(if (= (first l) (first (first acc)))
(cons (cons (first l) (first acc)) (next acc))
(cons (list (first l)) acc)
)
)
))
([l] (reverse (p09 l nil)))
)
; P10 - using built-in map and count function
(defn p10 [l]
(map #(list (count %) (first %)) (p09 l))
)
; P11 - slightly modified from P10
(defn p11
([l acc]
(if (nil? l)
acc
(recur (next l)
(let [facc (first acc)]
(if (= (first l) (first (next facc)))
(cons (cons (inc (first facc)) (next facc)) (next acc))
(cons (list 1 (first l)) acc)
)
)
)
)
)
([l]
((fn [l acc] (if (nil? l) acc (recur (next l) (cons (let [fl (first l)] (if (= (first fl) 1) (first (next fl)) fl)) acc))))
(p11 l nil)
nil
)
)
)
; P12 - using reverse again
(defn p12
([l acc]
(let [group (fn
[content count acc]
(if (= count 0)
acc
(recur content (- count 1) (cons content acc))
))]
(if (nil? l)
acc
(let [fl (first l)]
(recur (next l)
(if (list? fl)
(group (first (next fl)) (first fl) acc)
(cons fl acc)
)
)
)
)
)
)
([l] (reverse (p12 l nil)))
)
; P12 - using the built-in flatten and map functions
(defn p12'
[l]
(flatten (map (fn [item]
(if (list? item) (repeat (first item) (first (next item))) item)
) l))
)
; P13 - slightly modified from P09; only works for lists
(defn p13
([l acc] (if (nil? l)
acc
(recur (next l)
(let [facc (first acc)]
(if (= (first l) (first (next facc)))
(cons (cons (inc (first facc)) (next facc)) (next acc))
(cons (list 1 (first l)) acc)
)
)
)
))
([l] (reverse (p13 l nil)))
)
; P14 - recursive version
(defn p14 [l]
(if (nil? l) nil (cons (first l) (cons (first l) (p14 (next l)))))
)
; P14 - tail recursive version using reverse
(defn p14'
([l acc] (if (nil? l)
acc
(recur (next l) (cons (first l) (cons (first l) acc)))
))
([l] (reverse (p14' l nil)))
)
; P14 - using the built-in flatten and map functions
(defn p14'' [l]
(flatten (map #(list % %) l))
)
; P15 - modifying P14 for a bit
(defn p15 [l t]
(let [append (fn repeated [content remaining source] (if (= remaining 0) source (cons content (repeated content (- remaining 1) source))))]
(if (nil? l) nil (append (first l) t (p15 (next l) t)))
)
)
; P15 - using built-in functions
(defn p15' [l t]
(flatten (map #(repeat 3 %) l))
)
; P16 - recursive version
(defn p16
([l n t]
(if (nil? l) nil
(let [remaining (p16 (next l) n (inc t))]
(if (= 0 (mod t n)) remaining (cons (first l) remaining))
)
)
)
([l n] (p16 l n 1))
)
; P17 - recursive version using no predefined predicatess
(defn p17 [l n]
(if (= n 0)
(list nil l)
(let [tp (p17 (next l) (- n 1))]
(cons
(cons (first l) (first tp))
(next tp)
)
)
)
)
; P18 - using P17
(defn p18 [l s e]
(first (p17 (first (next (p17 l (- s 1)))) (- e (- s 1))))
)
; P19 - using P17 and build-n flatten
(defn p19 [l r]
(let [n (mod r (count l))]
(let [parts (p17 l n)]
(if (= n 0) l (flatten (list (first (next parts)) (first parts))))
)
)
)
; P20 - recursive version, stripped from P16
(defn p20 [l n]
(if (nil? l) nil
(let [remaining (p20 (next l) (- n 1))]
(if (= 1 n) remaining (cons (first l) remaining))
)
)
)
; P21 - recursive version, modified from p20
(defn p21 [i l n]
(if (= 1 n) (cons i l)
(if (nil? l) nil
(cons (first l) (p21 i (next l) (- n 1)))
)
)
)
; P22 - tail recursive version
(defn p22
([s e acc]
(if (< e s) acc
(recur s (- e 1) (cons e acc))
)
)
([s e] (p22 s e nil))
)
; P22 - built-in version
(def p22' #(range % (inc %2)))
; P23 - using P20
(defn p23 [l r]
(let [cl (count l)]
(if (= r cl) l
(recur (p20 l (rand-int cl)) r)
)
)
)
; P24 - using P22 and P23
(def p24 #(p23 (p22 1 %2) %))
; P25 - using P03 and P20
(defn p25
([l acc]
(if (nil? l) acc
(let [tk (inc (rand-int (count l)))]
(recur (p20 l tk) (cons (p03 l tk) acc))
)
)
)
([l] (p25 l nil))
)
; P26 - naive brute force algorithm
(defn p26
[n l]
(let [aux (fn self [curr rem acc]
(if (= (count curr) n) (cons (reverse curr) acc)
(if (nil? rem) acc
(recur (cons (first rem) curr) (next rem) (self curr (next rem) acc))
)
))]
(aux nil l nil)
)
)
; P31 - get a list using sieve first
(defn p31 [t]
(let [test (fn [start coll] (every? #(not= 0 (mod start %)) coll))]
(test t ((fn [start acc target]
(if (> start target)
acc
(recur
(inc start)
(if (test start acc)
(cons start acc)
acc
)
target
)
)
) 2 nil (Math/sqrt t)))
)
)
; P32 - tail recursive
(defn p32 [a b]
(let [m (mod a b)]
(if (= m 0) b
(recur b m)
)
)
)
; P33 - using P32 and composition
(def p33 (comp (partial = 1) p32))
; P34 ,- brute force using P33
(defn p34
([n c acc]
(if (> c n) acc
(recur n (inc c) (if (p33 c n) (inc acc) acc))
)
)
([n] (p34 n 1 0))
)
; P35 - modified from P31
(defn p35 [num]
(let [prime-list
((fn [start acc target]
(if (> start target)
acc
(recur
(inc start)
(if (every? #(not= 0 (mod start %)) acc)
(cons start acc)
acc
)
target
)
)
) 2 nil (Math/sqrt num))
find-factor
(fn [factor-list to-find acc]
(if (nil? factor-list)
(reverse (cons to-find (reverse acc)))
(if (= to-find 1)
acc
(let [h (first factor-list)]
(if (= 0 (mod to-find h))
(recur factor-list (/ to-find h) (cons h acc))
(recur (next factor-list) to-find acc)
)
)
)
)
)]
(find-factor prime-list num nil)
)
)
; P36 - composed from P13 and P35
(def p36 (comp (partial map reverse) p13 p35))
; P37 - using P36
(def p37
(comp
(partial reduce +)
(partial map (fn [group]
(let [p (first group) m (first (next group))]
(* (- p 1)
(Math/pow p (- m 1))
)
)
))
p36
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment