diff --git a/exercises/practice/say/.docs/instructions.md b/exercises/practice/say/.docs/instructions.md index 727b0186d..fb4a6dfb9 100644 --- a/exercises/practice/say/.docs/instructions.md +++ b/exercises/practice/say/.docs/instructions.md @@ -6,11 +6,9 @@ Given a number from 0 to 999,999,999,999, spell out that number in English. Handle the basic case of 0 through 99. -If the input to the program is `22`, then the output should be -`'twenty-two'`. +If the input to the program is `22`, then the output should be `'twenty-two'`. -Your program should complain loudly if given a number outside the -blessed range. +Your program should complain loudly if given a number outside the blessed range. Some good test cases for this program are: @@ -23,15 +21,14 @@ Some good test cases for this program are: ### Extension -If you're on a Mac, shell out to Mac OS X's `say` program to talk out -loud. If you're on Linux or Windows, eSpeakNG may be available with the command `espeak`. +If you're on a Mac, shell out to Mac OS X's `say` program to talk out loud. +If you're on Linux or Windows, eSpeakNG may be available with the command `espeak`. ## Step 2 Implement breaking a number up into chunks of thousands. -So `1234567890` should yield a list like 1, 234, 567, and 890, while the -far simpler `1000` should yield just 1 and 0. +So `1234567890` should yield a list like 1, 234, 567, and 890, while the far simpler `1000` should yield just 1 and 0. The program must also report any values that are out of range. @@ -41,8 +38,8 @@ Now handle inserting the appropriate scale word between those chunks. So `1234567890` should yield `'1 billion 234 million 567 thousand 890'` -The program must also report any values that are out of range. It's -fine to stop at "trillion". +The program must also report any values that are out of range. +It's fine to stop at "trillion". ## Step 4 @@ -51,13 +48,3 @@ Put it all together to get nothing but plain English. `12345` should give `twelve thousand three hundred forty-five`. The program must also report any values that are out of range. - -### Extensions - -Use _and_ (correctly) when spelling out the number in English: - -- 14 becomes "fourteen". -- 100 becomes "one hundred". -- 120 becomes "one hundred and twenty". -- 1002 becomes "one thousand and two". -- 1323 becomes "one thousand three hundred and twenty-three". diff --git a/exercises/practice/say/.meta/additional-tests.json b/exercises/practice/say/.meta/additional-tests.json new file mode 100644 index 000000000..6df96e614 --- /dev/null +++ b/exercises/practice/say/.meta/additional-tests.json @@ -0,0 +1,20 @@ +[ + { + "uuid": "ecafab60-89f2-4680-9286-56b423e8a7b9", + "description": "max i64", + "property": "say", + "input": { + "number": 9223372036854775807 + }, + "expected": "nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven" + }, + { + "uuid": "88808dac-dffb-46a6-95d4-68d5271a9c38", + "description": "max u64", + "property": "say", + "input": { + "number": 18446744073709551615 + }, + "expected": "eighteen quintillion four hundred forty-six quadrillion seven hundred forty-four trillion seventy-three billion seven hundred nine million five hundred fifty-one thousand six hundred fifteen" + } +] \ No newline at end of file diff --git a/exercises/practice/say/.meta/config.json b/exercises/practice/say/.meta/config.json index 42c063967..195df14da 100644 --- a/exercises/practice/say/.meta/config.json +++ b/exercises/practice/say/.meta/config.json @@ -33,6 +33,6 @@ ] }, "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.", - "source": "A variation on JavaRanch CattleDrive, exercise 4a", - "source_url": "http://www.javaranch.com/say.jsp" + "source": "A variation on the JavaRanch CattleDrive, Assignment 4", + "source_url": "https://coderanch.com/wiki/718804" } diff --git a/exercises/practice/say/.meta/test_template.tera b/exercises/practice/say/.meta/test_template.tera new file mode 100644 index 000000000..51753e6f7 --- /dev/null +++ b/exercises/practice/say/.meta/test_template.tera @@ -0,0 +1,12 @@ +{% for test in cases %} +#[test] +{% if loop.index != 1 -%} +#[ignore] +{% endif -%} +fn {{ test.description | slugify | replace(from="-", to="_") }}() { + let input = {{ test.input.number | json_encode() }}; + let output = {{ crate_name }}::{{ fn_names[0] }}(input); + let expected = {{ test.expected | json_encode() }}; + assert_eq!(output, expected); +} +{% endfor -%} diff --git a/exercises/practice/say/.meta/tests.toml b/exercises/practice/say/.meta/tests.toml index 6ef482ff1..1d2c4d469 100644 --- a/exercises/practice/say/.meta/tests.toml +++ b/exercises/practice/say/.meta/tests.toml @@ -1,6 +1,13 @@ -# This is an auto-generated file. Regular comments will be removed when this -# file is regenerated. Regenerating will not touch any manually added keys, -# so comments can be added in a "comment" key. +# 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" @@ -13,3 +20,52 @@ 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" +include = false +comment = "explanation in .docs/instructions.append.md" + +[4d6492eb-5853-4d16-9d34-b0f61b261fd9] +description = "numbers above 999,999,999,999 are out of range" +include = false +comment = "explanation in .docs/instructions.append.md" diff --git a/exercises/practice/say/tests/say.rs b/exercises/practice/say/tests/say.rs index 02a17fc10..e7b002ca1 100644 --- a/exercises/practice/say/tests/say.rs +++ b/exercises/practice/say/tests/say.rs @@ -1,160 +1,169 @@ -// Note: No tests created using 'and' with numbers. -// Apparently Most American English does not use the 'and' with numbers, -// where it is common in British English to use the 'and'. - #[test] fn zero() { - assert_eq!(say::encode(0), String::from("zero")); -} - -// -// If the below test is uncommented, it should not compile. -// -/* -#[test] -#[ignore] -fn negative() { - assert_eq!(say::encode(-1), String::from("won't compile")); + let input = 0; + let output = say::encode(input); + let expected = "zero"; + assert_eq!(output, expected); } -*/ #[test] #[ignore] fn one() { - assert_eq!(say::encode(1), String::from("one")); + let input = 1; + let output = say::encode(input); + let expected = "one"; + assert_eq!(output, expected); } #[test] #[ignore] fn fourteen() { - assert_eq!(say::encode(14), String::from("fourteen")); + let input = 14; + let output = say::encode(input); + let expected = "fourteen"; + assert_eq!(output, expected); } #[test] #[ignore] fn twenty() { - assert_eq!(say::encode(20), String::from("twenty")); + let input = 20; + let output = say::encode(input); + let expected = "twenty"; + assert_eq!(output, expected); } #[test] #[ignore] fn twenty_two() { - assert_eq!(say::encode(22), String::from("twenty-two")); + let input = 22; + let output = say::encode(input); + let expected = "twenty-two"; + assert_eq!(output, expected); } #[test] #[ignore] -fn one_hundred() { - assert_eq!(say::encode(100), String::from("one hundred")); +fn thirty() { + let input = 30; + let output = say::encode(input); + let expected = "thirty"; + assert_eq!(output, expected); } -// note, using American style with no and #[test] #[ignore] -fn one_hundred_twenty() { - assert_eq!(say::encode(120), String::from("one hundred twenty")); +fn ninety_nine() { + let input = 99; + let output = say::encode(input); + let expected = "ninety-nine"; + assert_eq!(output, expected); +} + +#[test] +#[ignore] +fn one_hundred() { + let input = 100; + let output = say::encode(input); + let expected = "one hundred"; + assert_eq!(output, expected); } #[test] #[ignore] fn one_hundred_twenty_three() { - assert_eq!(say::encode(123), String::from("one hundred twenty-three")); + let input = 123; + let output = say::encode(input); + let expected = "one hundred twenty-three"; + assert_eq!(output, expected); } #[test] #[ignore] -fn one_thousand() { - assert_eq!(say::encode(1000), String::from("one thousand")); +fn two_hundred() { + let input = 200; + let output = say::encode(input); + let expected = "two hundred"; + assert_eq!(output, expected); } #[test] #[ignore] -fn one_thousand_two_hundred_thirty_four() { - assert_eq!( - say::encode(1234), - String::from("one thousand two hundred thirty-four") - ); +fn nine_hundred_ninety_nine() { + let input = 999; + let output = say::encode(input); + let expected = "nine hundred ninety-nine"; + assert_eq!(output, expected); } -// note, using American style with no and #[test] #[ignore] -fn eight_hundred_and_ten_thousand() { - assert_eq!( - say::encode(810_000), - String::from("eight hundred ten thousand") - ); +fn one_thousand() { + let input = 1000; + let output = say::encode(input); + let expected = "one thousand"; + assert_eq!(output, expected); } #[test] #[ignore] -fn one_million() { - assert_eq!(say::encode(1_000_000), String::from("one million")); +fn one_thousand_two_hundred_thirty_four() { + let input = 1234; + let output = say::encode(input); + let expected = "one thousand two hundred thirty-four"; + assert_eq!(output, expected); } -// note, using American style with no and #[test] #[ignore] -fn one_million_two() { - assert_eq!(say::encode(1_000_002), String::from("one million two")); +fn one_million() { + let input = 1000000; + let output = say::encode(input); + let expected = "one million"; + assert_eq!(output, expected); } #[test] #[ignore] fn one_million_two_thousand_three_hundred_forty_five() { - assert_eq!( - say::encode(1_002_345), - String::from("one million two thousand three hundred forty-five") - ); + let input = 1002345; + let output = say::encode(input); + let expected = "one million two thousand three hundred forty-five"; + assert_eq!(output, expected); } #[test] #[ignore] fn one_billion() { - assert_eq!(say::encode(1_000_000_000), String::from("one billion")); + let input = 1000000000; + let output = say::encode(input); + let expected = "one billion"; + assert_eq!(output, expected); } #[test] #[ignore] -fn test_987654321123() { - assert_eq!( - say::encode(987_654_321_123), - String::from( - "nine hundred eighty-seven billion \ - six hundred fifty-four million \ - three hundred twenty-one thousand \ - one hundred twenty-three" - ) - ); +fn a_big_number() { + let input = 987654321123; + let output = say::encode(input); + let expected = "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three"; + assert_eq!(output, expected); } -/* - These tests are only if you implemented full parsing for u64 type. -*/ #[test] #[ignore] fn max_i64() { - assert_eq!( - say::encode(9_223_372_036_854_775_807), - String::from( - "nine quintillion two hundred twenty-three \ - quadrillion three hundred seventy-two trillion \ - thirty-six billion eight hundred fifty-four million \ - seven hundred seventy-five thousand eight hundred seven" - ) - ); + let input = 9223372036854775807; + let output = say::encode(input); + let expected = "nine quintillion two hundred twenty-three quadrillion three hundred seventy-two trillion thirty-six billion eight hundred fifty-four million seven hundred seventy-five thousand eight hundred seven"; + assert_eq!(output, expected); } #[test] #[ignore] fn max_u64() { - assert_eq!( - say::encode(18_446_744_073_709_551_615), - String::from( - "eighteen quintillion four hundred forty-six \ - quadrillion seven hundred forty-four trillion \ - seventy-three billion seven hundred nine million \ - five hundred fifty-one thousand six hundred fifteen" - ) - ); + let input = 18446744073709551615; + let output = say::encode(input); + let expected = "eighteen quintillion four hundred forty-six quadrillion seven hundred forty-four trillion seventy-three billion seven hundred nine million five hundred fifty-one thousand six hundred fifteen"; + assert_eq!(output, expected); }