Skip to content

Commit b415d6a

Browse files
authored
Add flower-field exercise, deprecate minesweeper (#556)
1 parent ec6093d commit b415d6a

File tree

10 files changed

+388
-0
lines changed

10 files changed

+388
-0
lines changed

config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,22 @@
13021302
"practices": [],
13031303
"prerequisites": [],
13041304
"difficulty": 7,
1305+
"topics": [
1306+
"arrays",
1307+
"control_flow_if_else_statements",
1308+
"control_flow_loops",
1309+
"exception_handling",
1310+
"strings"
1311+
],
1312+
"status": "deprecated"
1313+
},
1314+
{
1315+
"slug": "flower-field",
1316+
"name": "flower-field",
1317+
"uuid": "7915cf5b-bd42-45aa-abd7-21dfb0059169",
1318+
"practices": [],
1319+
"prerequisites": [],
1320+
"difficulty": 7,
13051321
"topics": [
13061322
"arrays",
13071323
"control_flow_if_else_statements",
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: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Instructions
2+
3+
Your task is to add flower counts to empty squares in a completed Flower Field garden.
4+
The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`).
5+
6+
For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally).
7+
If the empty square has no adjacent flowers, leave it empty.
8+
Otherwise replace it with the count of adjacent flowers.
9+
10+
For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen):
11+
12+
```text
13+
·*·*·
14+
··*··
15+
··*··
16+
·····
17+
```
18+
19+
Which your code should transform into this:
20+
21+
```text
22+
1*3*1
23+
13*31
24+
·2*2·
25+
·111·
26+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Introduction
2+
3+
[Flower Field][history] is a compassionate reimagining of the popular game Minesweeper.
4+
The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square.
5+
"Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan.
6+
7+
[history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"ryanplusplus"
4+
],
5+
"contributors": [],
6+
"files": {
7+
"solution": [
8+
"flower-field.lua"
9+
],
10+
"test": [
11+
"flower-field_spec.lua"
12+
],
13+
"example": [
14+
".meta/example.lua"
15+
]
16+
},
17+
"blurb": "Mark all the flowers in a garden."
18+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
local garden = {}
2+
garden.__index = garden
3+
4+
local function Garden(rep)
5+
local height = #rep
6+
local width = height > 0 and #rep[1] or 0
7+
8+
return setmetatable({ rep = rep, width = width, height = height }, garden)
9+
end
10+
11+
function garden:at(x, y)
12+
if x < 1 or x > self.width then
13+
return ' '
14+
end
15+
if y < 1 or y > self.height then
16+
return ' '
17+
end
18+
return self.rep[y]:sub(x, x)
19+
end
20+
21+
function garden:set(x, y, c)
22+
local v = self.rep[y]
23+
v = v:sub(1, x - 1) .. c .. v:sub(x + 1)
24+
self.rep[y] = v
25+
end
26+
27+
function garden:neighbors(x, y)
28+
return coroutine.wrap(function()
29+
for xx = x - 1, x + 1 do
30+
for yy = y - 1, y + 1 do
31+
coroutine.yield(self:at(xx, yy))
32+
end
33+
end
34+
end)
35+
end
36+
37+
function garden:empty_spaces()
38+
return coroutine.wrap(function()
39+
for x = 1, self.width do
40+
for y = 1, self.height do
41+
if self:at(x, y) == ' ' then
42+
coroutine.yield(x, y)
43+
end
44+
end
45+
end
46+
end)
47+
end
48+
49+
local function annotate(garden)
50+
local garden = Garden(garden)
51+
52+
for x, y in garden:empty_spaces() do
53+
local flowers = 0
54+
for neighbor in garden:neighbors(x, y) do
55+
if neighbor == '*' then
56+
flowers = flowers + 1
57+
end
58+
end
59+
if flowers > 0 then
60+
garden:set(x, y, tostring(flowers))
61+
end
62+
end
63+
64+
return garden.rep
65+
end
66+
67+
return { annotate = annotate }
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
local map = function(t, f)
2+
local mapped = {}
3+
for i, v in ipairs(t) do
4+
mapped[i] = f(v)
5+
end
6+
return mapped
7+
end
8+
9+
local function render_garden(garden)
10+
return table.concat(map(garden, function(row)
11+
return "'" .. row .. "', --"
12+
end), ',\n ')
13+
end
14+
15+
return {
16+
module_name = 'flower_field',
17+
18+
generate_test = function(case)
19+
local template = [[
20+
local garden = {
21+
%s
22+
}
23+
local expected = {
24+
%s
25+
}
26+
assert.same(expected, flower_field.annotate(garden))]]
27+
28+
return template:format(render_garden(case.input.garden), render_garden(case.expected))
29+
end
30+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
[237ff487-467a-47e1-9b01-8a891844f86c]
13+
description = "no rows"
14+
15+
[4b4134ec-e20f-439c-a295-664c38950ba1]
16+
description = "no columns"
17+
18+
[d774d054-bbad-4867-88ae-069cbd1c4f92]
19+
description = "no flowers"
20+
21+
[225176a0-725e-43cd-aa13-9dced501f16e]
22+
description = "garden full of flowers"
23+
24+
[3f345495-f1a5-4132-8411-74bd7ca08c49]
25+
description = "flower surrounded by spaces"
26+
27+
[6cb04070-4199-4ef7-a6fa-92f68c660fca]
28+
description = "space surrounded by flowers"
29+
30+
[272d2306-9f62-44fe-8ab5-6b0f43a26338]
31+
description = "horizontal line"
32+
33+
[c6f0a4b2-58d0-4bf6-ad8d-ccf4144f1f8e]
34+
description = "horizontal line, flowers at edges"
35+
36+
[a54e84b7-3b25-44a8-b8cf-1753c8bb4cf5]
37+
description = "vertical line"
38+
39+
[b40f42f5-dec5-4abc-b167-3f08195189c1]
40+
description = "vertical line, flowers at edges"
41+
42+
[58674965-7b42-4818-b930-0215062d543c]
43+
description = "cross"
44+
45+
[dd9d4ca8-9e68-4f78-a677-a2a70fd7a7b8]
46+
description = "large garden"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
local function annotate(garden)
2+
end
3+
4+
return { annotate = annotate }

0 commit comments

Comments
 (0)