Skip to content

Commit

Permalink
Add the proverb exercise.
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelBunker committed Aug 5, 2023
1 parent cd1ca26 commit 50ad1c4
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 0 deletions.
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@
"difficulty": 2,
"topics": ["filtering", "strings"]
},
{
"slug": "proverb",
"name": "Proverb",
"uuid": "75519a64-8237-49e5-927f-c5974816258e",
"practices": [],
"prerequisites": [],
"difficulty": 2,
"topics": [
"strings"
]
},
{
"slug": "gigasecond",
"name": "Gigasecond",
Expand Down
17 changes: 17 additions & 0 deletions exercises/practice/proverb/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Instructions

For want of a horseshoe nail, a kingdom was lost, or so the saying goes.

Given a list of inputs, generate the relevant proverb. For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme:

```text
For want of a nail the shoe was lost.
For want of a shoe the horse was lost.
For want of a horse the rider was lost.
For want of a rider the message was lost.
For want of a message the battle was lost.
For want of a battle the kingdom was lost.
And all for the want of a nail.
```

Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. No line of the output text should be a static, unchanging string; all should vary according to the input given.
10 changes: 10 additions & 0 deletions exercises/practice/proverb/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.",
"authors": ["MichaelBunker"],
"contributors": [],
"files": {
"solution": ["Proverb.php"],
"test": ["ProverbTest.php"],
"example": [".meta/example.php"]
}
}
45 changes: 45 additions & 0 deletions exercises/practice/proverb/.meta/example.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class Proverb
{
public static function recite(array $pieces): array
{
$verses = [];

foreach ($pieces as $index => $piece) {
if ($index == count($pieces) - 1) {
$verses[] = "And all for the want of a $pieces[0].";
continue;
}

$wanted = $pieces[$index + 1];
$verses[] = "For want of a $piece the $wanted was lost.";
}

return $verses;
}
}
33 changes: 33 additions & 0 deletions exercises/practice/proverb/Proverb.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class Proverb
{
public static function recite()
{
throw new \Exception(sprintf('Implement the %s method', __FUNCTION__));
}
}
92 changes: 92 additions & 0 deletions exercises/practice/proverb/ProverbTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class ProverbTest extends PHPUnit\Framework\TestCase
{
public static function setUpBeforeClass(): void
{
require_once 'Proverb.php';
}

public function testNoVerses(): void
{
$pieces = [];
$expected = [];
$this->assertEquals($expected, Proverb::recite($pieces));
}

public function testOneVerse(): void
{
$pieces = ['nail'];
$expected = ['And all for the want of a nail.'];
$this->assertEquals($expected, Proverb::recite($pieces));
}

public function testTwoVerses(): void
{
$pieces = ['nail', 'shoe'];
$expected = ['For want of a nail the shoe was lost.', 'And all for the want of a nail.'];
$this->assertEquals($expected, Proverb::recite($pieces));
}

public function testThreeVerses(): void
{
$pieces = ['nail', 'shoe', 'horse'];
$expected = [
'For want of a nail the shoe was lost.',
'For want of a shoe the horse was lost.',
'And all for the want of a nail.'
];
$this->assertEquals($expected, Proverb::recite($pieces));
}

public function testFullProverb(): void
{
$pieces = ['nail', 'shoe', 'horse', 'rider', 'message', 'battle', 'kingdom'];
$expected = [
'For want of a nail the shoe was lost.',
'For want of a shoe the horse was lost.',
'For want of a horse the rider was lost.',
'For want of a rider the message was lost.',
'For want of a message the battle was lost.',
'For want of a battle the kingdom was lost.',
'And all for the want of a nail.'
];
$this->assertEquals($expected, Proverb::recite($pieces));
}

public function testFourModernizedVerses(): void
{
$pieces = ['pin', 'gun', 'soldier', 'battle'];
$expected = [
'For want of a pin the gun was lost.',
'For want of a gun the soldier was lost.',
'For want of a soldier the battle was lost.',
'And all for the want of a pin.'
];
$this->assertEquals($expected, Proverb::recite($pieces));
}
}

0 comments on commit 50ad1c4

Please sign in to comment.