diff --git a/config.json b/config.json index e6f9cce..914f483 100644 --- a/config.json +++ b/config.json @@ -752,6 +752,14 @@ "prerequisites": [], "difficulty": 5 }, + { + "slug": "say", + "name": "Say", + "uuid": "0f01ba32-e46b-47ac-93c7-e0c3739424ae", + "practices": [], + "prerequisites": [], + "difficulty": 5 + }, { "slug": "spiral-matrix", "name": "Spiral Matrix", 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..e719c84 --- /dev/null +++ b/exercises/practice/say/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "say.coffee" + ], + "test": [ + "say.spec.coffee" + ], + "example": [ + ".meta/example.coffee" + ] + }, + "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.coffee b/exercises/practice/say/.meta/example.coffee new file mode 100644 index 0000000..fc4ebf0 --- /dev/null +++ b/exercises/practice/say/.meta/example.coffee @@ -0,0 +1,68 @@ +class Say + @say: (number) -> + throw new Error 'input out of range' if number < 0 or number > 999999999999 + + if number is 0 + return 'zero' + + chunks = @chunksFromRight number.toString() + words = (chunks.map Number).map @toWords.bind @ + words = words.map @applyScale.bind @ + words = words.filter (word) -> word isnt '' + words.reverse().join(' ') + + @chunksFromRight: (str) -> + chunks = [] + working = str + + while working.length > 0 + chunks.push working.slice -3 + working = working.slice 0, -3 + + chunks + + @toWords: (chunk) -> + words = [] + if chunk < 20 + words.push @firstTwentyNumbers[chunk] + else if chunk < 100 + tens = @wordsForTens[Math.floor(chunk / 10)] + ones = @firstTwentyNumbers[chunk % 10] + if ones + words.push "#{tens}-#{ones}" + else + words.push tens + else + hundreds = @firstTwentyNumbers[Math.floor(chunk / 100)] + rest = @toWords(chunk % 100) + if rest + words.push "#{hundreds} hundred #{rest}" + else + words.push "#{hundreds} hundred" + + words.join ' ' + + @applyScale: (word, index) -> + if word is '' + return '' + if index == 0 + return word + if index == 1 + return "#{word} thousand" + if index == 2 + return "#{word} million" + if index == 3 + return "#{word} billion" + else + return word + + @firstTwentyNumbers: [ + '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', + 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' + ] + + @wordsForTens: [ + '', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' + ] + +module.exports = Say 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.coffee b/exercises/practice/say/say.coffee new file mode 100644 index 0000000..47135df --- /dev/null +++ b/exercises/practice/say/say.coffee @@ -0,0 +1,4 @@ +class Say + @say: (number) -> + +module.exports = Say diff --git a/exercises/practice/say/say.spec.coffee b/exercises/practice/say/say.spec.coffee new file mode 100644 index 0000000..b40bf2b --- /dev/null +++ b/exercises/practice/say/say.spec.coffee @@ -0,0 +1,66 @@ +Say = require './say' + +describe 'Say', -> + it 'zero', -> + expect(Say.say 0).toEqual 'zero' + + xit 'one', -> + expect(Say.say 1).toEqual 'one' + + xit 'fourteen', -> + expect(Say.say 14).toEqual 'fourteen' + + xit 'twenty', -> + expect(Say.say 20).toEqual 'twenty' + + xit 'twenty-two', -> + expect(Say.say 22).toEqual 'twenty-two' + + xit 'thirty', -> + expect(Say.say 30).toEqual 'thirty' + + xit 'ninety-nine', -> + expect(Say.say 99).toEqual 'ninety-nine' + + xit 'one hundred', -> + expect(Say.say 100).toEqual 'one hundred' + + xit 'one hundred twenty-three', -> + expect(Say.say 123).toEqual 'one hundred twenty-three' + + xit 'two hundred', -> + expect(Say.say 200).toEqual 'two hundred' + + xit 'nine hundred ninety-nine', -> + expect(Say.say 999).toEqual 'nine hundred ninety-nine' + + xit 'one thousand', -> + expect(Say.say 1000).toEqual 'one thousand' + + xit 'one thousand two hundred thirty-four', -> + expect(Say.say 1234).toEqual 'one thousand two hundred thirty-four' + + xit 'one million', -> + expect(Say.say 1000000).toEqual 'one million' + + xit 'one million two thousand three hundred forty-five', -> + expect(Say.say 1002345).toEqual 'one million two thousand three hundred forty-five' + + xit 'one billion', -> + expect(Say.say 1000000000).toEqual 'one billion' + + xit 'a big number', -> + expect(Say.say 987654321123).toEqual 'nine hundred eighty-seven billion ' + + 'six hundred fifty-four million ' + + 'three hundred twenty-one thousand ' + + 'one hundred twenty-three' + + xit 'numbers below zero are out of range', -> + expect -> + Say.say -1 + .toThrow new Error 'input out of range' + + xit 'numbers above 999,999,999,999 are out of range', -> + expect -> + Say.say 1000000000000 + .toThrow new Error 'input out of range'