diff --git a/config.json b/config.json index 957503a0..bed83b3f 100644 --- a/config.json +++ b/config.json @@ -1196,6 +1196,14 @@ "prerequisites": [], "difficulty": 6 }, + { + "slug": "food-chain", + "name": "Food Chain", + "uuid": "9fa82e62-1dd3-45c4-ae33-6c854a7b92b5", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, { "slug": "kindergarten-garden", "name": "Kindergarten Garden", diff --git a/exercises/practice/food-chain/.docs/instructions.md b/exercises/practice/food-chain/.docs/instructions.md new file mode 100644 index 00000000..125820e3 --- /dev/null +++ b/exercises/practice/food-chain/.docs/instructions.md @@ -0,0 +1,64 @@ +# Instructions + +Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'. + +While you could copy/paste the lyrics, or read them from a file, this problem is much more interesting if you approach it algorithmically. + +This is a [cumulative song][cumulative-song] of unknown origin. + +This is one of many common variants. + +```text +I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cat. +Imagine that, to swallow a cat! +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a dog. +What a hog, to swallow a dog! +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a goat. +Just opened her throat and swallowed a goat! +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cow. +I don't know how she swallowed a cow! +She swallowed the cow to catch the goat. +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a horse. +She's dead, of course! +``` + +[cumulative-song]: https://en.wikipedia.org/wiki/Cumulative_song diff --git a/exercises/practice/food-chain/.meta/config.json b/exercises/practice/food-chain/.meta/config.json new file mode 100644 index 00000000..a740eb34 --- /dev/null +++ b/exercises/practice/food-chain/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "FoodChain.php" + ], + "test": [ + "FoodChainTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" +} diff --git a/exercises/practice/food-chain/.meta/example.php b/exercises/practice/food-chain/.meta/example.php new file mode 100644 index 00000000..ecace289 --- /dev/null +++ b/exercises/practice/food-chain/.meta/example.php @@ -0,0 +1,62 @@ + 1; $verseNumber--) { + $text = sprintf( + "She swallowed the %s to catch the %s%s", + self::VERSE[$verseNumber][0], + self::VERSE[$verseNumber - 1][0], + $verseNumber !== 3 ? "." : "" + ); + if ($verseNumber === 3) { + $text .= " that wriggled and jiggled and tickled inside her."; + } + $result[] = $text; + } + $result[] = self::VERSE[$verseNumber][1]; + return $result; + } + + public function verses(int $start, int $end): array + { + if ($start < 1 || $start > $end || $end > 8) { + return $this->verse(1); + } + $s = $this->verse($start); + while ($start < $end) { + $start++; + $s[] = ""; + $s = array_merge($s, $this->verse($start)); + } + return $s; + } + + public function song(): array + { + return $this->verses(1, 8); + } +} diff --git a/exercises/practice/food-chain/.meta/tests.toml b/exercises/practice/food-chain/.meta/tests.toml new file mode 100644 index 00000000..30c5b980 --- /dev/null +++ b/exercises/practice/food-chain/.meta/tests.toml @@ -0,0 +1,40 @@ +# 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. + +[751dce68-9412-496e-b6e8-855998c56166] +description = "fly" + +[6c56f861-0c5e-4907-9a9d-b2efae389379] +description = "spider" + +[3edf5f33-bef1-4e39-ae67-ca5eb79203fa] +description = "bird" + +[e866a758-e1ff-400e-9f35-f27f28cc288f] +description = "cat" + +[3f02c30e-496b-4b2a-8491-bc7e2953cafb] +description = "dog" + +[4b3fd221-01ea-46e0-825b-5734634fbc59] +description = "goat" + +[1b707da9-7001-4fac-941f-22ad9c7a65d4] +description = "cow" + +[3cb10d46-ae4e-4d2c-9296-83c9ffc04cdc] +description = "horse" + +[22b863d5-17e4-4d1e-93e4-617329a5c050] +description = "multiple verses" + +[e626b32b-745c-4101-bcbd-3b13456893db] +description = "full song" diff --git a/exercises/practice/food-chain/FoodChain.php b/exercises/practice/food-chain/FoodChain.php new file mode 100644 index 00000000..8cd60bae --- /dev/null +++ b/exercises/practice/food-chain/FoodChain.php @@ -0,0 +1,43 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class FoodChain +{ + public function verse(int $verseNumber): array + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } + + public function verses(int $start, int $end): array + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } + + public function song(): array + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/food-chain/FoodChainTest.php b/exercises/practice/food-chain/FoodChainTest.php new file mode 100644 index 00000000..38de7dba --- /dev/null +++ b/exercises/practice/food-chain/FoodChainTest.php @@ -0,0 +1,225 @@ +foodChain = new FoodChain(); + } + + /** + * uuid: 751dce68-9412-496e-b6e8-855998c56166 + */ + public function testFly(): void + { + $expected = [ + "I know an old lady who swallowed a fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(1)); + } + + /** + * uuid: 6c56f861-0c5e-4907-9a9d-b2efae389379 + */ + public function testSpider(): void + { + $expected = [ + "I know an old lady who swallowed a spider.", + "It wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(2)); + } + + /** + * uuid: 3edf5f33-bef1-4e39-ae67-ca5eb79203fa + */ + public function testBird(): void + { + $expected = [ + "I know an old lady who swallowed a bird.", + "How absurd to swallow a bird!", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(3)); + } + + /** + * uuid: e866a758-e1ff-400e-9f35-f27f28cc288f + */ + public function testCat(): void + { + $expected = [ + "I know an old lady who swallowed a cat.", + "Imagine that, to swallow a cat!", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(4)); + } + + /** + * uuid: 3f02c30e-496b-4b2a-8491-bc7e2953cafb + */ + public function testDog(): void + { + $expected = [ + "I know an old lady who swallowed a dog.", + "What a hog, to swallow a dog!", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(5)); + } + + /** + * uuid: 4b3fd221-01ea-46e0-825b-5734634fbc59 + */ + public function testGoat(): void + { + $expected = [ + "I know an old lady who swallowed a goat.", + "Just opened her throat and swallowed a goat!", + "She swallowed the goat to catch the dog.", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(6)); + } + + /** + * uuid: 1b707da9-7001-4fac-941f-22ad9c7a65d4 + */ + public function testCow(): void + { + $expected = [ + "I know an old lady who swallowed a cow.", + "I don't know how she swallowed a cow!", + "She swallowed the cow to catch the goat.", + "She swallowed the goat to catch the dog.", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verse(7)); + } + + /** + * uuid: 3cb10d46-ae4e-4d2c-9296-83c9ffc04cdc + */ + public function testHorse(): void + { + $expected = [ + "I know an old lady who swallowed a horse.", + "She's dead, of course!" + ]; + $this->assertEquals($expected, $this->foodChain->verse(8)); + } + + /** + * uuid: 22b863d5-17e4-4d1e-93e4-617329a5c050 + */ + public function testMultipleVerses(): void + { + $expected = [ + "I know an old lady who swallowed a fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a spider.", + "It wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a bird.", + "How absurd to swallow a bird!", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die." + ]; + $this->assertEquals($expected, $this->foodChain->verses(1, 3)); + } + /** + * uuid: e626b32b-745c-4101-bcbd-3b13456893db + */ + public function testFullSong(): void + { + $expected = [ + "I know an old lady who swallowed a fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a spider.", + "It wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a bird.", + "How absurd to swallow a bird!", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a cat.", + "Imagine that, to swallow a cat!", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a dog.", + "What a hog, to swallow a dog!", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a goat.", + "Just opened her throat and swallowed a goat!", + "She swallowed the goat to catch the dog.", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a cow.", + "I don't know how she swallowed a cow!", + "She swallowed the cow to catch the goat.", + "She swallowed the goat to catch the dog.", + "She swallowed the dog to catch the cat.", + "She swallowed the cat to catch the bird.", + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.", + "She swallowed the spider to catch the fly.", + "I don't know why she swallowed the fly. Perhaps she'll die.", + "", + "I know an old lady who swallowed a horse.", + "She's dead, of course!" + ]; + $this->assertEquals($expected, $this->foodChain->song()); + } +}