Skip to content

Instantly share code, notes, and snippets.

@pjullah
Created May 23, 2017 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjullah/784df58de1cddb9ed699fb233df8d7d5 to your computer and use it in GitHub Desktop.
Save pjullah/784df58de1cddb9ed699fb233df8d7d5 to your computer and use it in GitHub Desktop.
The Little Schemer
(ns the-little-schema.core)
;;; Chapter 3 - Cons the magnificent
;; 1. Always ask null? as the first question in expressing any function
;; 2. Use cons to build lists
;; 3. When building a list, describe the first typical
;; element, and then cons in onto the natural recursion
(defn rember [n col]
(cond
(empty? col) (quote ())
:else (cond
(= (first col) n) (rest col)
:else (cons (first col)
(rember n
(rest col))))))
(rember "a" '("a" "a" "b"))
(rember "I" '("I" "I" "have" "a" "stutter"))
(def a 1)
(cond
(= a 2) (println "Maths is broken")
(= a 3) (println "Maths is broken")
:else "Everything is ok")
;;The function rember checked each atom of
;;the col, one at a time, to see if it was the
;;same as the atom n. If the car was not
;;the same as the atom, we saved it to be
;;consed to the final value later. When
;;rember found the atom n, it dropped it,
;;and consed the previous atoms back onto the
;;rest of the col.
(defn rember2 [n col]
(cond
(empty? col) (quote ())
(= (first col) n) (rest col)
:else (cons (first col)
(rember n
(rest col)))))
(rember2 "a" '("a" "a" "b"))
(defn firsts [col]
(cond
(empty? col) ()
:else (cons (first (first col)) (firsts (rest col)))))
(firsts '(:a :b :c))
(firsts '((list :a) (list :b) '(:c)))
(defn insert-after [new old coll]
(cond
(empty? coll) ()
(= (first coll) old) (cons old (cons new (rest coll)))
:else (cons (first coll)
(insert-after new old (rest coll)))))
(insert-after "pie" "Pigeon" '("Pigeon" "for" "dinner"))
(defn insert-before [new old coll]
(cond
(empty? coll) ()
(= (first coll) old) (cons new (cons old (rest coll)))
:else (cons (first coll)
(insert-before new old (rest coll)))))
(insert-before "pie" "Pigeon" '("Pigeon" "for" "dinner"))
(def new "b")
(def old "a")
(def coll '("a" "c" "d"))
(cons new coll)
(defn subst [new old coll]
(cond
(empty? coll) ()
(= (first coll) old) (cons new (rest coll))
:else (cons (first coll)
(subst new old (rest coll)))))
(subst "2" "1" '("I'd" "like" "1" "apples"))
(defn subst2 [new o1 o2 coll]
(cond
(empty? coll) ()
(= (first coll) o1) (cons new (rest coll))
(= (first coll) o2) (cons new (rest coll))
:else (cons (first coll)
(subst new o1 o2 (rest coll)))))
(subst2 "vanilla" "chocolate" "banana" '("banana" "ice" "cream" "with" "chocolate" "topping"))
(defn multirember [a coll]
(cond
(empty? coll) ()
:else
(cond
(= (first coll) a) (multirember a (rest coll))
:else (cons (first coll) (multirember a (rest coll))))))
(multirember "a" '("I" "like" "a" "nice" "bath" "and" "a" "coffee"))
; write filter in terms of first and rest
; write partial
; write +
; write sum
(clojure.core/+ 1 2)
(defn sub1 [a]
(cond
(zero? a) 0
:else (dec a)))
(sub1 10)
(defn add1 [a]
(inc a))
(defn + [a b]
(cond
(= b 0) a
:else (+ (add1 a) (sub1 b))))
(+ 1 14) ;15
(def tup '(1 2 3 4 5)) ;15
(defn addtup [t]
(cond
(empty? t) 0
:else
(+ (first t) (addtup (rest t)))))
(addtup tup) ;15
(defn * [a b]
(cond
(zero? a) 0
:else (+ b (* (dec a) b))))
(* 4 5) ;20
(defn tup+ [coll1 coll2]
(cond
(and (empty? coll1) (empty? coll2)) ()
:else (cons (+ (first coll1) (first coll2))
(tup+ (rest coll1) (rest coll2)))))
(tup+ '(1 2 3) '(4 5 6)) ;(5 7 9)
(tup+ '(1 2) '(4 5 6)) ;NullPointerException
(defn tup++ [coll1 coll2]
(cond
(empty? coll1) coll2
(empty? coll2) coll1
:else (cons (+ (first coll1) (first coll2))
(tup++ (rest coll1) (rest coll2)))))
(tup++ '(1 2) '(4 5 6)) ;(5 7 6)
; true when a > b
; false when a < b
; 120 > 12 #t
; 12 > 120 #f
(defn > [a b]
(cond
(= a b) false
(and (zero? a) (not (zero? b))) false
(and (zero? b) (not (zero? a))) true
:else (> (sub1 a) (sub1 b))))
(> 12 120) ;#f
(> 120 12) ;#t
(> 12 12) ;#f
(defn >> [a b]
(cond
(zero? a) false
(zero? b) true
:else (>> (sub1 a) (sub1 b))))
(>> 12 120) ;#f
(>> 120 12) ;#t
(>> 2 2) ;#f
(defn < [a b]
(cond
(zero? b) false
(zero? a) true
:else (< (sub1 a) (sub1 b))))
(< 12 120) ;#t
(< 120 12) ;#f
(< 2 2) ;#f
(defn == [a b]
(cond
(> a b) false
(< a b) false
:else true))
(== 3 3)
(== 5 3)
(== 3 5)
(defn pow [base exp]
(cond
(zero? exp) 1
:else (* base (pow base (sub1 exp)))))
(pow 1 1)
(pow 2 3)
(pow 5 3)
; determine the length
; of coll
(defn length [coll]
(cond
(empty? coll) 0
:else (+ (length (rest coll)) 1 )))
(length '(1 2 3 :a :b)) ;5
; pick the nth item
; from coll
(defn pick [n coll]
(cond
(zero? (sub1 n)) (first coll)
:else (pick (sub1 n) (rest coll))))
(pick 4 '(lasagne spaghetti ravioli macaroni meatball)) ;macaroni
(pick 3 '(spaghetti ravioli macaroni meatball)) ;macaroni
(pick 2 '(ravioli macaroni meatball)) ;macaroni
(pick 1 '(macaroni meatball)) ;macaroni
(defn rempick [n lat]
(cond
(zero? (sub1 n)) (rest lat)
:else (cons (first lat) (rempick (sub1 n) (rest lat)))))
(rempick 3 '(hotdogs with hot mustard)) ; (hotdogs with mustard)
(defn no-nums [lat]
(cond
(empty? lat) ()
:else (cond
(number? (first lat)) (no-nums (rest lat))
:else (cons (first lat) (no-nums (rest lat))))))
(no-nums '(:a 1 "apple" 2))
(defn all-nums [lat]
(cond
(empty? lat) ()
:else (cond
(number? (first lat)) (cons (first lat) (all-nums (rest lat)))
:else (all-nums (rest lat)))))
(all-nums '(:a 1 "apple" 2))
(defn one? [n]
(cond
(= 0 n) false
(= (sub1 n) 0) true
:else false))
(defn one? [n]
(= n 1))
(one? 1)
(one? 2)
(one? 0)
(defn tmp2 [col n]
(->> col
(map #(vector (inc %1) %2)(range))
(filter #(not (zero? (mod (first %) n))))
(map second)))
(map #(vector (inc %1) %2) (range) [:a :b :c :d :e :f])
(filter #((zero? (first %))) (list [1 :a] [2 :b] [3 :c] [4 :d] [5 :e] [6 :f]))
(tmp2 [:a :b :c :d :e :f] 2)
(= (tmp2 [:a :b :c :d :e :f] 2) [:a :c :e])
(apply + (map #(if % 1 0) [false false]))
(count [false false])
(defn some-true [& col]
(let [c (apply + (map #(if % 1 0) col))
len (count col)]
(cond
(= 0 c) false
(= c len) false
:else true)))
(= false (some-true false false))
(= true (some-true false true false))
(= (
(fn [a b]
(into {}
(map #(vector %1 %2) a b)
)
)
[:a :b :c] ;a
[1 2 3] ;b
)
{:a 1, :b 2, :c 3}
)
(map #(cond (zero? %) 0 (not (even %)) (map #(vector (inc %1) %2) (range) (reverse (map #(Character/digit % 10) (seq "0001")))))
(ns the-little-schema.chapter4)
;; chapter 4 - numbers games
(defn add1 [n]
(cond
(>= n 0) (+ n 1)
(< n 0) 0))
(add1 5)
(add1 -5)
(defn sub1 [n]
(cond
(> n 0) (- n 1)
(<= n 0) 0))
(sub1 0)
(sub1 1)
(sub1 2)
(defn plus [m n]
(cond
(zero? n) m
(> n 0) (plus (add1 m) (sub1 n))))
(plus 46 12)
(defn minus [m n]
(cond
(< m n) 0
(zero? n) m
(> n 0) (minus (sub1 m) (sub1 n))))
(minus 7 1)
(minus 25 18)
(minus 18 25)
(defn addtup [tup]
(cond
(not (list? tup)) 0
(empty? tup) 0
:else (plus (first tup) (addtup (rest tup)))))
(addtup (list 1 2 3 4 5))
(defn multiply [m n]
(cond
(zero? m) 0
:else (plus n (multiply n (sub1 m)))))
(plus 6 (multiply 6 (sub1 5)))
(plus 6 (multiply 6 (sub1 4)))
(plus 6 (multiply 6 (sub1 3)))
(plus 6 (multiply 6 (sub1 2)))
(plus 6 (multiply 6 (sub1 1)))
(plus 6 (multiply 6 (sub1 0)))
(multiply 5 6)
(defn tup+ [tup1 tup2]
(cond
; (and (empty? tup1) (empty? tup2)) (list)
(empty? tup1) tup2
(empty? tup2) tup1
:else (cons (plus (first tup1) (first tup2)) (tup+ (rest tup1) (rest tup2)))))
(tup+ (list 2 3) (list 4 6))
(tup+ (list 3 7) (list 4 6))
(tup+ (list 2 3 1 2) (list 4 6))
(tup+ (list 2 3 ) (list 4 6 7 8))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment