Skip to content

Commit 5eb6aa8

Browse files
authored
Add bottle-song exercise (#2507)
1 parent bbac886 commit 5eb6aa8

File tree

9 files changed

+362
-0
lines changed

9 files changed

+362
-0
lines changed

config.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,18 @@
695695
"difficulty": 6,
696696
"status": "deprecated"
697697
},
698+
{
699+
"slug": "bottle-song",
700+
"name": "Bottle Song",
701+
"uuid": "3fa6750f-cf01-4542-a494-df9a8c658733",
702+
"practices": [
703+
"strings"
704+
],
705+
"prerequisites": [
706+
"strings"
707+
],
708+
"difficulty": 6
709+
},
698710
{
699711
"slug": "food-chain",
700712
"name": "Food Chain",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Instructions
2+
3+
Recite the lyrics to that popular children's repetitive song: Ten Green Bottles.
4+
5+
Note that not all verses are identical.
6+
7+
```text
8+
Ten green bottles hanging on the wall,
9+
Ten green bottles hanging on the wall,
10+
And if one green bottle should accidentally fall,
11+
There'll be nine green bottles hanging on the wall.
12+
13+
Nine green bottles hanging on the wall,
14+
Nine green bottles hanging on the wall,
15+
And if one green bottle should accidentally fall,
16+
There'll be eight green bottles hanging on the wall.
17+
18+
Eight green bottles hanging on the wall,
19+
Eight green bottles hanging on the wall,
20+
And if one green bottle should accidentally fall,
21+
There'll be seven green bottles hanging on the wall.
22+
23+
Seven green bottles hanging on the wall,
24+
Seven green bottles hanging on the wall,
25+
And if one green bottle should accidentally fall,
26+
There'll be six green bottles hanging on the wall.
27+
28+
Six green bottles hanging on the wall,
29+
Six green bottles hanging on the wall,
30+
And if one green bottle should accidentally fall,
31+
There'll be five green bottles hanging on the wall.
32+
33+
Five green bottles hanging on the wall,
34+
Five green bottles hanging on the wall,
35+
And if one green bottle should accidentally fall,
36+
There'll be four green bottles hanging on the wall.
37+
38+
Four green bottles hanging on the wall,
39+
Four green bottles hanging on the wall,
40+
And if one green bottle should accidentally fall,
41+
There'll be three green bottles hanging on the wall.
42+
43+
Three green bottles hanging on the wall,
44+
Three green bottles hanging on the wall,
45+
And if one green bottle should accidentally fall,
46+
There'll be two green bottles hanging on the wall.
47+
48+
Two green bottles hanging on the wall,
49+
Two green bottles hanging on the wall,
50+
And if one green bottle should accidentally fall,
51+
There'll be one green bottle hanging on the wall.
52+
53+
One green bottle hanging on the wall,
54+
One green bottle hanging on the wall,
55+
And if one green bottle should accidentally fall,
56+
There'll be no green bottles hanging on the wall.
57+
```
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"kahgoh"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/main/java/BottleSong.java"
8+
],
9+
"test": [
10+
"src/test/java/BottleSongTest.java"
11+
],
12+
"example": [
13+
".meta/src/reference/java/BottleSong.java"
14+
]
15+
},
16+
"blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.",
17+
"source": "Wikipedia",
18+
"source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles"
19+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
class BottleSong {
2+
private String word(int number) {
3+
return switch (number) {
4+
case 2 -> "two";
5+
case 3 -> "three";
6+
case 4 -> "four";
7+
case 5 -> "five";
8+
case 6 -> "six";
9+
case 7 -> "seven";
10+
case 8 -> "eight";
11+
case 9 -> "nine";
12+
case 10 -> "ten";
13+
default -> throw new IllegalArgumentException("Unrecognised number: " + Integer.toString(number));
14+
};
15+
}
16+
17+
private String verse(int number) {
18+
return switch (number) {
19+
case 1 ->
20+
"One green bottle hanging on the wall,\n" +
21+
"One green bottle hanging on the wall,\n" +
22+
"And if one green bottle should accidentally fall,\n" +
23+
"There'll be no green bottles hanging on the wall.\n";
24+
case 2 ->
25+
"Two green bottles hanging on the wall,\n" +
26+
"Two green bottles hanging on the wall,\n" +
27+
"And if one green bottle should accidentally fall,\n" +
28+
"There'll be one green bottle hanging on the wall.\n";
29+
default -> {
30+
var codePoints = word(number).codePoints().toArray();
31+
codePoints[0] = Character.toUpperCase(codePoints[0]);
32+
var numberText = new String(codePoints, 0, codePoints.length);
33+
34+
var nextNumberText = word(number - 1);
35+
36+
yield String.format(
37+
"%s green bottles hanging on the wall,\n" +
38+
"%s green bottles hanging on the wall,\n" +
39+
"And if one green bottle should accidentally fall,\n" +
40+
"There'll be %s green bottles hanging on the wall.\n",
41+
numberText, numberText, nextNumberText);
42+
}
43+
};
44+
}
45+
46+
String recite(int startBottles, int takeDown) {
47+
var stop = startBottles - takeDown + 1;
48+
var output = new StringBuilder();
49+
50+
for (var i = startBottles; i >= stop; i--) {
51+
if (i != startBottles) {
52+
output.append("\n");
53+
}
54+
output.append(verse(i));
55+
}
56+
57+
return output.toString();
58+
}
59+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
[d4ccf8fc-01dc-48c0-a201-4fbeb30f2d03]
13+
description = "verse -> single verse -> first generic verse"
14+
15+
[0f0aded3-472a-4c64-b842-18d4f1f5f030]
16+
description = "verse -> single verse -> last generic verse"
17+
18+
[f61f3c97-131f-459e-b40a-7428f3ed99d9]
19+
description = "verse -> single verse -> verse with 2 bottles"
20+
21+
[05eadba9-5dbd-401e-a7e8-d17cc9baa8e0]
22+
description = "verse -> single verse -> verse with 1 bottle"
23+
24+
[a4a28170-83d6-4dc1-bd8b-319b6abb6a80]
25+
description = "lyrics -> multiple verses -> first two verses"
26+
27+
[3185d438-c5ac-4ce6-bcd3-02c9ff1ed8db]
28+
description = "lyrics -> multiple verses -> last three verses"
29+
30+
[28c1584a-0e51-4b65-9ae2-fbc0bf4bbb28]
31+
description = "lyrics -> multiple verses -> all verses"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apply plugin: "java"
2+
apply plugin: "eclipse"
3+
apply plugin: "idea"
4+
5+
// set default encoding to UTF-8
6+
compileJava.options.encoding = "UTF-8"
7+
compileTestJava.options.encoding = "UTF-8"
8+
9+
repositories {
10+
mavenCentral()
11+
}
12+
13+
dependencies {
14+
testImplementation "junit:junit:4.13"
15+
testImplementation "org.assertj:assertj-core:3.15.0"
16+
}
17+
18+
test {
19+
testLogging {
20+
exceptionFormat = 'full'
21+
showStandardStreams = true
22+
events = ["passed", "failed", "skipped"]
23+
}
24+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class BottleSong {
2+
3+
String recite(int startBottles, int takeDown) {
4+
throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
5+
}
6+
7+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import org.junit.Test;
2+
import org.junit.Ignore;
3+
import org.junit.Before;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
public class BottleSongTest {
8+
9+
private BottleSong bottleSong;
10+
11+
@Before
12+
public void setup() {
13+
bottleSong = new BottleSong();
14+
}
15+
16+
@Test
17+
public void firstGenericVerse() {
18+
assertThat(bottleSong.recite(10, 1)).isEqualTo(
19+
"Ten green bottles hanging on the wall,\n" +
20+
"Ten green bottles hanging on the wall,\n" +
21+
"And if one green bottle should accidentally fall,\n" +
22+
"There'll be nine green bottles hanging on the wall.\n"
23+
);
24+
}
25+
26+
@Ignore("Remove to run test")
27+
@Test
28+
public void lastGenericVerse() {
29+
assertThat(bottleSong.recite(3, 1)).isEqualTo(
30+
"Three green bottles hanging on the wall,\n" +
31+
"Three green bottles hanging on the wall,\n" +
32+
"And if one green bottle should accidentally fall,\n" +
33+
"There'll be two green bottles hanging on the wall.\n"
34+
);
35+
}
36+
37+
@Ignore("Remove to run test")
38+
@Test
39+
public void verseWithTwoBottles() {
40+
assertThat(bottleSong.recite(2, 1)).isEqualTo(
41+
"Two green bottles hanging on the wall,\n" +
42+
"Two green bottles hanging on the wall,\n" +
43+
"And if one green bottle should accidentally fall,\n" +
44+
"There'll be one green bottle hanging on the wall.\n"
45+
);
46+
}
47+
48+
@Ignore("Remove to run test")
49+
@Test
50+
public void verseWithOneBottle() {
51+
assertThat(bottleSong.recite(1, 1)).isEqualTo(
52+
"One green bottle hanging on the wall,\n" +
53+
"One green bottle hanging on the wall,\n" +
54+
"And if one green bottle should accidentally fall,\n" +
55+
"There'll be no green bottles hanging on the wall.\n"
56+
);
57+
}
58+
59+
@Ignore("Remove to run test")
60+
@Test
61+
public void firstTwoVerses() {
62+
assertThat(bottleSong.recite(10, 2)).isEqualTo(
63+
"Ten green bottles hanging on the wall,\n" +
64+
"Ten green bottles hanging on the wall,\n" +
65+
"And if one green bottle should accidentally fall,\n" +
66+
"There'll be nine green bottles hanging on the wall.\n" +
67+
"\n" +
68+
"Nine green bottles hanging on the wall,\n" +
69+
"Nine green bottles hanging on the wall,\n" +
70+
"And if one green bottle should accidentally fall,\n" +
71+
"There'll be eight green bottles hanging on the wall.\n"
72+
);
73+
}
74+
75+
@Ignore("Remove to run test")
76+
@Test
77+
public void lastThreeVerses() {
78+
assertThat(bottleSong.recite(3, 3)).isEqualTo(
79+
"Three green bottles hanging on the wall,\n" +
80+
"Three green bottles hanging on the wall,\n" +
81+
"And if one green bottle should accidentally fall,\n" +
82+
"There'll be two green bottles hanging on the wall.\n" +
83+
"\n" +
84+
"Two green bottles hanging on the wall,\n" +
85+
"Two green bottles hanging on the wall,\n" +
86+
"And if one green bottle should accidentally fall,\n" +
87+
"There'll be one green bottle hanging on the wall.\n" +
88+
"\n" +
89+
"One green bottle hanging on the wall,\n" +
90+
"One green bottle hanging on the wall,\n" +
91+
"And if one green bottle should accidentally fall,\n" +
92+
"There'll be no green bottles hanging on the wall.\n"
93+
);
94+
}
95+
96+
@Ignore("Remove to run test")
97+
@Test
98+
public void allVerses() {
99+
assertThat(bottleSong.recite(10, 10))
100+
.isEqualTo(
101+
"Ten green bottles hanging on the wall,\n" +
102+
"Ten green bottles hanging on the wall,\n" +
103+
"And if one green bottle should accidentally fall,\n" +
104+
"There'll be nine green bottles hanging on the wall.\n" +
105+
"\n" +
106+
"Nine green bottles hanging on the wall,\n" +
107+
"Nine green bottles hanging on the wall,\n" +
108+
"And if one green bottle should accidentally fall,\n" +
109+
"There'll be eight green bottles hanging on the wall.\n" +
110+
"\n" +
111+
"Eight green bottles hanging on the wall,\n" +
112+
"Eight green bottles hanging on the wall,\n" +
113+
"And if one green bottle should accidentally fall,\n" +
114+
"There'll be seven green bottles hanging on the wall.\n" +
115+
"\n" +
116+
"Seven green bottles hanging on the wall,\n" +
117+
"Seven green bottles hanging on the wall,\n" +
118+
"And if one green bottle should accidentally fall,\n" +
119+
"There'll be six green bottles hanging on the wall.\n" +
120+
"\n" +
121+
"Six green bottles hanging on the wall,\n" +
122+
"Six green bottles hanging on the wall,\n" +
123+
"And if one green bottle should accidentally fall,\n" +
124+
"There'll be five green bottles hanging on the wall.\n" +
125+
"\n" +
126+
"Five green bottles hanging on the wall,\n" +
127+
"Five green bottles hanging on the wall,\n" +
128+
"And if one green bottle should accidentally fall,\n" +
129+
"There'll be four green bottles hanging on the wall.\n" +
130+
"\n" +
131+
"Four green bottles hanging on the wall,\n" +
132+
"Four green bottles hanging on the wall,\n" +
133+
"And if one green bottle should accidentally fall,\n" +
134+
"There'll be three green bottles hanging on the wall.\n" +
135+
"\n" +
136+
"Three green bottles hanging on the wall,\n" +
137+
"Three green bottles hanging on the wall,\n" +
138+
"And if one green bottle should accidentally fall,\n" +
139+
"There'll be two green bottles hanging on the wall.\n" +
140+
"\n" +
141+
"Two green bottles hanging on the wall,\n" +
142+
"Two green bottles hanging on the wall,\n" +
143+
"And if one green bottle should accidentally fall,\n" +
144+
"There'll be one green bottle hanging on the wall.\n" +
145+
"\n" +
146+
"One green bottle hanging on the wall,\n" +
147+
"One green bottle hanging on the wall,\n" +
148+
"And if one green bottle should accidentally fall,\n" +
149+
"There'll be no green bottles hanging on the wall.\n"
150+
);
151+
}
152+
}

exercises/settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ include 'practice:binary-search'
3535
include 'practice:binary-search-tree'
3636
include 'practice:bob'
3737
include 'practice:book-store'
38+
include 'practice:bottle-song'
3839
include 'practice:bowling'
3940
include 'practice:change'
4041
include 'practice:circular-buffer'

0 commit comments

Comments
 (0)