Skip to content

Commit

Permalink
Merge branch 'update-say' of https://github.com/BNAndras/exercism-racket
Browse files Browse the repository at this point in the history
 into update-say
  • Loading branch information
BNAndras committed Dec 20, 2023
2 parents d915c9d + d7624e0 commit cbfba99
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 103 deletions.
29 changes: 18 additions & 11 deletions exercises/practice/say/.meta/example.rkt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#lang racket/base
#lang racket

;; say : Convert integers to English-language descriptions

Expand All @@ -22,20 +22,24 @@

;; Use contracts to enforce all bounds
(provide (contract-out
[step1 (-> (integer-in 0 99) string?)]
[spell-out (-> (integer-in (- UPPER-BOUND) UPPER-BOUND)
string?)]
;; Band-aid alias for step4 for tests to pass

[step1 (-> (integer-in 0 99) string?)]
;; Convert a positive, 2-digit number to an English string

[step2 (-> natural-number/c (listof (integer-in 0 999)))]
[step2 (-> natural-number/c (listof (integer-in 0 999)))]
;; Divide a large positive number into a list of 3-digit (or smaller) chunks

[step3 (-> (integer-in (- UPPER-BOUND) UPPER-BOUND)
(listof (cons/c natural-number/c scale?)))]
[step3 (-> (integer-in (- UPPER-BOUND) UPPER-BOUND)
(listof (cons/c natural-number/c scale?)))]
;; Break a number into chunks and insert scales between the chunks

[step4 (-> (integer-in (- UPPER-BOUND) UPPER-BOUND)
string?)]
[step4 (-> (integer-in (- UPPER-BOUND) UPPER-BOUND)
string?)]))
;; Convert a number to an English-language string
))


;; =============================================================================

Expand All @@ -47,6 +51,8 @@
(define TENS>10
'#("twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety"))

(define (spell-out number) (step4 number))

(define (step1 n)
(cond
[(< n 20)
Expand Down Expand Up @@ -108,10 +114,11 @@
;; Use `string-trim` to remove trailing whitespace
(define n-str (string-trim (apply string-append str*)))
(cond ;; Check for special cases
[(negative? N)
(error "input out of range")]
[(> N 999999999999)
(error "input out of range")]
[(zero? N)
"zero"]
[(negative? N)
(string-append "negative " n-str)]
[else
n-str]))

12 changes: 12 additions & 0 deletions exercises/practice/say/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,24 @@ description = "twenty"
[d78601eb-4a84-4bfa-bf0e-665aeb8abe94]
description = "twenty-two"

[f010d4ca-12c9-44e9-803a-27789841adb1]
description = "thirty"

[738ce12d-ee5c-4dfb-ad26-534753a98327]
description = "ninety-nine"

[e417d452-129e-4056-bd5b-6eb1df334dce]
description = "one hundred"

[d6924f30-80ba-4597-acf6-ea3f16269da8]
description = "one hundred twenty-three"

[2f061132-54bc-4fd4-b5df-0a3b778959b9]
description = "two hundred"

[feed6627-5387-4d38-9692-87c0dbc55c33]
description = "nine hundred ninety-nine"

[3d83da89-a372-46d3-b10d-de0c792432b3]
description = "one thousand"

Expand Down
158 changes: 89 additions & 69 deletions exercises/practice/say/say-test.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,95 @@

(require "say.rkt")


(module+ test
(require rackunit rackunit/text-ui)

(define-syntax-rule (check-equal* f [arg == val] ...)
(begin (check-equal? (f arg) val) ...))

(define-syntax-rule (check-exn* f pat [arg] ...)
(begin (check-exn exn:fail:contract? (lambda () (f arg))) ...))

(define step*
(list
(test-suite "step1"
(check-equal* step1
[0 == "zero"]
[2 == "two"]
[14 == "fourteen"]
[50 == "fifty"]
[98 == "ninety-eight"]
[99 == "ninety-nine"])

(check-exn* step1
[-1]
[100]))

(test-suite "step2"
(check-equal* step2
[1234567890 == '(1 234 567 890)]
[1000000890 == '(1 0 0 890)]
[22 == '(22)]
[3222 == '(3 222)]
[1000231 == '(1 0 231)]
[1000 == '(1 0)]))

(test-suite "step3"
(check-equal* step3
[3222 == '((3 . thousand) (222 . END))]
[901003004111 == '((901 . billion) (3 . million)
(4 . thousand) (111 . END))]
[999 == '((999 . END))]
[21 == '((21 . END))]
[19 == '((19 . END))]
[100 == '((100 . END))]
[123 == '((123 . END))]
[1234567890 == '((1 . billion) (234 . million)
(567 . thousand) (890 . END))]))

(test-suite "step4"
(check-equal* step4
[10 == "ten"]
[100 == "one hundred"]
[10000 == "ten thousand"]
[10000000 == "ten million"]
[10000000000 == "ten billion"]
[10000000000000 == "ten trillion"]
[999000000000000 == "nine hundred ninety-nine trillion"]
[0 == "zero"]
[16 == "sixteen"]
[300 == "three hundred"]
[440 == "four hundred forty"]
[999 == "nine hundred ninety-nine"]
[-1 == "negative one"]
[22 == "twenty-two"]
[123 == "one hundred twenty-three"]
[22 == "twenty-two"]
[14 == "fourteen"]
[50 == "fifty"]
[98 == "ninety-eight"]
[-432600 == "negative four hundred thirty-two thousand six hundred"]
[12345 == "twelve thousand three hundred forty-five"]))))

(for ([suite (in-list step*)])
(run-tests suite)))
(define (exn-msg-matches? msg f)
(with-handlers ([exn:fail? (lambda (exn)
(string=? (exn-message exn) msg))])
(f)))

(define suite
(test-suite
"say tests"

(test-equal? "zero"
(spell-out 0)
"zero")

(test-equal? "one"
(spell-out 1)
"one")

(test-equal? "fourteen"
(spell-out 14)
"fourteen")

(test-equal? "twenty"
(spell-out 20)
"twenty")

(test-equal? "twenty-two"
(spell-out 22)
"twenty-two")

(test-equal? "thirty"
(spell-out 30)
"thirty")

(test-equal? "ninety-nine"
(spell-out 99)
"ninety-nine")

(test-equal? "one hundred"
(spell-out 100)
"one hundred")

(test-equal? "one hundred twenty-three"
(spell-out 123)
"one hundred twenty-three")

(test-equal? "two hundred"
(spell-out 200)
"two hundred")

(test-equal? "nine hundred ninety-nine"
(spell-out 999)
"nine hundred ninety-nine")

(test-equal? "one thousand"
(spell-out 1000)
"one thousand")

(test-equal? "one thousand two hundred thirty-four"
(spell-out 1234)
"one thousand two hundred thirty-four")

(test-equal? "one million"
(spell-out 1000000)
"one million")

(test-equal? "one million two thousand three hundred forty-five"
(spell-out 1002345)
"one million two thousand three hundred forty-five")

(test-equal? "one billion"
(spell-out 1000000000)
"one billion")

(test-equal? "a big number"
(spell-out 987654321123)
"nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three")

(test-true "numbers below zero are out of range"
(exn-msg-matches?
"input out of range"
(lambda () (spell-out -1))))

(test-true "numbers above 999,999,999,999 are out of range"
(exn-msg-matches?
"input out of range"
(lambda () (spell-out 1000000000000))))))

(run-tests suite))
Loading

0 comments on commit cbfba99

Please sign in to comment.