Skip to content

Commit e546bfc

Browse files
flower-field replaces minesweeper
1 parent d03a4e7 commit e546bfc

File tree

12 files changed

+445
-0
lines changed

12 files changed

+445
-0
lines changed

config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,25 @@
284284
"generic_over_type"
285285
]
286286
},
287+
{
288+
"slug": "flower-field",
289+
"name": "Flower Field",
290+
"uuid": "117d6a25-960e-4d53-8347-a20490f60f36",
291+
"practices": [],
292+
"prerequisites": [],
293+
"difficulty": 7,
294+
"topics": [
295+
"board_state"
296+
]
297+
},
287298
{
288299
"slug": "minesweeper",
289300
"name": "Minesweeper",
290301
"uuid": "e0037ac4-ae5f-4622-b3ad-915648263495",
291302
"practices": [],
292303
"prerequisites": [],
293304
"difficulty": 7,
305+
"status": "deprecated",
294306
"topics": [
295307
"board_state"
296308
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Instructions append
2+
3+
## Performance Hint
4+
5+
All the inputs and outputs are in ASCII.
6+
Rust `String`s and `&str` are utf8, so while one might expect `"Hello".chars()` to be simple, it actually has to check each char to see if it's 1, 2, 3 or 4 `u8`s long.
7+
If we know a `&str` is ASCII then we can call `.as_bytes()` and refer to the underlying data as a `&[u8]` (byte slice).
8+
Iterating over a slice of ASCII bytes is much quicker as there are no codepoints involved - every ASCII byte is one `u8` long.
9+
10+
Can you complete the challenge without cloning the input?
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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"authors": [
3+
"EduardoBautista"
4+
],
5+
"contributors": [
6+
"ashleygwilliams",
7+
"coriolinus",
8+
"cwhakes",
9+
"EduardoBautista",
10+
"efx",
11+
"ErikSchierboom",
12+
"ffflorian",
13+
"IanWhitney",
14+
"keiravillekode",
15+
"kytrinyx",
16+
"lutostag",
17+
"mkantor",
18+
"nfiles",
19+
"petertseng",
20+
"rofrol",
21+
"stringparser",
22+
"workingjubilee",
23+
"xakon",
24+
"ZapAnton"
25+
],
26+
"files": {
27+
"solution": [
28+
"src/lib.rs",
29+
"Cargo.toml"
30+
],
31+
"test": [
32+
"tests/flower_field.rs"
33+
],
34+
"example": [
35+
".meta/example.rs"
36+
]
37+
},
38+
"blurb": "Mark all the flowers in a garden."
39+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
struct Board {
2+
pieces: Vec<Vec<char>>,
3+
num_rows: usize,
4+
num_cols: usize,
5+
}
6+
7+
impl Board {
8+
fn annotated(&self) -> Vec<String> {
9+
(0..self.num_rows).map(|y| self.annotated_row(y)).collect()
10+
}
11+
12+
fn annotated_row(&self, y: usize) -> String {
13+
self.pieces[y]
14+
.iter()
15+
.enumerate()
16+
.map(|(x, &c)| {
17+
if c == ' ' {
18+
self.count_neighbouring_flowers_char(x, y)
19+
} else {
20+
c
21+
}
22+
})
23+
.collect::<String>()
24+
}
25+
26+
fn count_neighbouring_flowers_char(&self, x: usize, y: usize) -> char {
27+
let mut count = 0;
28+
for x1 in neighbouring_points(x, self.num_cols) {
29+
for y1 in neighbouring_points(y, self.num_rows) {
30+
let piece = self.pieces[y1][x1];
31+
if piece == '*' {
32+
count += 1;
33+
}
34+
}
35+
}
36+
if count == 0 {
37+
' '
38+
} else {
39+
(b'0' + count) as char
40+
}
41+
}
42+
}
43+
44+
pub fn annotate(pieces: &[&str]) -> Vec<String> {
45+
if pieces.is_empty() {
46+
return Vec::new();
47+
}
48+
let pieces_vec = pieces.iter().map(|&r| r.chars().collect()).collect();
49+
Board {
50+
pieces: pieces_vec,
51+
num_rows: pieces.len(),
52+
num_cols: pieces[0].len(),
53+
}
54+
.annotated()
55+
}
56+
57+
fn neighbouring_points(x: usize, limit: usize) -> Vec<usize> {
58+
let mut offsets = vec![x];
59+
if x >= 1 {
60+
offsets.push(x - 1);
61+
}
62+
if x + 2 <= limit {
63+
offsets.push(x + 1);
64+
}
65+
offsets
66+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use flower_field::*;
2+
3+
{% for test in cases %}
4+
#[test]
5+
#[ignore]
6+
fn {{ test.description | make_ident }}() {
7+
{% if test.input.garden | length < 2 -%}
8+
let input = &[
9+
{%- for line in test.input.garden %}
10+
{{ line | json_encode() }},
11+
{%- endfor %}
12+
];
13+
let expected{% if test.expected | length == 0 %}: &[&str]{% endif %} = &[
14+
{%- for line in test.expected %}
15+
{{ line | json_encode() }},
16+
{%- endfor %}
17+
];
18+
{% else -%}
19+
#[rustfmt::skip]
20+
let (input, expected) = (&[
21+
{%- for line in test.input.garden %}
22+
{{ line | json_encode() }},
23+
{%- endfor %}
24+
], &[
25+
{%- for line in test.expected %}
26+
{{ line | json_encode() }},
27+
{%- endfor %}
28+
]);
29+
{% endif -%}
30+
let actual = annotate(input);
31+
assert_eq!(actual, expected);
32+
}
33+
{% endfor -%}
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "flower_field"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
# Not all libraries from crates.io are available in Exercism's test runner.
7+
# The full list of available libraries is here:
8+
# https://github.com/exercism/rust-test-runner/blob/main/local-registry/Cargo.toml
9+
[dependencies]

0 commit comments

Comments
 (0)