From b86729a2513fddce7faf28f2d568e47affa84f5c Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:02:21 +0200 Subject: [PATCH 1/7] Run bin/configlet sync --- .../practice/wordy/.docs/instructions.md | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/exercises/practice/wordy/.docs/instructions.md b/exercises/practice/wordy/.docs/instructions.md index f65b05ac..aafb9ee5 100644 --- a/exercises/practice/wordy/.docs/instructions.md +++ b/exercises/practice/wordy/.docs/instructions.md @@ -40,8 +40,7 @@ Now, perform the other three operations. Handle a set of operations, in sequence. -Since these are verbal word problems, evaluate the expression from -left-to-right, _ignoring the typical order of operations._ +Since these are verbal word problems, evaluate the expression from left-to-right, _ignoring the typical order of operations._ > What is 5 plus 13 plus 6? @@ -49,20 +48,12 @@ left-to-right, _ignoring the typical order of operations._ > What is 3 plus 2 multiplied by 3? -15 (i.e. not 9) +15 (i.e. not 9) ## Iteration 4 — Errors The parser should reject: -* Unsupported operations ("What is 52 cubed?") -* Non-math questions ("Who is the President of the United States") -* Word problems with invalid syntax ("What is 1 plus plus 2?") - -## Bonus — Exponentials - -If you'd like, handle exponentials. - -> What is 2 raised to the 5th power? - -32 +- Unsupported operations ("What is 52 cubed?") +- Non-math questions ("Who is the President of the United States") +- Word problems with invalid syntax ("What is 1 plus plus 2?") From 45cf0a7b2de03bce8ff4ac1e3e8beac0dfd8e837 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:03:33 +0200 Subject: [PATCH 2/7] Drop strict types comments --- exercises/practice/wordy/.meta/example.php | 22 ---------------------- exercises/practice/wordy/WordyTest.php | 22 ---------------------- 2 files changed, 44 deletions(-) diff --git a/exercises/practice/wordy/.meta/example.php b/exercises/practice/wordy/.meta/example.php index dc368102..d5dc9e34 100644 --- a/exercises/practice/wordy/.meta/example.php +++ b/exercises/practice/wordy/.meta/example.php @@ -1,27 +1,5 @@ . - * - * To disable strict typing, comment out the directive below. - */ - declare(strict_types=1); function calculate($question = "") diff --git a/exercises/practice/wordy/WordyTest.php b/exercises/practice/wordy/WordyTest.php index b1f4e00b..a5c33142 100644 --- a/exercises/practice/wordy/WordyTest.php +++ b/exercises/practice/wordy/WordyTest.php @@ -1,27 +1,5 @@ . - * - * To disable strict typing, comment out the directive below. - */ - declare(strict_types=1); use PHPUnit\Framework\TestCase; From 54a26e3cba60725e303672ee98e4f9e02af2ebcd Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:15:32 +0200 Subject: [PATCH 3/7] Add and sync test meta data to tests --- exercises/practice/wordy/WordyTest.php | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/exercises/practice/wordy/WordyTest.php b/exercises/practice/wordy/WordyTest.php index a5c33142..6e9931ee 100644 --- a/exercises/practice/wordy/WordyTest.php +++ b/exercises/practice/wordy/WordyTest.php @@ -3,6 +3,7 @@ declare(strict_types=1); use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\TestDox; class WordyTest extends TestCase { @@ -11,83 +12,115 @@ public static function setUpBeforeClass(): void require_once 'Wordy.php'; } + /** uuid: bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0 */ + #[TestDox('addition')] public function testAdd1(): void { $this->assertEquals(2, calculate('What is 1 plus 1?')); } + /** uuid: 79e49e06-c5ae-40aa-a352-7a3a01f70015 */ + #[TestDox('more addition')] public function testAdd2(): void { $this->assertEquals(55, calculate('What is 53 plus 2?')); } + /** uuid: b345dbe0-f733-44e1-863c-5ae3568f3803 */ + #[TestDox('addition with negative numbers')] public function testAddNegativeNumbers(): void { $this->assertEquals(-11, calculate('What is -1 plus -10?')); } + /** uuid: cd070f39-c4cc-45c4-97fb-1be5e5846f87 */ + #[TestDox('large addition')] public function testAddMoreDigits(): void { $this->assertEquals(45801, calculate('What is 123 plus 45678?')); } + /** uuid: 0d86474a-cd93-4649-a4fa-f6109a011191 */ + #[TestDox('subtraction')] public function testSubtract(): void { $this->assertEquals(16, calculate('What is 4 minus -12?')); } + /** uuid: 30bc8395-5500-4712-a0cf-1d788a529be5 */ + #[TestDox('multiplication')] public function testMultiply(): void { $this->assertEquals(-75, calculate('What is -3 multiplied by 25?')); } + /** uuid: 34c36b08-8605-4217-bb57-9a01472c427f */ + #[TestDox('division')] public function testDivide(): void { $this->assertEquals(-11, calculate('What is 33 divided by -3?')); } + /** uuid: da6d2ce4-fb94-4d26-8f5f-b078adad0596 */ + #[TestDox('multiple additions')] public function testAddTwice(): void { $this->assertEquals(3, calculate('What is 1 plus 1 plus 1?')); } + /** uuid: 7fd74c50-9911-4597-be09-8de7f2fea2bb */ + #[TestDox('addition and subtraction')] public function testAddThenSubtract(): void { $this->assertEquals(8, calculate('What is 1 plus 5 minus -2?')); } + /** uuid: b120ffd5-bad6-4e22-81c8-5512e8faf905 */ + #[TestDox('multiple subtraction')] public function testSubtractTwice(): void { $this->assertEquals(3, calculate('What is 20 minus 4 minus 13?')); } + /** uuid: 4f4a5749-ef0c-4f60-841f-abcfaf05d2ae */ + #[TestDox('subtraction then addition')] public function testSubtractThenAdd(): void { $this->assertEquals(14, calculate('What is 17 minus 6 plus 3?')); } + /** uuid: 312d908c-f68f-42c9-aa75-961623cc033f */ + #[TestDox('multiple multiplication')] public function testMultiplyTwice(): void { $this->assertEquals(-12, calculate('What is 2 multiplied by -2 multiplied by 3?')); } + /** uuid: 38e33587-8940-4cc1-bc28-bfd7e3966276 */ + #[TestDox('addition and multiplication')] public function testAddThenMultiply(): void { $this->assertEquals(-8, calculate('What is -3 plus 7 multiplied by -2?')); } + /** uuid: 3c854f97-9311-46e8-b574-92b60d17d394 */ + #[TestDox('multiple division')] public function testDivideTwice(): void { $this->assertEquals(2, calculate('What is -12 divided by 2 divided by -3?')); } + /** uuid: 3ad3e433-8af7-41ec-aa9b-97b42ab49357 */ + #[TestDox('unknown operation')] public function testTooAdvanced(): void { $this->expectException('InvalidArgumentException'); - calculate('What is 53 cubed?'); + calculate('What is 52 cubed?'); } + /** uuid: 8a7e85a8-9e7b-4d46-868f-6d759f4648f8 */ + #[TestDox('Non math question')] public function testIrrelevant(): void { $this->expectException('InvalidArgumentException'); From 98cdef79c36e6cfdb913f6268de3ba818274d76d Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:16:12 +0200 Subject: [PATCH 4/7] Add exercise to bin/auto-sync.txt --- bin/auto-sync.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/auto-sync.txt b/bin/auto-sync.txt index e360a4b7..76fea216 100644 --- a/bin/auto-sync.txt +++ b/bin/auto-sync.txt @@ -71,5 +71,6 @@ strain sublist two-bucket two-fer +wordy yacht zebra-puzzle From a325c92bcab57c3baec466334cb490bd5c5c0263 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:36:56 +0200 Subject: [PATCH 5/7] Adding test cases to match current problem specs --- exercises/practice/wordy/.meta/tests.toml | 31 +++++++- exercises/practice/wordy/WordyTest.php | 89 +++++++++++++++++++++++ 2 files changed, 117 insertions(+), 3 deletions(-) diff --git a/exercises/practice/wordy/.meta/tests.toml b/exercises/practice/wordy/.meta/tests.toml index 912d5760..7ad684d9 100644 --- a/exercises/practice/wordy/.meta/tests.toml +++ b/exercises/practice/wordy/.meta/tests.toml @@ -1,13 +1,38 @@ -# 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. +# 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. [88bf4b28-0de3-4883-93c7-db1b14aa806e] description = "just a number" +include = false +comment = "New requirement incompatible with our solution" + +[18983214-1dfc-4ebd-ac77-c110dde699ce] +description = "just a zero" +include = false +comment = "New requirement incompatible with our solution" + +[607c08ee-2241-4288-916d-dae5455c87e6] +description = "just a negative number" +include = false +comment = "New requirement incompatible with our solution" [bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0] description = "addition" +[bb9f2082-171c-46ad-ad4e-c3f72087c1b5] +description = "addition with a left hand zero" + +[6fa05f17-405a-4742-80ae-5d1a8edb0d5d] +description = "addition with a right hand zero" + [79e49e06-c5ae-40aa-a352-7a3a01f70015] description = "more addition" diff --git a/exercises/practice/wordy/WordyTest.php b/exercises/practice/wordy/WordyTest.php index 6e9931ee..a1651981 100644 --- a/exercises/practice/wordy/WordyTest.php +++ b/exercises/practice/wordy/WordyTest.php @@ -12,6 +12,27 @@ public static function setUpBeforeClass(): void require_once 'Wordy.php'; } + // /** uuid: 88bf4b28-0de3-4883-93c7-db1b14aa806e */ + // #[TestDox('just a number')] + // public function testJustANumber(): void + // { + // $this->assertEquals(5, calculate('What is 5?')); + // } + + // /** uuid: 18983214-1dfc-4ebd-ac77-c110dde699ce */ + // #[TestDox('just a zero')] + // public function testJustAZero(): void + // { + // $this->assertEquals(0, calculate('What is 0?')); + // } + + // /** uuid: 607c08ee-2241-4288-916d-dae5455c87e6 */ + // #[TestDox('just a negative number')] + // public function testJustANegativeNumber(): void + // { + // $this->assertEquals(-123, calculate('What is -123?')); + // } + /** uuid: bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0 */ #[TestDox('addition')] public function testAdd1(): void @@ -19,6 +40,20 @@ public function testAdd1(): void $this->assertEquals(2, calculate('What is 1 plus 1?')); } + /** uuid: bb9f2082-171c-46ad-ad4e-c3f72087c1b5 */ + #[TestDox('addition with a left hand zero')] + public function testAdditionWithALeftHandZero(): void + { + $this->assertEquals(2, calculate('What is 0 plus 2?')); + } + + /** uuid: 6fa05f17-405a-4742-80ae-5d1a8edb0d5d */ + #[TestDox('addition with a right hand zero')] + public function testAdditionWithARightHandZero(): void + { + $this->assertEquals(3, calculate('What is 3 plus 0?')); + } + /** uuid: 79e49e06-c5ae-40aa-a352-7a3a01f70015 */ #[TestDox('more addition')] public function testAdd2(): void @@ -127,4 +162,58 @@ public function testIrrelevant(): void calculate('Who is the president of the United States?'); } + + /** uuid: 42d78b5f-dbd7-4cdb-8b30-00f794bb24cf */ + #[TestDox('reject problem missing an operand')] + public function testRejectProblemMissingAnOperand(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is 1 plus?'); + } + + /** uuid: c2c3cbfc-1a72-42f2-b597-246e617e66f5 */ + #[TestDox('reject problem with no operands or operators')] + public function testRejectProblemWithNoOperandsOrOperators(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is?'); + } + + /** uuid: 4b3df66d-6ed5-4c95-a0a1-d38891fbdab6 */ + #[TestDox('reject two operations in a row')] + public function testRejectTwoOperationsInARow(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is 1 plus plus 2?'); + } + + /** uuid: 6abd7a50-75b4-4665-aa33-2030fd08bab1 */ + #[TestDox('reject two numbers in a row')] + public function testRejectTwoNumbersInARow(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is 1 plus 2 1?'); + } + + /** uuid: 10a56c22-e0aa-405f-b1d2-c642d9c4c9de */ + #[TestDox('reject postfix notation')] + public function testRejectPostfixNotation(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is 1 2 plus?'); + } + + /** uuid: 0035bc63-ac43-4bb5-ad6d-e8651b7d954e */ + #[TestDox('reject prefix notation')] + public function testRejectPrefixNotation(): void + { + $this->expectException('InvalidArgumentException'); + + calculate('What is plus 1 2?'); + } } From 4d15458ab28543dd89331c3dc5b21226c4cf6dc1 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 15:51:53 +0200 Subject: [PATCH 6/7] Add test cases (new requirement in problem specs) --- exercises/practice/wordy/.meta/example.php | 40 ++++++++++++---------- exercises/practice/wordy/.meta/tests.toml | 6 ---- exercises/practice/wordy/WordyTest.php | 40 +++++++++++----------- 3 files changed, 42 insertions(+), 44 deletions(-) diff --git a/exercises/practice/wordy/.meta/example.php b/exercises/practice/wordy/.meta/example.php index d5dc9e34..6f7c4f0a 100644 --- a/exercises/practice/wordy/.meta/example.php +++ b/exercises/practice/wordy/.meta/example.php @@ -5,31 +5,35 @@ function calculate($question = "") { preg_match( - "/What is (-?\d+) (plus|minus|multiplied by|divided by) " - . "(-?\d+)(?: (plus|minus|multiplied by|divided by) (-?\d+))?\?/", + "/What is (-?\d+)(?: (plus|minus|multiplied by|divided by) " + . "(-?\d+)(?: (plus|minus|multiplied by|divided by) (-?\d+))?)?\?/", $question, $matches ); - if (empty($matches[2])) { + if (!isset($matches[1])) { throw new InvalidArgumentException(); } - switch ($matches[2]) { - case 'plus': - $number = $matches[1] + $matches[3]; - break; - case 'minus': - $number = $matches[1] - $matches[3]; - break; - case 'multiplied by': - $number = $matches[1] * $matches[3]; - break; - case 'divided by': - $number = $matches[1] / $matches[3]; - break; - default: - $number = 0; + $number = $matches[1]; + + if (isset($matches[2]) && isset($matches[3])) { + switch ($matches[2]) { + case 'plus': + $number = $matches[1] + $matches[3]; + break; + case 'minus': + $number = $matches[1] - $matches[3]; + break; + case 'multiplied by': + $number = $matches[1] * $matches[3]; + break; + case 'divided by': + $number = $matches[1] / $matches[3]; + break; + default: + throw new InvalidArgumentException(); + } } if (isset($matches[4]) && isset($matches[5])) { diff --git a/exercises/practice/wordy/.meta/tests.toml b/exercises/practice/wordy/.meta/tests.toml index 7ad684d9..a0a83ed0 100644 --- a/exercises/practice/wordy/.meta/tests.toml +++ b/exercises/practice/wordy/.meta/tests.toml @@ -11,18 +11,12 @@ [88bf4b28-0de3-4883-93c7-db1b14aa806e] description = "just a number" -include = false -comment = "New requirement incompatible with our solution" [18983214-1dfc-4ebd-ac77-c110dde699ce] description = "just a zero" -include = false -comment = "New requirement incompatible with our solution" [607c08ee-2241-4288-916d-dae5455c87e6] description = "just a negative number" -include = false -comment = "New requirement incompatible with our solution" [bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0] description = "addition" diff --git a/exercises/practice/wordy/WordyTest.php b/exercises/practice/wordy/WordyTest.php index a1651981..5315de51 100644 --- a/exercises/practice/wordy/WordyTest.php +++ b/exercises/practice/wordy/WordyTest.php @@ -12,26 +12,26 @@ public static function setUpBeforeClass(): void require_once 'Wordy.php'; } - // /** uuid: 88bf4b28-0de3-4883-93c7-db1b14aa806e */ - // #[TestDox('just a number')] - // public function testJustANumber(): void - // { - // $this->assertEquals(5, calculate('What is 5?')); - // } - - // /** uuid: 18983214-1dfc-4ebd-ac77-c110dde699ce */ - // #[TestDox('just a zero')] - // public function testJustAZero(): void - // { - // $this->assertEquals(0, calculate('What is 0?')); - // } - - // /** uuid: 607c08ee-2241-4288-916d-dae5455c87e6 */ - // #[TestDox('just a negative number')] - // public function testJustANegativeNumber(): void - // { - // $this->assertEquals(-123, calculate('What is -123?')); - // } + /** uuid: 88bf4b28-0de3-4883-93c7-db1b14aa806e */ + #[TestDox('just a number')] + public function testJustANumber(): void + { + $this->assertEquals(5, calculate('What is 5?')); + } + + /** uuid: 18983214-1dfc-4ebd-ac77-c110dde699ce */ + #[TestDox('just a zero')] + public function testJustAZero(): void + { + $this->assertEquals(0, calculate('What is 0?')); + } + + /** uuid: 607c08ee-2241-4288-916d-dae5455c87e6 */ + #[TestDox('just a negative number')] + public function testJustANegativeNumber(): void + { + $this->assertEquals(-123, calculate('What is -123?')); + } /** uuid: bb8c655c-cf42-4dfc-90e0-152fcfd8d4e0 */ #[TestDox('addition')] From dcf01d00f647d17604c0112dacd599e8b76e6b41 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Oct 2025 16:00:28 +0200 Subject: [PATCH 7/7] Set difficulty to 5 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index bf8deaeb..b3614357 100644 --- a/config.json +++ b/config.json @@ -784,7 +784,7 @@ "uuid": "85408bdd-3c22-4b5a-9c61-044ddfb0c3ac", "practices": [], "prerequisites": [], - "difficulty": 1, + "difficulty": 5, "topics": [ "parsing", "strings",