Skip to content

Commit

Permalink
Add say exercise (#406)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored Mar 25, 2024
1 parent 43752ae commit 0195e72
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "say",
"name": "Say",
"uuid": "50fe2f01-54d1-4dea-a476-e2aa3e7ffdaa",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
],
"foregone": [
Expand Down
48 changes: 48 additions & 0 deletions exercises/practice/say/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Instructions

Given a number from 0 to 999,999,999,999, spell out that number in English.

## Step 1

Handle the basic case of 0 through 99.

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.

Some good test cases for this program are:

- 0
- 14
- 50
- 98
- -1
- 100

### 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`.

## 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.

## Step 3

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".

## Step 4

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.
19 changes: 19 additions & 0 deletions exercises/practice/say/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"erikschierboom"
],
"files": {
"solution": [
"say.pl"
],
"test": [
"say_tests.plt"
],
"example": [
".meta/say.example.pl"
]
},
"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://coderanch.com/wiki/718804"
}
55 changes: 55 additions & 0 deletions exercises/practice/say/.meta/say.example.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
say(0, "zero") :- !.
say(1, "one") :- !.
say(2, "two") :- !.
say(3, "three") :- !.
say(4, "four") :- !.
say(5, "five") :- !.
say(6, "six") :- !.
say(7, "seven") :- !.
say(8, "eight") :- !.
say(9, "nine") :- !.
say(10, "ten") :- !.
say(11, "eleven") :- !.
say(12, "twelve") :- !.
say(13, "thirteen") :- !.
say(14, "fourteen") :- !.
say(15, "fifteen") :- !.
say(16, "sixteen") :- !.
say(17, "seventeen") :- !.
say(18, "eighteen") :- !.
say(19, "nineteen") :- !.

say(20, "twenty") :- !.
say(30, "thirty") :- !.
say(40, "forty") :- !.
say(50, "fifty") :- !.
say(60, "sixty") :- !.
say(70, "seventy") :- !.
say(80, "eighty") :- !.
say(90, "ninety") :- !.

say(N, English) :-
between(10, 99, N),
Remainder is N mod 10,
Tens is N - Remainder,
say(Tens, TensEnglish),
say(Remainder, RemainderEnglish),
format(string(English), "~s-~s", [TensEnglish, RemainderEnglish]), !.

say(N, English) :- say(N, 100, 999, "hundred", English), !.
say(N, English) :- say(N, 1000, 999999, "thousand", English), !.
say(N, English) :- say(N, 1000000, 999999999, "million", English), !.
say(N, English) :- say(N, 1000000000, 999999999999, "billion", English).

say(Units, 0, Unit, English) :-
say(Units, UnitsEnglish),
format(string(English), "~s ~s", [UnitsEnglish, Unit]), !.
say(Units, Remainder, Unit, English) :-
say(Units, UnitsEnglish),
say(Remainder, RemainderEnglish),
format(string(English), "~s ~s ~s", [UnitsEnglish, Unit, RemainderEnglish]).

say(N, Low, High, Unit, English) :-
between(Low, High, N),
divmod(N, Low, Units, Remainder),
say(Units, Remainder, Unit, English).
67 changes: 67 additions & 0 deletions exercises/practice/say/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
1 change: 1 addition & 0 deletions exercises/practice/say/say.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
say(N, English).
83 changes: 83 additions & 0 deletions exercises/practice/say/say_tests.plt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
pending :-
current_prolog_flag(argv, ['--all'|_]).
pending :-
write('\nA TEST IS PENDING!\n'),
fail.

:- begin_tests(say).

test(zero, condition(true)) :-
say(0, English),
English == "zero".

test(one, condition(pending)) :-
say(1, English),
English == "one".

test(fourteen, condition(pending)) :-
say(14, English),
English == "fourteen".

test(twenty, condition(pending)) :-
say(20, English),
English == "twenty".

test(twenty_two, condition(pending)) :-
say(22, English),
English == "twenty-two".

test(thirty, condition(pending)) :-
say(30, English),
English == "thirty".

test(ninety_nine, condition(pending)) :-
say(99, English),
English == "ninety-nine".

test(one_hundred, condition(pending)) :-
say(100, English),
English == "one hundred".

test(one_hundred_twenty_three, condition(pending)) :-
say(123, English),
English == "one hundred twenty-three".

test(two_hundred, condition(pending)) :-
say(200, English),
English == "two hundred".

test(nine_hundred_ninety_nine, condition(pending)) :-
say(999, English),
English == "nine hundred ninety-nine".

test(one_thousand, condition(pending)) :-
say(1000, English),
English == "one thousand".

test(one_thousand_two_hundred_thirty_four, condition(pending)) :-
say(1234, English),
English == "one thousand two hundred thirty-four".

test(one_million, condition(pending)) :-
say(1000000, English),
English == "one million".

test(one_million_two_thousand_three_hundred_forty_five, condition(pending)) :-
say(1002345, English),
English == "one million two thousand three hundred forty-five".

test(one_billion, condition(pending)) :-
say(1000000000, English),
English == "one billion".

test(a_big_number, condition(pending)) :-
say(987654321123, English),
English == "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three".

test(numbers_below_zero_are_out_of_range, [fail, condition(pending)]) :-
say(-1, _).

test(numbers_above_999_999_999_999_are_out_of_range, [fail, condition(pending)]) :-
say(1000000000000, _).

:- end_tests(say).

0 comments on commit 0195e72

Please sign in to comment.