Skip to content

Commit

Permalink
Add bottle-song exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode committed Feb 15, 2025
1 parent 95cfaf3 commit 6fcfa50
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,14 @@
"prerequisites": [],
"difficulty": 4
},
{
"slug": "bottle-song",
"name": "Bottle Song",
"uuid": "92fd7655-0e70-4f6d-9485-dbfbdce89dba",
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "circular-buffer",
"name": "Circular Buffer",
Expand Down
57 changes: 57 additions & 0 deletions exercises/practice/bottle-song/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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.
```
19 changes: 19 additions & 0 deletions exercises/practice/bottle-song/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"bottle-song.v"
],
"test": [
"run_test.v"
],
"example": [
".meta/example.v"
]
},
"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"
}
40 changes: 40 additions & 0 deletions exercises/practice/bottle-song/.meta/example.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module main

import strings

const numbers = ['No', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
'Ten']

fn append_line(mut builder strings.Builder, bottles int, lower bool) {
if lower {
builder.write_rune(numbers[bottles][0] | 32)
builder.write_string(numbers[bottles][1..])
} else {
builder.write_string(numbers[bottles])
}
builder.write_string(' green bottle')
if bottles != 1 {
builder.write_rune(`s`)
}
builder.write_string(' hanging on the wall')
}

fn recite(start_bottles int, take_down int) string {
mut builder := strings.new_builder(4000)
mut bottles := start_bottles
for bottles > start_bottles - take_down {
append_line(mut &builder, bottles, false)
builder.write_string(',\n')

append_line(mut &builder, bottles, false)
builder.write_string(',\n')

builder.write_string("And if one green bottle should accidentally fall,\nThere'll be ")
bottles--

append_line(mut &builder, bottles, true)
builder.write_string('.\n\n')
}
builder.go_back(2)
return builder.str()
}
24 changes: 24 additions & 0 deletions exercises/practice/bottle-song/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in 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"
4 changes: 4 additions & 0 deletions exercises/practice/bottle-song/bottle-song.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module main

fn recite(start_bottles int, take_down int) string {
}
124 changes: 124 additions & 0 deletions exercises/practice/bottle-song/run_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
module main

fn test_verse__single_verse__first_generic_verse() {
expected :=
("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.")
assert recite(10, 1) == expected
}

fn test_verse__single_verse__last_generic_verse() {
expected :=
("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.")
assert recite(3, 1) == expected
}

fn test_verse__single_verse__verse_with_2_bottles() {
expected :=
("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.")
assert recite(2, 1) == expected
}

fn test_verse__single_verse__verse_with_1_bottle() {
expected :=
("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.")
assert recite(1, 1) == expected
}

fn test_lyrics__multiple_verses__first_two_verses() {
expected :=
("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.")
assert recite(10, 2) == expected
}

fn test_lyrics__multiple_verses__last_three_verses() {
expected :=
("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.")
assert recite(3, 3) == expected
}

fn test_lyrics__multiple_verses__all_verses() {
expected :=
("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.")
assert recite(10, 10) == expected
}

0 comments on commit 6fcfa50

Please sign in to comment.