Skip to content

Commit 44c4b9a

Browse files
authored
add flower-field (#757)
1 parent 706060c commit 44c4b9a

File tree

9 files changed

+351
-3
lines changed

9 files changed

+351
-3
lines changed

config.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,9 +1372,9 @@
13721372
"difficulty": 8
13731373
},
13741374
{
1375-
"slug": "minesweeper",
1376-
"name": "Minesweeper",
1377-
"uuid": "c4e75eb8-6e26-4582-95b6-7ea3205ede6e",
1375+
"slug": "flower-field",
1376+
"name": "Flower Field",
1377+
"uuid": "e26395e9-2fed-4ede-8175-5e9d7c556566",
13781378
"practices": [
13791379
"dict"
13801380
],
@@ -1388,6 +1388,15 @@
13881388
],
13891389
"difficulty": 5
13901390
},
1391+
{
1392+
"slug": "minesweeper",
1393+
"name": "Minesweeper",
1394+
"uuid": "c4e75eb8-6e26-4582-95b6-7ea3205ede6e",
1395+
"practices": [],
1396+
"prerequisites": [],
1397+
"difficulty": 5,
1398+
"status": "deprecated"
1399+
},
13911400
{
13921401
"slug": "protein-translation",
13931402
"name": "Protein Translation",
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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"jiegillet"
4+
],
5+
"contributors": [
6+
"BNAndras"
7+
],
8+
"files": {
9+
"solution": [
10+
"src/FlowerField.elm"
11+
],
12+
"test": [
13+
"tests/Tests.elm"
14+
],
15+
"example": [
16+
".meta/src/FlowerField.example.elm"
17+
]
18+
},
19+
"blurb": "Mark all the flowers in a garden."
20+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
module FlowerField exposing (annotate)
2+
3+
import Dict exposing (Dict)
4+
5+
6+
type Tile
7+
= Empty
8+
| Flower
9+
| Annotated Int
10+
11+
12+
annotate : String -> String
13+
annotate garden =
14+
let
15+
positionMap =
16+
makePositionMap garden
17+
in
18+
positionMap
19+
|> Dict.map (annotateTile positionMap)
20+
|> mergeRows
21+
|> Dict.values
22+
|> List.map (List.map printTile >> String.concat)
23+
|> String.join "\n"
24+
25+
26+
makePositionMap : String -> Dict ( Int, Int ) Tile
27+
makePositionMap input =
28+
input
29+
|> String.lines
30+
|> List.indexedMap
31+
(\row line ->
32+
line
33+
|> String.toList
34+
|> List.indexedMap
35+
(\column char ->
36+
case char of
37+
'*' ->
38+
( ( row, column ), Flower )
39+
40+
_ ->
41+
( ( row, column ), Empty )
42+
)
43+
)
44+
|> List.concat
45+
|> Dict.fromList
46+
47+
48+
annotateTile : Dict ( Int, Int ) Tile -> ( Int, Int ) -> Tile -> Tile
49+
annotateTile garden ( row, col ) tile =
50+
case tile of
51+
Empty ->
52+
[ ( row + 1, col + 1 )
53+
, ( row + 1, col )
54+
, ( row + 1, col - 1 )
55+
, ( row, col + 1 )
56+
, ( row, col - 1 )
57+
, ( row - 1, col + 1 )
58+
, ( row - 1, col )
59+
, ( row - 1, col - 1 )
60+
]
61+
|> List.filter (\p -> Dict.get p garden == Just Flower)
62+
|> List.length
63+
|> Annotated
64+
65+
other ->
66+
other
67+
68+
69+
mergeRows : Dict ( Int, Int ) Tile -> Dict Int (List Tile)
70+
mergeRows =
71+
Dict.foldl
72+
-- we rely on Dict.foldl traversing the keys in order
73+
(\( row, _ ) tile rows ->
74+
Dict.update row
75+
(\line -> Just (tile :: Maybe.withDefault [] line))
76+
rows
77+
)
78+
Dict.empty
79+
>> Dict.map (always List.reverse)
80+
81+
82+
printTile : Tile -> String
83+
printTile tile =
84+
case tile of
85+
Flower ->
86+
"*"
87+
88+
Empty ->
89+
"."
90+
91+
Annotated 0 ->
92+
"."
93+
94+
Annotated count ->
95+
String.fromInt count
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
include = false
18+
comment = "empty board already covered by 237ff487-467a-47e1-9b01-8a891844f86c"
19+
20+
[d774d054-bbad-4867-88ae-069cbd1c4f92]
21+
description = "no flowers"
22+
23+
[225176a0-725e-43cd-aa13-9dced501f16e]
24+
description = "garden full of flowers"
25+
26+
[3f345495-f1a5-4132-8411-74bd7ca08c49]
27+
description = "flower surrounded by spaces"
28+
29+
[6cb04070-4199-4ef7-a6fa-92f68c660fca]
30+
description = "space surrounded by flowers"
31+
32+
[272d2306-9f62-44fe-8ab5-6b0f43a26338]
33+
description = "horizontal line"
34+
35+
[c6f0a4b2-58d0-4bf6-ad8d-ccf4144f1f8e]
36+
description = "horizontal line, flowers at edges"
37+
38+
[a54e84b7-3b25-44a8-b8cf-1753c8bb4cf5]
39+
description = "vertical line"
40+
41+
[b40f42f5-dec5-4abc-b167-3f08195189c1]
42+
description = "vertical line, flowers at edges"
43+
44+
[58674965-7b42-4818-b930-0215062d543c]
45+
description = "cross"
46+
47+
[dd9d4ca8-9e68-4f78-a677-a2a70fd7a7b8]
48+
description = "large garden"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"type": "application",
3+
"source-directories": [
4+
"src"
5+
],
6+
"elm-version": "0.19.1",
7+
"dependencies": {
8+
"direct": {
9+
"elm/core": "1.0.5",
10+
"elm/json": "1.1.3",
11+
"elm/parser": "1.1.0",
12+
"elm/random": "1.0.0",
13+
"elm/regex": "1.0.0",
14+
"elm/time": "1.0.0",
15+
"elm/html": "1.0.0"
16+
},
17+
"indirect": {}
18+
},
19+
"test-dependencies": {
20+
"direct": {
21+
"elm-explorations/test": "2.1.0",
22+
"rtfeldman/elm-iso8601-date-strings": "1.1.4"
23+
},
24+
"indirect": {
25+
"elm/bytes": "1.0.8",
26+
"elm/virtual-dom": "1.0.3"
27+
}
28+
}
29+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module FlowerField exposing (annotate)
2+
3+
4+
annotate : String -> String
5+
annotate garden =
6+
Debug.todo "Please implement annotate"
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
module Tests exposing (tests)
2+
3+
import Expect
4+
import FlowerField
5+
import Test exposing (Test, describe, skip, test)
6+
7+
8+
tests : Test
9+
tests =
10+
describe "FlowerField"
11+
[ -- skip <|
12+
test "no rows" <|
13+
\() ->
14+
FlowerField.annotate ""
15+
|> Expect.equal ""
16+
, skip <|
17+
test "no flowers" <|
18+
\() ->
19+
FlowerField.annotate """...
20+
...
21+
...""" |> Expect.equal """...
22+
...
23+
..."""
24+
, skip <|
25+
test "garden full of flowers" <|
26+
\() ->
27+
FlowerField.annotate """***
28+
***
29+
***""" |> Expect.equal """***
30+
***
31+
***"""
32+
, skip <|
33+
test "flower surrounded by spaces" <|
34+
\() ->
35+
FlowerField.annotate """...
36+
.*.
37+
...""" |> Expect.equal """111
38+
1*1
39+
111"""
40+
, skip <|
41+
test "space surrounded by flowers" <|
42+
\() ->
43+
FlowerField.annotate """***
44+
*.*
45+
***""" |> Expect.equal """***
46+
*8*
47+
***"""
48+
, skip <|
49+
test "horizontal line" <|
50+
\() ->
51+
FlowerField.annotate ".*.*."
52+
|> Expect.equal "1*2*1"
53+
, skip <|
54+
test "horizontal line, flowers at edges" <|
55+
\() ->
56+
FlowerField.annotate "*...*"
57+
|> Expect.equal "*1.1*"
58+
, skip <|
59+
test "vertical line" <|
60+
\() ->
61+
FlowerField.annotate """.
62+
*
63+
.
64+
*
65+
.""" |> Expect.equal """1
66+
*
67+
2
68+
*
69+
1"""
70+
, skip <|
71+
test "vertical line, flowers at edges" <|
72+
\() ->
73+
FlowerField.annotate """*
74+
.
75+
.
76+
.
77+
*""" |> Expect.equal """*
78+
1
79+
.
80+
1
81+
*"""
82+
, skip <|
83+
test "cross" <|
84+
\() ->
85+
FlowerField.annotate """..*..
86+
..*..
87+
*****
88+
..*..
89+
..*..""" |> Expect.equal """.2*2.
90+
25*52
91+
*****
92+
25*52
93+
.2*2."""
94+
, skip <|
95+
test "large garden" <|
96+
\() ->
97+
FlowerField.annotate """.*..*.
98+
..*...
99+
....*.
100+
...*.*
101+
.*..*.
102+
......""" |> Expect.equal """1*22*1
103+
12*322
104+
.123*2
105+
112*4*
106+
1*22*2
107+
111111"""
108+
]

0 commit comments

Comments
 (0)