diff --git a/config.json b/config.json
index 2942d5a61..586d055ec 100644
--- a/config.json
+++ b/config.json
@@ -342,18 +342,10 @@
"slug": "beer-song",
"name": "Beer Song",
"uuid": "0ea0d92f-5510-4ba9-b419-3f5ad029b74f",
- "practices": [
- "ranges",
- "string-formatting"
- ],
- "prerequisites": [
- "lists",
- "numbers",
- "ranges",
- "string-formatting",
- "strings"
- ],
- "difficulty": 3
+ "practices": [],
+ "prerequisites": [],
+ "difficulty": 3,
+ "status": "deprecated"
},
{
"slug": "kindergarten-garden",
@@ -2157,6 +2149,23 @@
"practices": [],
"prerequisites": [],
"difficulty": 5
+ },
+ {
+ "slug": "bottle-song",
+ "name": "Bottle Song",
+ "uuid": "05f6895a-b770-4a07-8db8-3787adf5fdf9",
+ "practices": [
+ "ranges",
+ "string-formatting"
+ ],
+ "prerequisites": [
+ "lists",
+ "numbers",
+ "ranges",
+ "string-formatting",
+ "strings"
+ ],
+ "difficulty": 3
}
],
"foregone": [
diff --git a/exercises/practice/bottle-song/.config/dotnet-tools.json b/exercises/practice/bottle-song/.config/dotnet-tools.json
new file mode 100644
index 000000000..0f7926bad
--- /dev/null
+++ b/exercises/practice/bottle-song/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "fantomas-tool": {
+ "version": "4.7.9",
+ "commands": [
+ "fantomas"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/exercises/practice/bottle-song/.docs/instructions.md b/exercises/practice/bottle-song/.docs/instructions.md
new file mode 100644
index 000000000..febdfc863
--- /dev/null
+++ b/exercises/practice/bottle-song/.docs/instructions.md
@@ -0,0 +1,57 @@
+# Instructions
+
+Recite the lyrics to that popular children's repetitive song: Ten Green Bottles.
+
+Note that not all verses are identical.
+
+```text
+Ten green bottles hanging on the wall,
+Ten green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be nine green bottles hanging on the wall.
+
+Nine green bottles hanging on the wall,
+Nine green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be eight green bottles hanging on the wall.
+
+Eight green bottles hanging on the wall,
+Eight green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be seven green bottles hanging on the wall.
+
+Seven green bottles hanging on the wall,
+Seven green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be six green bottles hanging on the wall.
+
+Six green bottles hanging on the wall,
+Six green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be five green bottles hanging on the wall.
+
+Five green bottles hanging on the wall,
+Five green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be four green bottles hanging on the wall.
+
+Four green bottles hanging on the wall,
+Four green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be three green bottles hanging on the wall.
+
+Three green bottles hanging on the wall,
+Three green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be two green bottles hanging on the wall.
+
+Two green bottles hanging on the wall,
+Two green bottles hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be one green bottle hanging on the wall.
+
+One green bottle hanging on the wall,
+One green bottle hanging on the wall,
+And if one green bottle should accidentally fall,
+There'll be no green bottles hanging on the wall.
+```
diff --git a/exercises/practice/bottle-song/.meta/Example.fs b/exercises/practice/bottle-song/.meta/Example.fs
new file mode 100644
index 000000000..877e2e967
--- /dev/null
+++ b/exercises/practice/bottle-song/.meta/Example.fs
@@ -0,0 +1,29 @@
+module BottleSong
+
+let private counts =
+ [| "no"
+ "one"
+ "two"
+ "three"
+ "four"
+ "five"
+ "six"
+ "seven"
+ "eight"
+ "nine"
+ "ten" |]
+
+let private capitalize (s: string) = $"{System.Char.ToUpper(s[0])}{s[1..]}"
+
+let private bottles n = if n = 1 then "bottle" else "bottles"
+
+let private verse bottleCount =
+ [ $"{counts[bottleCount] |> capitalize} green {bottles bottleCount} hanging on the wall,"
+ $"{counts[bottleCount] |> capitalize} green {bottles bottleCount} hanging on the wall,"
+ $"And if one green {bottles 1} should accidentally fall,"
+ $"There'll be {counts[bottleCount - 1]} green {bottles (bottleCount - 1)} hanging on the wall." ]
+
+let recite startBottles takeDown =
+ [ startBottles .. -1 .. (startBottles - takeDown + 1) ]
+ |> List.map verse
+ |> List.reduce (fun x y -> x @ "" :: y)
diff --git a/exercises/practice/bottle-song/.meta/config.json b/exercises/practice/bottle-song/.meta/config.json
new file mode 100644
index 000000000..d01a1e404
--- /dev/null
+++ b/exercises/practice/bottle-song/.meta/config.json
@@ -0,0 +1,19 @@
+{
+ "authors": [
+ "erikschierboom"
+ ],
+ "files": {
+ "solution": [
+ "BottleSong.fs"
+ ],
+ "test": [
+ "BottleSongTests.fs"
+ ],
+ "example": [
+ ".meta/Example.fs"
+ ]
+ },
+ "blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.",
+ "source": "Wikipedia",
+ "source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles"
+}
diff --git a/exercises/practice/bottle-song/.meta/tests.toml b/exercises/practice/bottle-song/.meta/tests.toml
new file mode 100644
index 000000000..1f6e40a37
--- /dev/null
+++ b/exercises/practice/bottle-song/.meta/tests.toml
@@ -0,0 +1,31 @@
+# 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.
+
+[d4ccf8fc-01dc-48c0-a201-4fbeb30f2d03]
+description = "verse -> single verse -> first generic verse"
+
+[0f0aded3-472a-4c64-b842-18d4f1f5f030]
+description = "verse -> single verse -> last generic verse"
+
+[f61f3c97-131f-459e-b40a-7428f3ed99d9]
+description = "verse -> single verse -> verse with 2 bottles"
+
+[05eadba9-5dbd-401e-a7e8-d17cc9baa8e0]
+description = "verse -> single verse -> verse with 1 bottle"
+
+[a4a28170-83d6-4dc1-bd8b-319b6abb6a80]
+description = "lyrics -> multiple verses -> first two verses"
+
+[3185d438-c5ac-4ce6-bcd3-02c9ff1ed8db]
+description = "lyrics -> multiple verses -> last three verses"
+
+[28c1584a-0e51-4b65-9ae2-fbc0bf4bbb28]
+description = "lyrics -> multiple verses -> all verses"
diff --git a/exercises/practice/bottle-song/BottleSong.fs b/exercises/practice/bottle-song/BottleSong.fs
new file mode 100644
index 000000000..a2e9dbcad
--- /dev/null
+++ b/exercises/practice/bottle-song/BottleSong.fs
@@ -0,0 +1,4 @@
+module BottleSong
+
+let recite startBottles takeDown =
+ failwith "Please implement the 'recite' function"
diff --git a/exercises/practice/bottle-song/BottleSong.fsproj b/exercises/practice/bottle-song/BottleSong.fsproj
new file mode 100644
index 000000000..080e24680
--- /dev/null
+++ b/exercises/practice/bottle-song/BottleSong.fsproj
@@ -0,0 +1,22 @@
+
+
+ net8.0
+ false
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
\ No newline at end of file
diff --git a/exercises/practice/bottle-song/BottleSongTests.fs b/exercises/practice/bottle-song/BottleSongTests.fs
new file mode 100644
index 000000000..1748fb11b
--- /dev/null
+++ b/exercises/practice/bottle-song/BottleSongTests.fs
@@ -0,0 +1,136 @@
+module BottleSongTests
+
+open FsUnit.Xunit
+open Xunit
+
+open BottleSong
+
+[]
+let ``First generic verse`` () =
+ recite 10 1
+ |> should
+ equal
+ [ "Ten green bottles hanging on the wall,"
+ "Ten green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be nine green bottles hanging on the wall." ]
+
+[]
+let ``Last generic verse`` () =
+ recite 3 1
+ |> should
+ equal
+ [ "Three green bottles hanging on the wall,"
+ "Three green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be two green bottles hanging on the wall." ]
+
+[]
+let ``Verse with 2 bottles`` () =
+ recite 2 1
+ |> should
+ equal
+ [ "Two green bottles hanging on the wall,"
+ "Two green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be one green bottle hanging on the wall." ]
+
+[]
+let ``Verse with 1 bottle`` () =
+ recite 1 1
+ |> should
+ equal
+ [ "One green bottle hanging on the wall,"
+ "One green bottle hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be no green bottles hanging on the wall." ]
+
+[]
+let ``First two verses`` () =
+ recite 10 2
+ |> should
+ equal
+ [ "Ten green bottles hanging on the wall,"
+ "Ten green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be nine green bottles hanging on the wall."
+ ""
+ "Nine green bottles hanging on the wall,"
+ "Nine green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be eight green bottles hanging on the wall." ]
+
+[]
+let ``Last three verses`` () =
+ recite 3 3
+ |> should
+ equal
+ [ "Three green bottles hanging on the wall,"
+ "Three green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be two green bottles hanging on the wall."
+ ""
+ "Two green bottles hanging on the wall,"
+ "Two green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be one green bottle hanging on the wall."
+ ""
+ "One green bottle hanging on the wall,"
+ "One green bottle hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be no green bottles hanging on the wall." ]
+
+[]
+let ``All verses`` () =
+ recite 10 10
+ |> should
+ equal
+ [ "Ten green bottles hanging on the wall,"
+ "Ten green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be nine green bottles hanging on the wall."
+ ""
+ "Nine green bottles hanging on the wall,"
+ "Nine green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be eight green bottles hanging on the wall."
+ ""
+ "Eight green bottles hanging on the wall,"
+ "Eight green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be seven green bottles hanging on the wall."
+ ""
+ "Seven green bottles hanging on the wall,"
+ "Seven green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be six green bottles hanging on the wall."
+ ""
+ "Six green bottles hanging on the wall,"
+ "Six green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be five green bottles hanging on the wall."
+ ""
+ "Five green bottles hanging on the wall,"
+ "Five green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be four green bottles hanging on the wall."
+ ""
+ "Four green bottles hanging on the wall,"
+ "Four green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be three green bottles hanging on the wall."
+ ""
+ "Three green bottles hanging on the wall,"
+ "Three green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be two green bottles hanging on the wall."
+ ""
+ "Two green bottles hanging on the wall,"
+ "Two green bottles hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be one green bottle hanging on the wall."
+ ""
+ "One green bottle hanging on the wall,"
+ "One green bottle hanging on the wall,"
+ "And if one green bottle should accidentally fall,"
+ "There'll be no green bottles hanging on the wall." ]
diff --git a/generators/Generators.fs b/generators/Generators.fs
index 8e44dfa01..f72e2210f 100644
--- a/generators/Generators.fs
+++ b/generators/Generators.fs
@@ -2044,3 +2044,6 @@ type EliudsEggs() =
type Knapsack() =
inherit ExerciseGenerator()
+
+type BottleSong() =
+ inherit ExerciseGenerator()