Famous "99 problems", referring to https://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html, written in Clojure.
As an exercise when I read the book Clojure Programming (Emerick).
| ; 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 | |
| ) | |
| ) |
Famous "99 problems", referring to https://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html, written in Clojure.
As an exercise when I read the book Clojure Programming (Emerick).