Created
April 1, 2015 13:47
-
-
Save xuchunyang/7fd6ebf0ad0c47ed8795 to your computer and use it in GitHub Desktop.
elisp-pcase-note.el
This file contains hidden or 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
;;; elisp-pcase-note.el --- Learning Notes for Pattern Matching implemented in Emacs Lisp | |
;; URL: http://www.emacswiki.org/emacs/PatternMatching | |
;; Created: Wed Apr 1 20:57:16 CST 2015 | |
;;; Find the reciprocal of a number | |
(defun recip (n) | |
(pcase n | |
(`0 (error "Can't divide by zero")) | |
(n (/ 1.0 n)))) | |
;;; Find the absoulte value of a number | |
(defun abs2 (x) | |
(pcase x | |
((pred (< 0)) x) | |
((pred (= 0)) 0) | |
((pred (> 0)) (- x)))) | |
;;; Find the head (`car') of a list | |
(defun car2 (list) | |
(pcase list | |
(`(,l . ,ll) l))) | |
(car2 '(1 2 3)) ;=> 1 | |
;;; Find the tail (`cdr') of a list | |
(defun cdr2 (list) | |
(pcase list | |
(`(,l . ,ll) ll))) | |
(cdr2 '(1 2 3)) ;=> (2 3) | |
;;; Find the 2th element of a list | |
(defun 2nd (list) | |
(pcase list | |
(`(,l ,l2 . ,_) l2))) | |
(2nd '(1 2 3)) ;=> 2 | |
;;; Find the 3rd element of a list | |
(defun 3rd (list) | |
(pcase list | |
(`(,l ,l2 ,l3 . ,_) l3))) | |
(3rd '(1 2 3 4)) ;=> 3 | |
;;; Find the last element of a list | |
(defun thelast (list) | |
(pcase list | |
(`(,l . nil) l) | |
(_ (thelast (cdr list))))) | |
(thelast '(1 2 3)) ;=> 3 | |
;;; sum(1, n) | |
(defun sum-to (n) | |
(pcase n | |
('1 1) | |
(n (+ n (sum-to (1- n)))))) | |
(sum-to 1) ; => 1 | |
(sum-to 3) ; => 6 | |
(mapcar 'sum-to (number-sequence 1 10)) ;; => (1 3 6 10 15 21 28 36 45 55) | |
;;; Fibonacci number | |
(defun fib (n) | |
(pcase n | |
('0 1) | |
('1 1) | |
(n (+ (fib (- n 1)) (fib (- n 2)))))) | |
(mapcar 'fib (number-sequence 0 7)) ;; => (1 1 2 3 5 8 13 21) | |
;;; GCD | |
(defun gcd (x y) | |
(pcase (list x y) | |
(`(,x 0) x) | |
(`(,x ,y) (gcd y (% x y))))) | |
(gcd 12 8) ;; => 4 | |
(defun pow (x n) | |
(pcase `(,x ,n) | |
(`(,x 0) 1) | |
(`(,x ,n) | |
(* x (pow x (1- n)))))) | |
(pow 2 10) ;; => 1024 | |
(defun ackermann (m n) | |
(pcase (list m n) | |
(`(0 ,n) (1+ n)) | |
(`(,m 0) (ackermann (1- m) 1)) | |
(`(,m ,n) (ackermann (1- m) | |
(ackermann m (1- n)))))) | |
(ackermann 0 0) ;; => 1 | |
(defun int-to-words (n) | |
"List of English groupings for number N." | |
(let* ((pow10 (pcase (if (zerop n) 1 (floor (log10 (abs n)))) | |
(`1 1) | |
(`2 2) | |
(`3 3) | |
(n (- n (% n 3))))) | |
(base10 (expt 10.0 pow10))) | |
(pcase n | |
(`nil (error)) | |
((pred (> 0)) (cons "negative" (int-to-words (- n)))) | |
(`0 '("zero")) | |
(`1 '("one")) | |
(`2 '("two")) | |
(`3 '("three")) | |
(`4 '("four")) | |
(`5 '("five")) | |
(`6 '("six")) | |
(`7 '("seven")) | |
(`8 '("eight")) | |
(`9 '("nine")) | |
(`10 '("ten")) | |
(`11 '("eleven")) | |
(`12 '("twelve")) | |
(`13 '("thirteen")) | |
(`14 '("fourteen")) | |
(`15 '("fifteen")) | |
(`16 '("sixteen")) | |
(`17 '("seventeen")) | |
(`18 '("eighteen")) | |
(`19 '("nineteen")) | |
(`20 '("twenty")) | |
(`30 '("thirty")) | |
(`40 '("forty")) | |
(`50 '("fifty")) | |
(`60 '("sixty")) | |
(`70 '("seventy")) | |
(`80 '("eighty")) | |
(`90 '("ninety")) | |
;; Less than 100 | |
((pred (> 100)) | |
(list (mapconcat 'identity | |
(cons (car (int-to-words (- n (% n 10)))) | |
(int-to-words (% n 10))) "-"))) | |
;; Equal to a base ten | |
((pred (= base10)) (pcase pow10 | |
(`2 '("hundred")) | |
(`3 '("thousand")) | |
(`6 '("million")) | |
(`9 '("billion")) | |
(`12 '("trillion")) | |
(`15 '("quadrillion")) | |
(`18 '("quintillion")) | |
(`21 '("sextillion")) | |
(`24 '("septillion")) | |
(`27 '("octillion")) | |
(`30 '("nonillion")) | |
(`33 '("decillion")) | |
(`36 '("undecillion")) | |
(`39 '("duodecillion")) | |
(`42 '("tredecillion")) | |
(`45 '("quattuordecillion")) | |
(`48 '("quindecillion")) | |
(`51 '("sexdecillion")) | |
(`54 '("septendecillion")) | |
(`57 '("octodecillion")) | |
(`60 '("novemdecillion")) | |
(`63 '("vigintillion")) | |
(_ (signal 'domain-error (list n))))) | |
;; Greater than a base ten | |
((pred (< base10)) | |
(cons (mapconcat 'identity | |
(append (int-to-words (floor (/ n base10))) | |
(int-to-words base10)) | |
(if (< (/ n base10) 20) "-" " ")) | |
(if (zerop (mod n base10)) | |
nil | |
(int-to-words (if (< n most-positive-fixnum) | |
(% (floor n) (floor base10)) | |
(mod n base10))))))))) | |
(int-to-words 333) ;; => ("three-hundred" "thirty-three") | |
;;; elisp-pcase-note.el ends here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment