Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,14 @@
"prerequisites": [],
"difficulty": 7
},
{
"slug": "rectangles",
"name": "Rectangles",
"uuid": "c63979dc-1b48-4fbf-ae84-c10ba5a10304",
"practices": [],
"prerequisites": [],
"difficulty": 7
},
{
"slug": "rest-api",
"name": "REST API",
Expand Down
5 changes: 5 additions & 0 deletions exercises/practice/rectangles/.busted
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
return {
default = {
ROOT = { '.' }
}
}
63 changes: 63 additions & 0 deletions exercises/practice/rectangles/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Instructions

Count the rectangles in an ASCII diagram like the one below.

```text
+--+
++ |
+-++--+
| | |
+--+--+
```

The above diagram contains these 6 rectangles:

```text


+-----+
| |
+-----+
```

```text
+--+
| |
| |
| |
+--+
```

```text
+--+
| |
+--+


```

```text


+--+
| |
+--+
```

```text


+--+
| |
+--+
```

```text

++
++


```

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).
17 changes: 17 additions & 0 deletions exercises/practice/rectangles/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"glennj"
],
"files": {
"solution": [
"rectangles.moon"
],
"test": [
"rectangles_spec.moon"
],
"example": [
".meta/example.moon"
]
},
"blurb": "Count the rectangles in an ASCII diagram."
}
52 changes: 52 additions & 0 deletions exercises/practice/rectangles/.meta/example.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
contains = (vertices, vertex) ->
for v in *vertices
return true if v == vertex
false

-- ----------------------------------------
class Vertex
new: (@row, @col) =>
__eq: (other) => @row == other.row and @col == other.col

vertices = (input) ->
[Vertex row, col for row = 1, #input for col = 1, #input[1] when input[row][col] == '+']

verticesRightOf = (vertex, vertices) ->
[v for v in *vertices when v.row == vertex.row and v.col > vertex.col]

verticesBelow = (vertex, vertices) ->
[v for v in *vertices when v.col == vertex.col and v.row > vertex.row]

-- ----------------------------------------
isRectangle = (input, topLeft, topRight, bottomLeft, bottomRight) ->
horizontalLine = (left, right) ->
for col = left.col + 1, right.col - 1
return false if not (input[left.row][col] == '-' or input[left.row][col] == '+')
true

verticalLine = (top, bottom) ->
for row = top.row + 1, bottom.row - 1
return false if not (input[row][top.col] == '|' or input[row][top.col] == '+')
true

return false if not horizontalLine topLeft, topRight
return false if not horizontalLine bottomLeft, bottomRight
return false if not verticalLine topLeft, bottomLeft
return false if not verticalLine topRight, bottomRight
true

-- ----------------------------------------
rectangles = (input) ->
input = [ [c for c in line\gmatch '.'] for line in *input]
vs = vertices input
count = 0
for topLeft in *vs
for topRight in *verticesRightOf topLeft, vs
for bottomLeft in *verticesBelow topLeft, vs
bottomRight = Vertex bottomLeft.row, topRight.col
if contains vs, bottomRight
if isRectangle input, topLeft, topRight, bottomLeft, bottomRight
count += 1
count

{ :rectangles }
13 changes: 13 additions & 0 deletions exercises/practice/rectangles/.meta/spec_generator.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
test_helpers = require 'test_helpers'
import string_list from test_helpers

{
module_imports: {'rectangles'},

generate_test: (case, level) ->
lines = {
"input = #{string_list case.input.strings, level, {inline: 1}}",
"assert.are.equal #{case.expected}, rectangles input"
}
table.concat [indent line, level for line in *lines], '\n'
}
52 changes: 52 additions & 0 deletions exercises/practice/rectangles/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 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.

[485b7bab-4150-40aa-a8db-73013427d08c]
description = "no rows"

[076929ed-27e8-45dc-b14b-08279944dc49]
description = "no columns"

[0a8abbd1-a0a4-4180-aa4e-65c1b1a073fa]
description = "no rectangles"

[a4ba42e9-4e7f-4973-b7c7-4ce0760ac6cd]
description = "one rectangle"

[ced06550-83da-4d23-98b7-d24152e0db93]
description = "two rectangles without shared parts"

[5942d69a-a07c-41c8-8b93-2d13877c706a]
description = "five rectangles with shared parts"

[82d70be4-ab37-4bf2-a433-e33778d3bbf1]
description = "rectangle of height 1 is counted"

[57f1bc0e-2782-401e-ab12-7c01d8bfc2e0]
description = "rectangle of width 1 is counted"

[ef0bb65c-bd80-4561-9535-efc4067054f9]
description = "1x1 square is counted"

[e1e1d444-e926-4d30-9bf3-7d8ec9a9e330]
description = "only complete rectangles are counted"

[ca021a84-1281-4a56-9b9b-af14113933a4]
description = "rectangles can be of different sizes"

[51f689a7-ef3f-41ae-aa2f-5ea09ad897ff]
description = "corner is required for a rectangle to be complete"

[d78fe379-8c1b-4d3c-bdf7-29bfb6f6dc66]
description = "large input with many rectangles"

[6ef24e0f-d191-46da-b929-4faca24b4cd2]
description = "rectangles must have four sides"
4 changes: 4 additions & 0 deletions exercises/practice/rectangles/rectangles.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
rectangles: (input) ->
error 'Implement me'
}
119 changes: 119 additions & 0 deletions exercises/practice/rectangles/rectangles_spec.moon
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import rectangles from require 'rectangles'

describe 'rectangles', ->
it 'no rows', ->
input = {}
assert.are.equal 0, rectangles input

pending 'no columns', ->
input = {''}
assert.are.equal 0, rectangles input

pending 'no rectangles', ->
input = {' '}
assert.are.equal 0, rectangles input

pending 'one rectangle', ->
input = {
'+-+',
'| |',
'+-+',
}
assert.are.equal 1, rectangles input

pending 'two rectangles without shared parts', ->
input = {
' +-+',
' | |',
'+-+-+',
'| | ',
'+-+ ',
}
assert.are.equal 2, rectangles input

pending 'five rectangles with shared parts', ->
input = {
' +-+',
' | |',
'+-+-+',
'| | |',
'+-+-+',
}
assert.are.equal 5, rectangles input

pending 'rectangle of height 1 is counted', ->
input = {
'+--+',
'+--+',
}
assert.are.equal 1, rectangles input

pending 'rectangle of width 1 is counted', ->
input = {
'++',
'||',
'++',
}
assert.are.equal 1, rectangles input

pending '1x1 square is counted', ->
input = {
'++',
'++',
}
assert.are.equal 1, rectangles input

pending 'only complete rectangles are counted', ->
input = {
' +-+',
' |',
'+-+-+',
'| | -',
'+-+-+',
}
assert.are.equal 1, rectangles input

pending 'rectangles can be of different sizes', ->
input = {
'+------+----+',
'| | |',
'+---+--+ |',
'| | |',
'+---+-------+',
}
assert.are.equal 3, rectangles input

pending 'corner is required for a rectangle to be complete', ->
input = {
'+------+----+',
'| | |',
'+------+ |',
'| | |',
'+---+-------+',
}
assert.are.equal 2, rectangles input

pending 'large input with many rectangles', ->
input = {
'+---+--+----+',
'| +--+----+',
'+---+--+ |',
'| +--+----+',
'+---+--+--+-+',
'+---+--+--+-+',
'+------+ | |',
' +-+',
}
assert.are.equal 60, rectangles input

pending 'rectangles must have four sides', ->
input = {
'+-+ +-+',
'| | | |',
'+-+-+-+',
' | | ',
'+-+-+-+',
'| | | |',
'+-+ +-+',
}
assert.are.equal 5, rectangles input
7 changes: 4 additions & 3 deletions exercises/shared/templates/spec_generator.moon
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
test_helpers = require 'test_helpers'
import int_list, word_list from test_helpers
import int_list, word_list from require 'test_helpers'

{
-- one of:
module_name: '${camel_slug}',
-- or, module_imports: {'func1', 'func2', ...},
-- or
-- module_imports: {'func1', 'func2', ...},

generate_test: (case, level) ->
local lines
Expand Down
5 changes: 3 additions & 2 deletions lib/test_helpers.moon
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ word_list = (list) ->
-- This returns a multi-line string without the first line indented.
-- The returned string will be added to another string in the test case body,
-- and then that string (without regard to internal newlines) will later be indented.
string_list = (list, level) ->
string_list = (list, level, opts) ->
error 'Provide a level for `string_list`', 2 if not level
if #list <= 2
opts = opts or {inline: 2}
if #list <= opts.inline
"{#{table.concat [quote elem for elem in *list], ', '}}"
else
lines = [indent quote(elem) .. ',', level + 1 for elem in *list]
Expand Down
Loading