Skip to content

Commit 4d26c02

Browse files
committed
[gleam] complete rectangles
1 parent bc2cded commit 4d26c02

File tree

7 files changed

+359
-0
lines changed

7 files changed

+359
-0
lines changed

gleam/rectangles/.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.beam
2+
*.ez
3+
build
4+
erl_crash.dump

gleam/rectangles/HELP.md

+32
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/rectangles.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/rectangles/README.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Rectangles
2+
3+
Welcome to Rectangles 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+
Count the rectangles in an ASCII diagram like the one below.
9+
10+
```text
11+
+--+
12+
++ |
13+
+-++--+
14+
| | |
15+
+--+--+
16+
```
17+
18+
The above diagram contains these 6 rectangles:
19+
20+
```text
21+
22+
23+
+-----+
24+
| |
25+
+-----+
26+
```
27+
28+
```text
29+
+--+
30+
| |
31+
| |
32+
| |
33+
+--+
34+
```
35+
36+
```text
37+
+--+
38+
| |
39+
+--+
40+
41+
42+
```
43+
44+
```text
45+
46+
47+
+--+
48+
| |
49+
+--+
50+
```
51+
52+
```text
53+
54+
55+
+--+
56+
| |
57+
+--+
58+
```
59+
60+
```text
61+
62+
++
63+
++
64+
65+
66+
```
67+
68+
You may assume that the input is always a proper rectangle (i.e. the length of every line equals the length of the first line).
69+
70+
## Source
71+
72+
### Created by
73+
74+
- @jiegillet

gleam/rectangles/gleam.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name = "rectangles"
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/rectangles/manifest.toml

+28
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/rectangles/src/rectangles.gleam

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import gleam/bool
2+
import gleam/int
3+
import gleam/list
4+
import gleam/string
5+
6+
type Point {
7+
Point(char: String, x: Int, y: Int)
8+
}
9+
10+
pub fn rectangles(input: String) -> Int {
11+
let points =
12+
input
13+
|> string.split("\n")
14+
|> list.index_map(fn(line, y) {
15+
line
16+
|> string.to_graphemes
17+
|> list.index_map(fn(char, x) { Point(char, x, y) })
18+
})
19+
|> list.flatten
20+
21+
points
22+
|> list.filter(fn(p) { p.char == "+" })
23+
|> list.combinations(4)
24+
|> list.map(list.sort(_, fn(a, b) { int.compare(a.x, b.x) }))
25+
|> list.filter(fn(vertices) {
26+
let assert [tl, bl, tr, br] = vertices
27+
use <- bool.guard(
28+
tl.y != tr.y || tr.x != br.x || br.y != bl.y || bl.x != tl.x,
29+
False,
30+
)
31+
32+
let horizontal =
33+
list.filter(points, fn(p) {
34+
{ p.y == tl.y || p.y == bl.y } && tl.x < p.x && p.x < tr.x
35+
})
36+
let vertical =
37+
list.filter(points, fn(p) {
38+
{ p.x == tl.x || p.x == tr.x } && tl.y < p.y && p.y < bl.y
39+
})
40+
41+
list.all(horizontal, fn(p) { p.char == "-" || p.char == "+" })
42+
&& list.all(vertical, fn(p) { p.char == "|" || p.char == "+" })
43+
})
44+
|> list.length
45+
}
+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import exercism/should
2+
import exercism/test_runner
3+
import rectangles
4+
5+
pub fn main() {
6+
test_runner.main()
7+
}
8+
9+
pub fn no_rows_test() {
10+
rectangles.rectangles("")
11+
|> should.equal(0)
12+
}
13+
14+
pub fn no_columns_test() {
15+
rectangles.rectangles(
16+
"
17+
18+
",
19+
)
20+
|> should.equal(0)
21+
}
22+
23+
pub fn no_rectangles_test() {
24+
rectangles.rectangles(" ")
25+
|> should.equal(0)
26+
}
27+
28+
pub fn one_rectangle_test() {
29+
rectangles.rectangles(
30+
"
31+
+-+
32+
| |
33+
+-+
34+
",
35+
)
36+
|> should.equal(1)
37+
}
38+
39+
pub fn two_rectangles_without_shared_parts_test() {
40+
rectangles.rectangles(
41+
"
42+
+-+
43+
| |
44+
+-+-+
45+
| |
46+
+-+
47+
",
48+
)
49+
|> should.equal(2)
50+
}
51+
52+
pub fn five_rectangles_with_shared_parts_test() {
53+
rectangles.rectangles(
54+
"
55+
+-+
56+
| |
57+
+-+-+
58+
| | |
59+
+-+-+
60+
",
61+
)
62+
|> should.equal(5)
63+
}
64+
65+
pub fn rectangle_of_height_1_is_counted_test() {
66+
rectangles.rectangles(
67+
"
68+
+--+
69+
+--+
70+
",
71+
)
72+
|> should.equal(1)
73+
}
74+
75+
pub fn rectangle_of_width_1_is_counted_test() {
76+
rectangles.rectangles(
77+
"
78+
++
79+
||
80+
++
81+
",
82+
)
83+
|> should.equal(1)
84+
}
85+
86+
pub fn one_by_one_square_is_counted_test() {
87+
rectangles.rectangles(
88+
"
89+
++
90+
++
91+
",
92+
)
93+
|> should.equal(1)
94+
}
95+
96+
pub fn only_complete_rectangles_are_counted_test() {
97+
rectangles.rectangles(
98+
"
99+
+-+
100+
|
101+
+-+-+
102+
| | -
103+
+-+-+
104+
",
105+
)
106+
|> should.equal(1)
107+
}
108+
109+
pub fn rectangles_can_be_of_different_sizes_test() {
110+
rectangles.rectangles(
111+
"
112+
+------+----+
113+
| | |
114+
+---+--+ |
115+
| | |
116+
+---+-------+
117+
",
118+
)
119+
|> should.equal(3)
120+
}
121+
122+
pub fn corner_is_required_for_a_rectangle_to_be_complete_test() {
123+
rectangles.rectangles(
124+
"
125+
+------+----+
126+
| | |
127+
+------+ |
128+
| | |
129+
+---+-------+
130+
",
131+
)
132+
|> should.equal(2)
133+
}
134+
135+
pub fn large_input_with_many_rectangles_test() {
136+
rectangles.rectangles(
137+
"
138+
+---+--+----+
139+
| +--+----+
140+
+---+--+ |
141+
| +--+----+
142+
+---+--+--+-+
143+
+---+--+--+-+
144+
+------+ | |
145+
+-+
146+
",
147+
)
148+
|> should.equal(60)
149+
}
150+
151+
pub fn rectangles_must_have_four_sides_test() {
152+
rectangles.rectangles(
153+
"
154+
+-+ +-+
155+
| | | |
156+
+-+-+-+
157+
| |
158+
+-+-+-+
159+
| | | |
160+
+-+ +-+
161+
",
162+
)
163+
|> should.equal(5)
164+
}

0 commit comments

Comments
 (0)