From 865874f50b112e02ed878a64aa69912a622de693 Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Wed, 24 Dec 2025 19:19:17 -0500 Subject: [PATCH] say --- config.json | 8 ++ exercises/practice/say/.busted | 5 + exercises/practice/say/.docs/instructions.md | 12 +++ exercises/practice/say/.docs/introduction.md | 6 ++ exercises/practice/say/.meta/config.json | 19 ++++ exercises/practice/say/.meta/example.moon | 31 ++++++ .../practice/say/.meta/spec_generator.moon | 19 ++++ exercises/practice/say/.meta/tests.toml | 67 +++++++++++++ exercises/practice/say/say.moon | 4 + exercises/practice/say/say_spec.moon | 95 +++++++++++++++++++ 10 files changed, 266 insertions(+) create mode 100644 exercises/practice/say/.busted create mode 100644 exercises/practice/say/.docs/instructions.md create mode 100644 exercises/practice/say/.docs/introduction.md create mode 100644 exercises/practice/say/.meta/config.json create mode 100644 exercises/practice/say/.meta/example.moon create mode 100644 exercises/practice/say/.meta/spec_generator.moon create mode 100644 exercises/practice/say/.meta/tests.toml create mode 100644 exercises/practice/say/say.moon create mode 100644 exercises/practice/say/say_spec.moon diff --git a/config.json b/config.json index 156c454..583033c 100644 --- a/config.json +++ b/config.json @@ -486,6 +486,14 @@ "practices": [], "prerequisites": [], "difficulty": 6 + }, + { + "slug": "say", + "name": "Say", + "uuid": "c1c9b94f-abbb-4356-b35b-8cff366e9415", + "practices": [], + "prerequisites": [], + "difficulty": 6 } ] }, diff --git a/exercises/practice/say/.busted b/exercises/practice/say/.busted new file mode 100644 index 0000000..86b84e7 --- /dev/null +++ b/exercises/practice/say/.busted @@ -0,0 +1,5 @@ +return { + default = { + ROOT = { '.' } + } +} diff --git a/exercises/practice/say/.docs/instructions.md b/exercises/practice/say/.docs/instructions.md new file mode 100644 index 0000000..3251c51 --- /dev/null +++ b/exercises/practice/say/.docs/instructions.md @@ -0,0 +1,12 @@ +# Instructions + +Given a number, your task is to express it in English words exactly as your friend should say it out loud. +Yaʻqūb expects to use numbers from 0 up to 999,999,999,999. + +Examples: + +- 0 → zero +- 1 → one +- 12 → twelve +- 123 → one hundred twenty-three +- 1,234 → one thousand two hundred thirty-four diff --git a/exercises/practice/say/.docs/introduction.md b/exercises/practice/say/.docs/introduction.md new file mode 100644 index 0000000..abd2285 --- /dev/null +++ b/exercises/practice/say/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +Your friend Yaʻqūb works the counter at the busiest deli in town, slicing, weighing, and wrapping orders for a never-ending line of hungry customers. +To keep things moving, each customer takes a numbered ticket when they arrive. + +When it’s time to call the next person, Yaʻqūb reads their number out loud, always in full English words to make sure everyone hears it clearly. diff --git a/exercises/practice/say/.meta/config.json b/exercises/practice/say/.meta/config.json new file mode 100644 index 0000000..198f532 --- /dev/null +++ b/exercises/practice/say/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "say.moon" + ], + "test": [ + "say_spec.moon" + ], + "example": [ + ".meta/example.moon" + ] + }, + "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.", + "source": "A variation on the JavaRanch CattleDrive, Assignment 4", + "source_url": "https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804" +} diff --git a/exercises/practice/say/.meta/example.moon b/exercises/practice/say/.meta/example.moon new file mode 100644 index 0000000..c9813ec --- /dev/null +++ b/exercises/practice/say/.meta/example.moon @@ -0,0 +1,31 @@ +WORDS = { + [0]: 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', + 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', + 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty', + [30]: 'thirty', [40]: 'forty', [50]: 'fifty', [60]: 'sixty', + [70]: 'seventy', [80]: 'eighty', [90]: 'ninety', +} + + +say_small = (n) -> WORDS[n] or "#{WORDS[n - n % 10]}-#{WORDS[n % 10]}" + +local in_english + +say_compound = (n, base, unit) -> + quotient, remainder = n // base, n % base + saying = "#{in_english quotient} #{unit}" + saying ..= " #{in_english remainder}" if remainder > 0 + saying + + +in_english = (n) -> + assert 0 <= n and n < 1e12, 'input out of range' + + if n < 100 then say_small n + elseif n < 1e3 then say_compound n, 100, 'hundred' + elseif n < 1e6 then say_compound n, 1e3, 'thousand' + elseif n < 1e9 then say_compound n, 1e6, 'million' + else say_compound n, 1e9, 'billion' + + +{ :in_english } diff --git a/exercises/practice/say/.meta/spec_generator.moon b/exercises/practice/say/.meta/spec_generator.moon new file mode 100644 index 0000000..878afcd --- /dev/null +++ b/exercises/practice/say/.meta/spec_generator.moon @@ -0,0 +1,19 @@ +{ + module_name: 'Say', + + generate_test: (case, level) -> + local lines + switch type(case.expected) + when 'table' + lines = { + "f = -> Say.in_english #{case.input.number}", + "assert.has.error f,#{quote case.expected.error}" + } + else + lines = { + "result = Say.in_english #{case.input.number}", + "expected = #{quote case.expected}", + "assert.are.equal expected, result" + } + table.concat [indent line, level for line in *lines], '\n' +} diff --git a/exercises/practice/say/.meta/tests.toml b/exercises/practice/say/.meta/tests.toml new file mode 100644 index 0000000..a5532e9 --- /dev/null +++ b/exercises/practice/say/.meta/tests.toml @@ -0,0 +1,67 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[5d22a120-ba0c-428c-bd25-8682235d83e8] +description = "zero" + +[9b5eed77-dbf6-439d-b920-3f7eb58928f6] +description = "one" + +[7c499be1-612e-4096-a5e1-43b2f719406d] +description = "fourteen" + +[f541dd8e-f070-4329-92b4-b7ce2fcf06b4] +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" + +[865af898-1d5b-495f-8ff0-2f06d3c73709] +description = "one thousand two hundred thirty-four" + +[b6a3f442-266e-47a3-835d-7f8a35f6cf7f] +description = "one million" + +[2cea9303-e77e-4212-b8ff-c39f1978fc70] +description = "one million two thousand three hundred forty-five" + +[3e240eeb-f564-4b80-9421-db123f66a38f] +description = "one billion" + +[9a43fed1-c875-4710-8286-5065d73b8a9e] +description = "a big number" + +[49a6a17b-084e-423e-994d-a87c0ecc05ef] +description = "numbers below zero are out of range" + +[4d6492eb-5853-4d16-9d34-b0f61b261fd9] +description = "numbers above 999,999,999,999 are out of range" diff --git a/exercises/practice/say/say.moon b/exercises/practice/say/say.moon new file mode 100644 index 0000000..ab6979d --- /dev/null +++ b/exercises/practice/say/say.moon @@ -0,0 +1,4 @@ +{ + in_english: (number) -> + error 'Implement me' +} diff --git a/exercises/practice/say/say_spec.moon b/exercises/practice/say/say_spec.moon new file mode 100644 index 0000000..2a2fdbb --- /dev/null +++ b/exercises/practice/say/say_spec.moon @@ -0,0 +1,95 @@ +Say = require './say' + +describe 'say', -> + it 'zero', -> + result = Say.in_english 0 + expected = 'zero' + assert.are.equal expected, result + + pending 'one', -> + result = Say.in_english 1 + expected = 'one' + assert.are.equal expected, result + + pending 'fourteen', -> + result = Say.in_english 14 + expected = 'fourteen' + assert.are.equal expected, result + + pending 'twenty', -> + result = Say.in_english 20 + expected = 'twenty' + assert.are.equal expected, result + + pending 'twenty-two', -> + result = Say.in_english 22 + expected = 'twenty-two' + assert.are.equal expected, result + + pending 'thirty', -> + result = Say.in_english 30 + expected = 'thirty' + assert.are.equal expected, result + + pending 'ninety-nine', -> + result = Say.in_english 99 + expected = 'ninety-nine' + assert.are.equal expected, result + + pending 'one hundred', -> + result = Say.in_english 100 + expected = 'one hundred' + assert.are.equal expected, result + + pending 'one hundred twenty-three', -> + result = Say.in_english 123 + expected = 'one hundred twenty-three' + assert.are.equal expected, result + + pending 'two hundred', -> + result = Say.in_english 200 + expected = 'two hundred' + assert.are.equal expected, result + + pending 'nine hundred ninety-nine', -> + result = Say.in_english 999 + expected = 'nine hundred ninety-nine' + assert.are.equal expected, result + + pending 'one thousand', -> + result = Say.in_english 1000 + expected = 'one thousand' + assert.are.equal expected, result + + pending 'one thousand two hundred thirty-four', -> + result = Say.in_english 1234 + expected = 'one thousand two hundred thirty-four' + assert.are.equal expected, result + + pending 'one million', -> + result = Say.in_english 1000000 + expected = 'one million' + assert.are.equal expected, result + + pending 'one million two thousand three hundred forty-five', -> + result = Say.in_english 1002345 + expected = 'one million two thousand three hundred forty-five' + assert.are.equal expected, result + + pending 'one billion', -> + result = Say.in_english 1000000000 + expected = 'one billion' + assert.are.equal expected, result + + pending 'a big number', -> + result = Say.in_english 987654321123 + expected = 'nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three' + assert.are.equal expected, result + + pending 'numbers below zero are out of range', -> + f = -> Say.in_english -1 + assert.has.error f,'input out of range' + + pending 'numbers above 999,999,999,999 are out of range', -> + f = -> Say.in_english 1000000000000 + assert.has.error f,'input out of range'