Skip to content

Commit d5ff396

Browse files
committed
[gleam] complete wordy
1 parent 864b0e8 commit d5ff396

File tree

7 files changed

+325
-0
lines changed

7 files changed

+325
-0
lines changed

gleam/wordy/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
build
4+
erl_crash.dump

gleam/wordy/HELP.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Help
2+
3+
## Running the tests
4+
5+
To run the tests, run the command `gleam test` from within the exercise directory.
6+
7+
## Submitting your solution
8+
9+
You can submit your solution using the `exercism submit src/wordy.gleam` command.
10+
This command will upload your solution to the Exercism website and print the solution page's URL.
11+
12+
It's possible to submit an incomplete solution which allows you to:
13+
14+
- See how others have completed the exercise
15+
- Request help from a mentor
16+
17+
## Need to get help?
18+
19+
If you'd like help solving the exercise, check the following pages:
20+
21+
- The [Gleam track's documentation](https://exercism.org/docs/tracks/gleam)
22+
- The [Gleam track's programming category on the forum](https://forum.exercism.org/c/programming/gleam)
23+
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
24+
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
25+
26+
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
27+
28+
To get help if you're having trouble, you can use one of the following resources:
29+
30+
- [gleam.run](https://gleam.run/documentation/) is the gleam official documentation.
31+
- [Discord](https://discord.gg/Fm8Pwmy) is the discord channel.
32+
- [StackOverflow](https://stackoverflow.com/questions/tagged/gleam) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

gleam/wordy/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Wordy
2+
3+
Welcome to Wordy on Exercism's Gleam Track.
4+
If you need help running the tests or submitting your code, check out `HELP.md`.
5+
6+
## Instructions
7+
8+
Parse and evaluate simple math word problems returning the answer as an integer.
9+
10+
## Iteration 0 — Numbers
11+
12+
Problems with no operations simply evaluate to the number given.
13+
14+
> What is 5?
15+
16+
Evaluates to 5.
17+
18+
## Iteration 1 — Addition
19+
20+
Add two numbers together.
21+
22+
> What is 5 plus 13?
23+
24+
Evaluates to 18.
25+
26+
Handle large numbers and negative numbers.
27+
28+
## Iteration 2 — Subtraction, Multiplication and Division
29+
30+
Now, perform the other three operations.
31+
32+
> What is 7 minus 5?
33+
34+
2
35+
36+
> What is 6 multiplied by 4?
37+
38+
24
39+
40+
> What is 25 divided by 5?
41+
42+
5
43+
44+
## Iteration 3 — Multiple Operations
45+
46+
Handle a set of operations, in sequence.
47+
48+
Since these are verbal word problems, evaluate the expression from left-to-right, _ignoring the typical order of operations._
49+
50+
> What is 5 plus 13 plus 6?
51+
52+
24
53+
54+
> What is 3 plus 2 multiplied by 3?
55+
56+
15 (i.e. not 9)
57+
58+
## Iteration 4 — Errors
59+
60+
The parser should reject:
61+
62+
- Unsupported operations ("What is 52 cubed?")
63+
- Non-math questions ("Who is the President of the United States")
64+
- Word problems with invalid syntax ("What is 1 plus plus 2?")
65+
66+
## Source
67+
68+
### Created by
69+
70+
- @natanaelsirqueira
71+
72+
### Based on
73+
74+
Inspired by one of the generated questions in the Extreme Startup game. - https://github.com/rchatley/extreme_startup

gleam/wordy/gleam.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name = "wordy"
2+
version = "0.1.0"
3+
4+
[dependencies]
5+
gleam_bitwise = "~> 1.2"
6+
gleam_otp = "~> 0.7 or ~> 1.0"
7+
gleam_stdlib = "~> 0.32 or ~> 1.0"
8+
simplifile = "~> 1.0"
9+
gleam_erlang = ">= 0.25.0 and < 1.0.0"
10+
11+
[dev-dependencies]
12+
exercism_test_runner = "~> 1.4"

gleam/wordy/manifest.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
6+
{ name = "exercism_test_runner", version = "1.8.0", build_tools = ["gleam"], requirements = ["argv", "gap", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_stdlib", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "B944D89A9D049897DF28C63D595D89CB54D8C407D06EFFCE4CDA8C3EC1C9F51E" },
7+
{ name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" },
8+
{ name = "gap", version = "1.1.3", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "6EF5E3B523FDFBC317E9EA28D5163EE04744A97C007106F90207569789612291" },
9+
{ name = "glance", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "1510D4A03C28880E62974389E5BF1A5A185036BA07392F1D769620706A9E042F" },
10+
{ name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" },
11+
{ name = "gleam_community_ansi", version = "1.4.1", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "4CD513FC62523053E62ED7BAC2F36136EC17D6A8942728250A9A00A15E340E4B" },
12+
{ name = "gleam_community_colour", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "795964217EBEDB3DA656F5EB8F67D7AD22872EB95182042D3E7AFEF32D3FD2FE" },
13+
{ name = "gleam_erlang", version = "0.27.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "DE468F676D71B313C6C8C5334425CFCF827837333F8AB47B64D8A6D7AA40185D" },
14+
{ name = "gleam_json", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "9063D14D25406326C0255BDA0021541E797D8A7A12573D849462CAFED459F6EB" },
15+
{ name = "gleam_otp", version = "0.12.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "BFACC1513410DF5A1617169A9CD7EA334973AC71D860A17574BA7B2EADD89A6F" },
16+
{ name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" },
17+
{ name = "glexer", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "BD477AD657C2B637FEF75F2405FAEFFA533F277A74EF1A5E17B55B1178C228FB" },
18+
{ name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" },
19+
{ name = "thoas", version = "1.2.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "E38697EDFFD6E91BD12CEA41B155115282630075C2A727E7A6B2947F5408B86A" },
20+
]
21+
22+
[requirements]
23+
exercism_test_runner = { version = "~> 1.4" }
24+
gleam_bitwise = { version = "~> 1.2" }
25+
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0" }
26+
gleam_otp = { version = "~> 0.7 or ~> 1.0" }
27+
gleam_stdlib = { version = "~> 0.32 or ~> 1.0" }
28+
simplifile = { version = "~> 1.0" }

gleam/wordy/src/wordy.gleam

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import gleam/bool
2+
import gleam/int
3+
import gleam/list
4+
import gleam/regex
5+
import gleam/string
6+
7+
pub type Error {
8+
SyntaxError
9+
UnknownOperation
10+
ImpossibleOperation
11+
}
12+
13+
pub fn answer(question: String) -> Result(Int, Error) {
14+
use <- bool.guard(
15+
string.starts_with(question, "Who") || string.ends_with(question, "cubed?"),
16+
Error(UnknownOperation),
17+
)
18+
19+
let assert Ok(re) =
20+
regex.from_string(
21+
"^What is (-?\\d+)( (plus|minus|multiplied by|divided by) (-?\\d+))*\\?$",
22+
)
23+
24+
use <- bool.guard(!regex.check(re, question), Error(SyntaxError))
25+
26+
question
27+
|> string.replace("What is", "plus")
28+
|> string.replace(" by", "")
29+
|> string.drop_right(1)
30+
|> string.split(" ")
31+
|> list.sized_chunk(2)
32+
|> list.try_fold(0, fn(res, pair) {
33+
let assert [op, num_str] = pair
34+
let assert Ok(num) = int.parse(num_str)
35+
apply(res, num, op)
36+
})
37+
}
38+
39+
fn apply(a: Int, b: Int, op: String) -> Result(Int, Error) {
40+
case op {
41+
"plus" -> Ok(a + b)
42+
"minus" -> Ok(a - b)
43+
"multiplied" -> Ok(a * b)
44+
"divided" if b == 0 -> Error(ImpossibleOperation)
45+
"divided" -> Ok(a / b)
46+
_ -> Error(SyntaxError)
47+
}
48+
}

gleam/wordy/test/wordy_test.gleam

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import exercism/should
2+
import exercism/test_runner
3+
import wordy.{ImpossibleOperation, SyntaxError, UnknownOperation}
4+
5+
pub fn main() {
6+
test_runner.main()
7+
}
8+
9+
pub fn just_a_number_test() {
10+
wordy.answer("What is 5?")
11+
|> should.equal(Ok(5))
12+
}
13+
14+
pub fn addition_test() {
15+
wordy.answer("What is 1 plus 1?")
16+
|> should.equal(Ok(2))
17+
}
18+
19+
pub fn more_addition_test() {
20+
wordy.answer("What is 53 plus 2?")
21+
|> should.equal(Ok(55))
22+
}
23+
24+
pub fn addition_with_negative_numbers_test() {
25+
wordy.answer("What is -1 plus -10?")
26+
|> should.equal(Ok(-11))
27+
}
28+
29+
pub fn large_addition_test() {
30+
wordy.answer("What is 123 plus 45678?")
31+
|> should.equal(Ok(45_801))
32+
}
33+
34+
pub fn subtraction_test() {
35+
wordy.answer("What is 4 minus -12?")
36+
|> should.equal(Ok(16))
37+
}
38+
39+
pub fn multiplication_test() {
40+
wordy.answer("What is -3 multiplied by 25?")
41+
|> should.equal(Ok(-75))
42+
}
43+
44+
pub fn division_test() {
45+
wordy.answer("What is 33 divided by -3?")
46+
|> should.equal(Ok(-11))
47+
}
48+
49+
pub fn multiple_additions_test() {
50+
wordy.answer("What is 1 plus 1 plus 1?")
51+
|> should.equal(Ok(3))
52+
}
53+
54+
pub fn addition_and_subtraction_test() {
55+
wordy.answer("What is 1 plus 5 minus -2?")
56+
|> should.equal(Ok(8))
57+
}
58+
59+
pub fn multiple_subtraction_test() {
60+
wordy.answer("What is 20 minus 4 minus 13?")
61+
|> should.equal(Ok(3))
62+
}
63+
64+
pub fn subtraction_then_addition_test() {
65+
wordy.answer("What is 17 minus 6 plus 3?")
66+
|> should.equal(Ok(14))
67+
}
68+
69+
pub fn multiple_multiplication_test() {
70+
wordy.answer("What is 2 multiplied by -2 multiplied by 3?")
71+
|> should.equal(Ok(-12))
72+
}
73+
74+
pub fn addition_and_multiplication_test() {
75+
wordy.answer("What is -3 plus 7 multiplied by -2?")
76+
|> should.equal(Ok(-8))
77+
}
78+
79+
pub fn multiple_division_test() {
80+
wordy.answer("What is -12 divided by 2 divided by -3?")
81+
|> should.equal(Ok(2))
82+
}
83+
84+
pub fn unknown_operation_test() {
85+
wordy.answer("What is 52 cubed?")
86+
|> should.equal(Error(UnknownOperation))
87+
}
88+
89+
pub fn non_math_question_test() {
90+
wordy.answer("Who is the President of the United States?")
91+
|> should.equal(Error(UnknownOperation))
92+
}
93+
94+
pub fn reject_problem_missing_an_operand_test() {
95+
wordy.answer("What is 1 plus?")
96+
|> should.equal(Error(SyntaxError))
97+
}
98+
99+
pub fn reject_problem_with_no_operands_or_operators_test() {
100+
wordy.answer("What is?")
101+
|> should.equal(Error(SyntaxError))
102+
}
103+
104+
pub fn reject_two_operations_in_a_row_test() {
105+
wordy.answer("What is 1 plus plus 2?")
106+
|> should.equal(Error(SyntaxError))
107+
}
108+
109+
pub fn reject_two_numbers_in_a_row_test() {
110+
wordy.answer("What is 1 plus 2 1?")
111+
|> should.equal(Error(SyntaxError))
112+
}
113+
114+
pub fn reject_postfix_notation_test() {
115+
wordy.answer("What is 1 2 plus?")
116+
|> should.equal(Error(SyntaxError))
117+
}
118+
119+
pub fn reject_prefix_notation_test() {
120+
wordy.answer("What is plus 1 2?")
121+
|> should.equal(Error(SyntaxError))
122+
}
123+
124+
pub fn reject_division_by_zero_test() {
125+
wordy.answer("What is 1 divided by 0?")
126+
|> should.equal(Error(ImpossibleOperation))
127+
}

0 commit comments

Comments
 (0)