;;; spell-number.el

(defun spell-999 (n)
 "Return English spelling of integer N (0<=N<=999)."
 (let
     ((hundreds (/ n 100))
      (tens (/ (% n 100) 10))
      (units (% n 10)))
   (concat
    (if (> hundreds 0)
        (concat (spell-unit hundreds) " hundred "))
    (cond
     ((= tens 1) (spell-teens units))
     ((> tens 1)
      (concat
       (spell-tens tens)
       (if (> units 0) "-"))))
    (if (and (not (= tens 1)) (> units 0)) (spell-unit units)))))

(defun spell-unit (n)
 "Return spelling of single-digit integer N (1<=N<=9)."
 (cond
  ((= n 1) "one")
  ((= n 2) "two")
  ((= n 3) "three")
  ((= n 4) "four")
  ((= n 5) "five")
  ((= n 6) "six")
  ((= n 7) "seven")
  ((= n 8) "eight")
  ((= n 9) "nine")))

(defun spell-tens (n)
 "Return spelling of single-digit multiple of ten N (2<=N<=9)."
 (cond
  ((= n 2) "twenty")
  ((= n 3) "thirty")
  ((= n 4) "forty")
  ((= n 5) "fifty")
  ((= n 6) "sixty")
  ((= n 7) "seventy")
  ((= n 8) "eighty")
  ((= n 9) "ninety")))

(defun spell-teens (n)
 "Return spelling of 'teens' number corresponding to single-digit nteger N (0<=N<=9)."
 (cond
  ((= n 0) "ten")
  ((= n 1) "eleven")
  ((= n 2) "twelve")
  ((= n 3) "thirteen")
  ((= n 4) "fourteen")
  ((= n 5) "fifteen")
  ((= n 6) "sixteen")
  ((= n 7) "seventeen")
  ((= n 8) "eighteen")
  ((= n 9) "nineteen")))

(defun bottles-of-beer ()
 "Sing the song."
 (interactive)
 (progn
   (switch-to-buffer "*bottles-of-beer*")
   (dotimes (i 100)
     (let*
         ((n (- 100 i))
          (number (spell-999 n))
          (b (if (= n 1) "bottle" "bottles")))
       (insert
        (if (< n 100) (format "%s %s of beer on the wall\n\n" number b) "")
        (format "%s %s of beer on the wall\n%s %s of beer\nYou take one down, pass it around\n" number b number b))))
   (insert "no more bottles of beer on the wall\n")))