Created
May 23, 2017 13:57
-
-
Save pjullah/784df58de1cddb9ed699fb233df8d7d5 to your computer and use it in GitHub Desktop.
The Little Schemer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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"))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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