Skip to content

Commit 9ffbde3

Browse files
authored
Add practice exercise: say (#133)
1 parent 1a146b2 commit 9ffbde3

File tree

11 files changed

+383
-0
lines changed

11 files changed

+383
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,14 @@
426426
"prerequisites": [],
427427
"difficulty": 8
428428
},
429+
{
430+
"slug": "say",
431+
"name": "Say",
432+
"uuid": "5b643efe-e63b-4598-95f8-a4cb319107de",
433+
"practices": [],
434+
"prerequisites": [],
435+
"difficulty": 8
436+
},
429437
{
430438
"slug": "scrabble-score",
431439
"name": "Scrabble Score",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Instructions
2+
3+
Given a number, your task is to express it in English words exactly as your friend should say it out loud.
4+
Yaʻqūb expects to use numbers from 0 up to 999,999,999,999.
5+
6+
Examples:
7+
8+
- 0 → zero
9+
- 1 → one
10+
- 12 → twelve
11+
- 123 → one hundred twenty-three
12+
- 1,234 → one thousand two hundred thirty-four
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Introduction
2+
3+
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.
4+
To keep things moving, each customer takes a numbered ticket when they arrive.
5+
6+
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.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"jimmytty"
4+
],
5+
"files": {
6+
"solution": [
7+
"say.sql"
8+
],
9+
"test": [
10+
"say_test.sql"
11+
],
12+
"example": [
13+
".meta/example.sql"
14+
]
15+
},
16+
"blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.",
17+
"source": "A variation on the JavaRanch CattleDrive, Assignment 4",
18+
"source_url": "https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804"
19+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
UPDATE say SET result = 'zero' WHERE number = 0;
2+
3+
UPDATE say
4+
SET error = 'input out of range'
5+
WHERE number < 0
6+
OR number >= 1e12
7+
;
8+
9+
DROP TABLE IF EXISTS dict;
10+
CREATE TEMPORARY TABLE dict (
11+
digits INTEGER PRIMARY KEY,
12+
words TEXT NOT NULL
13+
);
14+
INSERT INTO dict (digits, words)
15+
VALUES ( 0, 'zero' ),
16+
( 1, 'one' ),
17+
( 2, 'two' ),
18+
( 3, 'three' ),
19+
( 4, 'four' ),
20+
( 5, 'five' ),
21+
( 6, 'six' ),
22+
( 7, 'seven' ),
23+
( 8, 'eight' ),
24+
( 9, 'nine' ),
25+
(10, 'ten' ),
26+
(11, 'eleven' ),
27+
(12, 'twelve' ),
28+
(13, 'thirteen' ),
29+
(14, 'fourteen' ),
30+
(15, 'fifteen' ),
31+
(16, 'sixteen' ),
32+
(17, 'seventeen'),
33+
(18, 'eighteen' ),
34+
(19, 'nineteen' ),
35+
(20, 'twenty' ),
36+
(30, 'thirty' ),
37+
(40, 'forty' ),
38+
(50, 'fifty' ),
39+
(60, 'sixty' ),
40+
(70, 'seventy' ),
41+
(80, 'eighty' ),
42+
(90, 'ninety' );
43+
WITH dozens (jarray) AS (
44+
SELECT (
45+
WITH RECURSIVE rcte (base, unit, dozen, string) AS (
46+
VALUES (digits, 1, NULL, NULL)
47+
UNION ALL
48+
SELECT digits,
49+
unit + 1,
50+
base + unit,
51+
PRINTF(
52+
'%s-%s',
53+
(SELECT words FROM dict WHERE digits = base),
54+
(SELECT words FROM dict WHERE digits = unit))
55+
FROM rcte
56+
WHERE unit < 10
57+
)
58+
SELECT JSON_GROUP_ARRAY(JSON_ARRAY(dozen, string))
59+
FROM rcte
60+
WHERE dozen NOT NULL
61+
)
62+
FROM dict
63+
WHERE digits BETWEEN 20 AND 90
64+
)
65+
INSERT INTO dict (digits, words)
66+
SELECT JSON_EXTRACT(j.VALUE, '$[0]'), JSON_EXTRACT(j.VALUE, '$[1]')
67+
FROM dozens, JSON_EACH(jarray) j;
68+
INSERT INTO dict
69+
SELECT value * 100,
70+
(SELECT words FROM dict WHERE digits = VALUE) || ' hundred'
71+
FROM GENERATE_SERIES(1, 9);
72+
73+
DROP TABLE IF EXISTS positions;
74+
CREATE TEMPORARY TABLE positions (
75+
pos INTEGER PRIMARY KEY,
76+
words TEXT NOT NULL
77+
);
78+
INSERT INTO positions (pos, words)
79+
VALUES ( 2, 'thousand' ),
80+
( 3, 'million' ),
81+
( 4, 'billion' ),
82+
( 5, 'trillion' ),
83+
( 6, 'quadrillion' ),
84+
( 7, 'quintillion' ),
85+
( 8, 'sextillion' ),
86+
( 9, 'septillion' ),
87+
(10, 'octillion' ),
88+
(11, 'nonillion' ),
89+
(12, 'decillion' ),
90+
(13, 'undecillion' ),
91+
(14, 'duodecillion' ),
92+
(15, 'tredecillion' ),
93+
(16, 'quattuordecillion'),
94+
(17, 'quindecillion' ),
95+
(18, 'sexdecillion' ),
96+
(19, 'septendecillion' ),
97+
(20, 'octodecillion' ),
98+
(21, 'novemdecillion' ),
99+
(22, 'vigintillion' );
100+
101+
UPDATE say
102+
SET result = (
103+
WITH
104+
decompositor (num, thousands, thpos) AS (
105+
WITH RECURSIVE decompositor (num, thousands, thpos) AS (
106+
VALUES (number, NULL, 0)
107+
UNION ALL
108+
SELECT num / 1000,
109+
JSON_ARRAY( num % 1000 - num % 100, (num % 1000) % 100 ),
110+
thpos + 1
111+
FROM decompositor
112+
WHERE num > 0
113+
)
114+
SELECT * FROM decompositor
115+
),
116+
to_strings (thpos, hundred, dozen, pos_str) AS (
117+
SELECT
118+
thpos,
119+
(
120+
SELECT words
121+
FROM dict
122+
WHERE digits = NULLIF(JSON_EXTRACT(thousands, '$[0]'), 0)
123+
),
124+
(
125+
SELECT words
126+
FROM dict
127+
WHERE digits = NULLIF(JSON_EXTRACT(thousands, '$[1]'), 0 )
128+
),
129+
IIF(
130+
JSON_EXTRACT(thousands, '$[0]') +
131+
JSON_EXTRACT(thousands, '$[1]') > 0,
132+
(SELECT words FROM positions WHERE pos = thpos),
133+
NULL
134+
)
135+
FROM decompositor
136+
WHERE thpos > 0
137+
),
138+
to_format (thpos, string) AS (
139+
SELECT thpos, TRIM(PRINTF('%s %s %s', hundred, dozen, pos_str))
140+
FROM to_strings
141+
ORDER BY thpos DESC
142+
)
143+
SELECT TRIM(GROUP_CONCAT(string, ' ')) FROM to_format
144+
)
145+
WHERE error IS NULL
146+
AND number > 0
147+
;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[5d22a120-ba0c-428c-bd25-8682235d83e8]
13+
description = "zero"
14+
15+
[9b5eed77-dbf6-439d-b920-3f7eb58928f6]
16+
description = "one"
17+
18+
[7c499be1-612e-4096-a5e1-43b2f719406d]
19+
description = "fourteen"
20+
21+
[f541dd8e-f070-4329-92b4-b7ce2fcf06b4]
22+
description = "twenty"
23+
24+
[d78601eb-4a84-4bfa-bf0e-665aeb8abe94]
25+
description = "twenty-two"
26+
27+
[f010d4ca-12c9-44e9-803a-27789841adb1]
28+
description = "thirty"
29+
30+
[738ce12d-ee5c-4dfb-ad26-534753a98327]
31+
description = "ninety-nine"
32+
33+
[e417d452-129e-4056-bd5b-6eb1df334dce]
34+
description = "one hundred"
35+
36+
[d6924f30-80ba-4597-acf6-ea3f16269da8]
37+
description = "one hundred twenty-three"
38+
39+
[2f061132-54bc-4fd4-b5df-0a3b778959b9]
40+
description = "two hundred"
41+
42+
[feed6627-5387-4d38-9692-87c0dbc55c33]
43+
description = "nine hundred ninety-nine"
44+
45+
[3d83da89-a372-46d3-b10d-de0c792432b3]
46+
description = "one thousand"
47+
48+
[865af898-1d5b-495f-8ff0-2f06d3c73709]
49+
description = "one thousand two hundred thirty-four"
50+
51+
[b6a3f442-266e-47a3-835d-7f8a35f6cf7f]
52+
description = "one million"
53+
54+
[2cea9303-e77e-4212-b8ff-c39f1978fc70]
55+
description = "one million two thousand three hundred forty-five"
56+
57+
[3e240eeb-f564-4b80-9421-db123f66a38f]
58+
description = "one billion"
59+
60+
[9a43fed1-c875-4710-8286-5065d73b8a9e]
61+
description = "a big number"
62+
63+
[49a6a17b-084e-423e-994d-a87c0ecc05ef]
64+
description = "numbers below zero are out of range"
65+
66+
[4d6492eb-5853-4d16-9d34-b0f61b261fd9]
67+
description = "numbers above 999,999,999,999 are out of range"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
DROP TABLE IF EXISTS say;
2+
CREATE TABLE say (
3+
number INTEGER NOT NULL,
4+
result TEXT,
5+
error TEXT
6+
);
7+
8+
.mode csv
9+
.import ./data.csv say
10+
11+
UPDATE say SET result = NULL, error = NULL;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
DROP TABLE IF EXISTS tests;
2+
CREATE TABLE IF NOT EXISTS tests (
3+
-- uuid and description are taken from the test.toml file
4+
uuid TEXT PRIMARY KEY,
5+
description TEXT NOT NULL,
6+
-- The following section is needed by the online test-runner
7+
status TEXT DEFAULT 'fail',
8+
message TEXT,
9+
output TEXT,
10+
test_code TEXT,
11+
task_id INTEGER DEFAULT NULL,
12+
-- Here are columns for the actual tests
13+
number INTEGER NOT NULL,
14+
expected_result TEXT,
15+
expected_error TEXT
16+
);
17+
18+
INSERT INTO tests (uuid, description, number, expected_result, expected_error)
19+
VALUES
20+
('5d22a120-ba0c-428c-bd25-8682235d83e8', 'zero', 0, 'zero', NULL),
21+
('9b5eed77-dbf6-439d-b920-3f7eb58928f6', 'one', 1, 'one', NULL),
22+
('7c499be1-612e-4096-a5e1-43b2f719406d', 'fourteen', 14, 'fourteen', NULL),
23+
('f541dd8e-f070-4329-92b4-b7ce2fcf06b4', 'twenty', 20, 'twenty', NULL),
24+
('d78601eb-4a84-4bfa-bf0e-665aeb8abe94', 'twenty-two', 22, 'twenty-two', NULL),
25+
('f010d4ca-12c9-44e9-803a-27789841adb1', 'thirty', 30, 'thirty', NULL),
26+
('738ce12d-ee5c-4dfb-ad26-534753a98327', 'ninety-nine', 99, 'ninety-nine', NULL),
27+
('e417d452-129e-4056-bd5b-6eb1df334dce', 'one hundred', 100, 'one hundred', NULL),
28+
('d6924f30-80ba-4597-acf6-ea3f16269da8', 'one hundred twenty-three', 123, 'one hundred twenty-three', NULL),
29+
('2f061132-54bc-4fd4-b5df-0a3b778959b9', 'two hundred', 200, 'two hundred', NULL),
30+
('feed6627-5387-4d38-9692-87c0dbc55c33', 'nine hundred ninety-nine', 999, 'nine hundred ninety-nine', NULL),
31+
('3d83da89-a372-46d3-b10d-de0c792432b3', 'one thousand', 1000, 'one thousand', NULL),
32+
('865af898-1d5b-495f-8ff0-2f06d3c73709', 'one thousand two hundred thirty-four', 1234, 'one thousand two hundred thirty-four', NULL),
33+
('b6a3f442-266e-47a3-835d-7f8a35f6cf7f', 'one million', 1000000, 'one million', NULL),
34+
('2cea9303-e77e-4212-b8ff-c39f1978fc70', 'one million two thousand three hundred forty-five', 1002345, 'one million two thousand three hundred forty-five', NULL),
35+
('3e240eeb-f564-4b80-9421-db123f66a38f', 'one billion', 1000000000, 'one billion', NULL),
36+
('9a43fed1-c875-4710-8286-5065d73b8a9e', 'a big number', 987654321123, 'nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three', NULL),
37+
('49a6a17b-084e-423e-994d-a87c0ecc05ef', 'numbers below zero are out of range', -1, NULL, 'input out of range'),
38+
('4d6492eb-5853-4d16-9d34-b0f61b261fd9', 'numbers above 999,999,999,999 are out of range', 1000000000000, NULL, 'input out of range');

exercises/practice/say/data.csv

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
0,,
2+
1,,
3+
14,,
4+
20,,
5+
22,,
6+
30,,
7+
99,,
8+
100,,
9+
123,,
10+
200,,
11+
999,,
12+
1000,,
13+
1234,,
14+
1000000,,
15+
1002345,,
16+
1000000000,,
17+
987654321123,,
18+
-1,,
19+
1000000000000,,

exercises/practice/say/say.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Schema:
2+
-- CREATE TABLE say (
3+
-- number INTEGER NOT NULL,
4+
-- result TEXT,
5+
-- error TEXT
6+
-- );
7+
--
8+
-- Task: update the say table and set the result or the error columns based on the number.

0 commit comments

Comments
 (0)