|
4 | 4 |
|
5 | 5 | ;;; Code: |
6 | 6 |
|
| 7 | +(require 'cl-lib) |
| 8 | + |
7 | 9 | (define-error 'out-of-range "input out of range") |
8 | 10 |
|
9 | 11 | (defun say (number) |
|
14 | 16 | (tens '("" "" "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety")) |
15 | 17 | (powers '("" "thousand" "million" "billion"))) |
16 | 18 |
|
17 | | - (defun number-to-words (n) |
18 | | - (let ((parts '())) |
19 | | - (while (> n 0) |
20 | | - (let* ((power (if (> n 999999999) 3 (if (> n 999999) 2 (if (> n 999) 1 0)))) |
21 | | - (unit (expt 1000 power)) |
22 | | - (quotient (/ n unit)) |
23 | | - (remainder (% n unit))) |
| 19 | + (cl-labels |
| 20 | + ((number-to-words (n) |
| 21 | + (let ((parts '())) |
| 22 | + (while (> n 0) |
| 23 | + (let* ((power (if (> n 999999999) 3 (if (> n 999999) 2 (if (> n 999) 1 0)))) |
| 24 | + (unit (expt 1000 power)) |
| 25 | + (quotient (/ n unit)) |
| 26 | + (remainder (% n unit))) |
24 | 27 | (if (> quotient 0) |
25 | | - (push (concat (number-to-words-1000 quotient) (if (> power 0) (concat " " (nth power powers)) "")) parts)) |
| 28 | + (push (concat (number-to-words-1000 quotient) (if (> power 0) (concat " " (nth power powers)) "")) parts)) |
26 | 29 | (setq n remainder))) |
27 | | - (string-join (reverse parts) " "))) |
28 | | - |
29 | | - (defun number-to-words-1000 (n) |
30 | | - (cond |
31 | | - ((< n 10) (nth n ones)) |
32 | | - ((< n 20) (nth (- n 10) teens)) |
33 | | - ((< n 100) |
34 | | - (let ((ten (nth (/ n 10) tens)) |
| 30 | + (string-join (reverse parts) " "))) |
| 31 | + |
| 32 | + (number-to-words-1000 (n) |
| 33 | + (cond |
| 34 | + ((< n 10) (nth n ones)) |
| 35 | + ((< n 20) (nth (- n 10) teens)) |
| 36 | + ((< n 100) |
| 37 | + (let ((ten (nth (/ n 10) tens)) |
35 | 38 | (one (nth (% n 10) ones))) |
36 | | - (if (= (% n 10) 0) |
| 39 | + (if (= (% n 10) 0) |
37 | 40 | ten |
38 | | - (concat ten "-" one)))) |
39 | | - ((< n 1000) |
40 | | - (let ((hundred (nth (/ n 100) ones)) |
| 41 | + (concat ten "-" one)))) |
| 42 | + ((< n 1000) |
| 43 | + (let ((hundred (nth (/ n 100) ones)) |
41 | 44 | (remainder (% n 100))) |
42 | | - (if (= remainder 0) |
| 45 | + (if (= remainder 0) |
43 | 46 | (concat hundred " hundred") |
44 | | - (concat hundred " hundred " (number-to-words-1000 remainder))))))) |
| 47 | + (concat hundred " hundred " (number-to-words-1000 remainder)))))))) |
45 | 48 |
|
46 | | - (when (and (>= number 0) (< number (expt 10 12))) |
47 | | - (if (= number 0) |
| 49 | + (when (and (>= number 0) (< number (expt 10 12))) |
| 50 | + (if (= number 0) |
48 | 51 | "zero" |
49 | | - (string-trim (number-to-words number)))))) |
50 | | - |
| 52 | + (string-trim (number-to-words number))))))) |
51 | 53 |
|
52 | 54 | (provide 'say) |
53 | 55 | ;;; say.el ends here |
|
0 commit comments