Skip to content

Commit 61a50fc

Browse files
authored
Add wordy (#153)
1 parent 2a3c610 commit 61a50fc

9 files changed

Lines changed: 361 additions & 0 deletions

File tree

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,14 @@
850850
"prerequisites": [],
851851
"difficulty": 6
852852
},
853+
{
854+
"slug": "wordy",
855+
"name": "Wordy",
856+
"uuid": "c4112228-adec-4109-a9aa-5bd366c1e658",
857+
"practices": [],
858+
"prerequisites": [],
859+
"difficulty": 6
860+
},
853861
{
854862
"slug": "book-store",
855863
"name": "Book Store",

exercises/practice/wordy/.busted

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
return {
2+
default = {
3+
ROOT = { '.' }
4+
}
5+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Instructions
2+
3+
Parse and evaluate simple math word problems returning the answer as an integer.
4+
5+
## Iteration 0 — Numbers
6+
7+
Problems with no operations simply evaluate to the number given.
8+
9+
> What is 5?
10+
11+
Evaluates to 5.
12+
13+
## Iteration 1 — Addition
14+
15+
Add two numbers together.
16+
17+
> What is 5 plus 13?
18+
19+
Evaluates to 18.
20+
21+
Handle large numbers and negative numbers.
22+
23+
## Iteration 2 — Subtraction, Multiplication and Division
24+
25+
Now, perform the other three operations.
26+
27+
> What is 7 minus 5?
28+
29+
2
30+
31+
> What is 6 multiplied by 4?
32+
33+
24
34+
35+
> What is 25 divided by 5?
36+
37+
5
38+
39+
## Iteration 3 — Multiple Operations
40+
41+
Handle a set of operations, in sequence.
42+
43+
Since these are verbal word problems, evaluate the expression from left-to-right, _ignoring the typical order of operations._
44+
45+
> What is 5 plus 13 plus 6?
46+
47+
24
48+
49+
> What is 3 plus 2 multiplied by 3?
50+
51+
15 (i.e. not 9)
52+
53+
## Iteration 4 — Errors
54+
55+
The parser should reject:
56+
57+
- Unsupported operations ("What is 52 cubed?")
58+
- Non-math questions ("Who is the President of the United States")
59+
- Word problems with invalid syntax ("What is 1 plus plus 2?")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"glennj"
4+
],
5+
"files": {
6+
"solution": [
7+
"wordy.moon"
8+
],
9+
"test": [
10+
"wordy_spec.moon"
11+
],
12+
"example": [
13+
".meta/example.moon"
14+
]
15+
},
16+
"blurb": "Parse and evaluate simple math word problems returning the answer as an integer.",
17+
"source": "Inspired by one of the generated questions in the Extreme Startup game.",
18+
"source_url": "https://github.com/rchatley/extreme_startup"
19+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
re = require 're' -- https://www.inf.puc-rio.br/~roberto/lpeg/re.html
2+
3+
local err, evaluate
4+
5+
answer = (input) ->
6+
wordy = re.compile [[
7+
wordy <- 'What is ' {| expr |} '?'
8+
expr <- { num } (s {~ op ~} s { num })*
9+
num <- '-'? %d+
10+
op <- 'plus' -> '+'
11+
/ 'minus' -> '-'
12+
/ 'multiplied by' -> '*'
13+
/ 'divided by' -> '/'
14+
s <- %s+
15+
]]
16+
17+
tokens = re.match input, wordy
18+
if tokens
19+
evaluate tokens
20+
else
21+
err input
22+
23+
evaluate = (tokens) ->
24+
result = tonumber tokens[1]
25+
for i = 2, #tokens, 2
26+
addend = tonumber tokens[i+1]
27+
result = switch tokens[i]
28+
when '+' then result + addend
29+
when '-' then result - addend
30+
when '*' then result * addend
31+
when '/' then result // addend
32+
result
33+
34+
err = (input) ->
35+
refute = (cond, msg) -> assert not cond, msg
36+
37+
-- figure out the appropriate error message
38+
refute input\match('^What is *%?$'), 'syntax error'
39+
assert input\match('^What is .+%?$'), 'unknown operation'
40+
syntax_errs = re.compile [[
41+
x <- s (op s op / num s num / op '?')
42+
op <- 'plus' / 'minus' / 'multiplied by' / 'divided by'
43+
num <- '-'? %d+
44+
s <- %s+
45+
]]
46+
refute re.find(input, syntax_errs), 'syntax error'
47+
error 'unknown operation'
48+
49+
{ :answer }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
module_name: 'Wordy',
3+
4+
generate_test: (case, level) ->
5+
lines = if type(case.expected) == 'table'
6+
{
7+
"fn = -> Wordy.#{case.property} #{quote case.input.question}",
8+
"assert.has.error fn, #{quote case.expected.error}"
9+
}
10+
else
11+
{
12+
"result = Wordy.#{case.property} #{quote case.input.question}",
13+
"assert.are.equal #{case.expected}, result"
14+
}
15+
table.concat [indent line, level for line in *lines], '\n'
16+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
[88bf4b28-0de3-4883-93c7-db1b14aa806e]
13+
description = "just a number"
14+
15+
[18983214-1dfc-4ebd-ac77-c110dde699ce]
16+
description = "just a zero"
17+
18+
[607c08ee-2241-4288-916d-dae5455c87e6]
19+
description = "just a negative number"
20+
21+
[bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0]
22+
description = "addition"
23+
24+
[bb9f2082-171c-46ad-ad4e-c3f72087c1b5]
25+
description = "addition with a left hand zero"
26+
27+
[6fa05f17-405a-4742-80ae-5d1a8edb0d5d]
28+
description = "addition with a right hand zero"
29+
30+
[79e49e06-c5ae-40aa-a352-7a3a01f70015]
31+
description = "more addition"
32+
33+
[b345dbe0-f733-44e1-863c-5ae3568f3803]
34+
description = "addition with negative numbers"
35+
36+
[cd070f39-c4cc-45c4-97fb-1be5e5846f87]
37+
description = "large addition"
38+
39+
[0d86474a-cd93-4649-a4fa-f6109a011191]
40+
description = "subtraction"
41+
42+
[30bc8395-5500-4712-a0cf-1d788a529be5]
43+
description = "multiplication"
44+
45+
[34c36b08-8605-4217-bb57-9a01472c427f]
46+
description = "division"
47+
48+
[da6d2ce4-fb94-4d26-8f5f-b078adad0596]
49+
description = "multiple additions"
50+
51+
[7fd74c50-9911-4597-be09-8de7f2fea2bb]
52+
description = "addition and subtraction"
53+
54+
[b120ffd5-bad6-4e22-81c8-5512e8faf905]
55+
description = "multiple subtraction"
56+
57+
[4f4a5749-ef0c-4f60-841f-abcfaf05d2ae]
58+
description = "subtraction then addition"
59+
60+
[312d908c-f68f-42c9-aa75-961623cc033f]
61+
description = "multiple multiplication"
62+
63+
[38e33587-8940-4cc1-bc28-bfd7e3966276]
64+
description = "addition and multiplication"
65+
66+
[3c854f97-9311-46e8-b574-92b60d17d394]
67+
description = "multiple division"
68+
69+
[3ad3e433-8af7-41ec-aa9b-97b42ab49357]
70+
description = "unknown operation"
71+
72+
[8a7e85a8-9e7b-4d46-868f-6d759f4648f8]
73+
description = "Non math question"
74+
75+
[42d78b5f-dbd7-4cdb-8b30-00f794bb24cf]
76+
description = "reject problem missing an operand"
77+
78+
[c2c3cbfc-1a72-42f2-b597-246e617e66f5]
79+
description = "reject problem with no operands or operators"
80+
81+
[4b3df66d-6ed5-4c95-a0a1-d38891fbdab6]
82+
description = "reject two operations in a row"
83+
84+
[6abd7a50-75b4-4665-aa33-2030fd08bab1]
85+
description = "reject two numbers in a row"
86+
87+
[10a56c22-e0aa-405f-b1d2-c642d9c4c9de]
88+
description = "reject postfix notation"
89+
90+
[0035bc63-ac43-4bb5-ad6d-e8651b7d954e]
91+
description = "reject prefix notation"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
answer: (question) ->
3+
error 'Implement me'
4+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Wordy = require 'wordy'
2+
3+
describe 'wordy', ->
4+
it 'just a number', ->
5+
result = Wordy.answer 'What is 5?'
6+
assert.are.equal 5, result
7+
8+
pending 'just a zero', ->
9+
result = Wordy.answer 'What is 0?'
10+
assert.are.equal 0, result
11+
12+
pending 'just a negative number', ->
13+
result = Wordy.answer 'What is -123?'
14+
assert.are.equal -123, result
15+
16+
pending 'addition', ->
17+
result = Wordy.answer 'What is 1 plus 1?'
18+
assert.are.equal 2, result
19+
20+
pending 'addition with a left hand zero', ->
21+
result = Wordy.answer 'What is 0 plus 2?'
22+
assert.are.equal 2, result
23+
24+
pending 'addition with a right hand zero', ->
25+
result = Wordy.answer 'What is 3 plus 0?'
26+
assert.are.equal 3, result
27+
28+
pending 'more addition', ->
29+
result = Wordy.answer 'What is 53 plus 2?'
30+
assert.are.equal 55, result
31+
32+
pending 'addition with negative numbers', ->
33+
result = Wordy.answer 'What is -1 plus -10?'
34+
assert.are.equal -11, result
35+
36+
pending 'large addition', ->
37+
result = Wordy.answer 'What is 123 plus 45678?'
38+
assert.are.equal 45801, result
39+
40+
pending 'subtraction', ->
41+
result = Wordy.answer 'What is 4 minus -12?'
42+
assert.are.equal 16, result
43+
44+
pending 'multiplication', ->
45+
result = Wordy.answer 'What is -3 multiplied by 25?'
46+
assert.are.equal -75, result
47+
48+
pending 'division', ->
49+
result = Wordy.answer 'What is 33 divided by -3?'
50+
assert.are.equal -11, result
51+
52+
pending 'multiple additions', ->
53+
result = Wordy.answer 'What is 1 plus 1 plus 1?'
54+
assert.are.equal 3, result
55+
56+
pending 'addition and subtraction', ->
57+
result = Wordy.answer 'What is 1 plus 5 minus -2?'
58+
assert.are.equal 8, result
59+
60+
pending 'multiple subtraction', ->
61+
result = Wordy.answer 'What is 20 minus 4 minus 13?'
62+
assert.are.equal 3, result
63+
64+
pending 'subtraction then addition', ->
65+
result = Wordy.answer 'What is 17 minus 6 plus 3?'
66+
assert.are.equal 14, result
67+
68+
pending 'multiple multiplication', ->
69+
result = Wordy.answer 'What is 2 multiplied by -2 multiplied by 3?'
70+
assert.are.equal -12, result
71+
72+
pending 'addition and multiplication', ->
73+
result = Wordy.answer 'What is -3 plus 7 multiplied by -2?'
74+
assert.are.equal -8, result
75+
76+
pending 'multiple division', ->
77+
result = Wordy.answer 'What is -12 divided by 2 divided by -3?'
78+
assert.are.equal 2, result
79+
80+
pending 'unknown operation', ->
81+
fn = -> Wordy.answer 'What is 52 cubed?'
82+
assert.has.error fn, 'unknown operation'
83+
84+
pending 'Non math question', ->
85+
fn = -> Wordy.answer 'Who is the President of the United States?'
86+
assert.has.error fn, 'unknown operation'
87+
88+
pending 'reject problem missing an operand', ->
89+
fn = -> Wordy.answer 'What is 1 plus?'
90+
assert.has.error fn, 'syntax error'
91+
92+
pending 'reject problem with no operands or operators', ->
93+
fn = -> Wordy.answer 'What is?'
94+
assert.has.error fn, 'syntax error'
95+
96+
pending 'reject two operations in a row', ->
97+
fn = -> Wordy.answer 'What is 1 plus plus 2?'
98+
assert.has.error fn, 'syntax error'
99+
100+
pending 'reject two numbers in a row', ->
101+
fn = -> Wordy.answer 'What is 1 plus 2 1?'
102+
assert.has.error fn, 'syntax error'
103+
104+
pending 'reject postfix notation', ->
105+
fn = -> Wordy.answer 'What is 1 2 plus?'
106+
assert.has.error fn, 'syntax error'
107+
108+
pending 'reject prefix notation', ->
109+
fn = -> Wordy.answer 'What is plus 1 2?'
110+
assert.has.error fn, 'syntax error'

0 commit comments

Comments
 (0)