diff --git a/config.json b/config.json index 88334ceb..f13890aa 100644 --- a/config.json +++ b/config.json @@ -997,6 +997,14 @@ "strings" ] }, + { + "slug": "strain", + "name": "Strain", + "uuid": "8872a713-cb44-4769-a67b-85bbd944a726", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "pig-latin", "name": "Pig Latin", @@ -1021,6 +1029,14 @@ "transforming" ] }, + { + "slug": "sublist", + "name": "Sublist", + "uuid": "a5323160-bb75-4dd7-8800-789a83cd7008", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "poker", "name": "Poker", @@ -1148,6 +1164,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "slug": "isbn-verifier", + "name": "ISBN Verifier", + "uuid": "f7309216-0ba7-4990-acd7-4a47eca949fb", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "say", "name": "Say", diff --git a/exercises/practice/isbn-verifier/.docs/instructions.md b/exercises/practice/isbn-verifier/.docs/instructions.md new file mode 100644 index 00000000..4a0244e5 --- /dev/null +++ b/exercises/practice/isbn-verifier/.docs/instructions.md @@ -0,0 +1,42 @@ +# Instructions + +The [ISBN-10 verification process][isbn-verification] is used to validate book identification numbers. +These normally contain dashes and look like: `3-598-21508-8` + +## ISBN + +The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only). +In the case the check character is an X, this represents the value '10'. +These may be communicated with or without hyphens, and can be checked for their validity by the following formula: + +```text +(d₁ * 10 + d₂ * 9 + d₃ * 8 + d₄ * 7 + d₅ * 6 + d₆ * 5 + d₇ * 4 + d₈ * 3 + d₉ * 2 + d₁₀ * 1) mod 11 == 0 +``` + +If the result is 0, then it is a valid ISBN-10, otherwise it is invalid. + +## Example + +Let's take the ISBN-10 `3-598-21508-8`. +We plug it in to the formula, and get: + +```text +(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0 +``` + +Since the result is 0, this proves that our ISBN is valid. + +## Task + +Given a string the program should check if the provided string is a valid ISBN-10. +Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. + +The program should be able to verify ISBN-10 both with and without separating dashes. + +## Caveats + +Converting from strings to numbers can be tricky in certain languages. +Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10'). +For instance `3-598-21507-X` is a valid ISBN-10. + +[isbn-verification]: https://en.wikipedia.org/wiki/International_Standard_Book_Number diff --git a/exercises/practice/isbn-verifier/.meta/config.json b/exercises/practice/isbn-verifier/.meta/config.json new file mode 100644 index 00000000..8fbad0ce --- /dev/null +++ b/exercises/practice/isbn-verifier/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "IsbnVerifier.php" + ], + "test": [ + "IsbnVerifierTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Check if a given string is a valid ISBN-10 number.", + "source": "Converting a string into a number and some basic processing utilizing a relatable real world example.", + "source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation" +} diff --git a/exercises/practice/isbn-verifier/.meta/example.php b/exercises/practice/isbn-verifier/.meta/example.php new file mode 100644 index 00000000..e575c2e7 --- /dev/null +++ b/exercises/practice/isbn-verifier/.meta/example.php @@ -0,0 +1,34 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class IsbnVerifier +{ + public function isValid(string $isbn): bool + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/isbn-verifier/IsbnVerifierTest.php b/exercises/practice/isbn-verifier/IsbnVerifierTest.php new file mode 100644 index 00000000..563a35d3 --- /dev/null +++ b/exercises/practice/isbn-verifier/IsbnVerifierTest.php @@ -0,0 +1,170 @@ +isbnVerifier = new IsbnVerifier(); + } + + /** + * uuid: 0caa3eac-d2e3-4c29-8df8-b188bc8c9292 + */ + public function testValidIsbn(): void + { + $this->assertTrue($this->isbnVerifier->isValid('3-598-21508-8')); + } + + /** + * uuid: 19f76b53-7c24-45f8-87b8-4604d0ccd248 + */ + public function testInvalidIsbnCheckDigit(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-21508-9')); + } + + /** + * uuid: 4164bfee-fb0a-4a1c-9f70-64c6a1903dcd + */ + public function testValidIsbnWithACheckDigitOf10(): void + { + $this->assertTrue($this->isbnVerifier->isValid('3-598-21507-X')); + } + + /** + * uuid: 3ed50db1-8982-4423-a993-93174a20825c + */ + public function testCheckDigitIsACharacterOtherThanX(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-21507-A')); + } + + /** + * uuid: 9416f4a5-fe01-4b61-a07b-eb75892ef562 + */ + public function testInvalidCheckDigitInIsbnIsNotTreatedAsZero(): void + { + $this->assertFalse($this->isbnVerifier->isValid('4-598-21507-B')); + } + + /** + * uuid: c19ba0c4-014f-4dc3-a63f-ff9aefc9b5ec + */ + public function testInvalidCharacterInIsbnIsNotTreatedAsZero(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-P1581-X')); + } + + /** + * uuid: 28025280-2c39-4092-9719-f3234b89c627 + */ + public function testXIsOnlyValidAsACheckDigit(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-2X507-9')); + } + + /** + * uuid: f6294e61-7e79-46b3-977b-f48789a4945b + */ + public function testValidIsbnWithoutSeparatingDashes(): void + { + $this->assertTrue($this->isbnVerifier->isValid('3598215088')); + } + + /** + * uuid: 185ab99b-3a1b-45f3-aeec-b80d80b07f0b + */ + public function testIsbnWithoutSeparatingDashesAndXAsCheckDigit(): void + { + $this->assertTrue($this->isbnVerifier->isValid('359821507X')); + } + + /** + * uuid: 7725a837-ec8e-4528-a92a-d981dd8cf3e2 + */ + public function testIsbnWithoutCheckDigitAndDashes(): void + { + $this->assertFalse($this->isbnVerifier->isValid('359821507')); + } + + /** + * uuid: 47e4dfba-9c20-46ed-9958-4d3190630bdf + */ + public function testTooLongIsbnAndNoDashes(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3598215078X')); + } + + /** + * uuid: 737f4e91-cbba-4175-95bf-ae630b41fb60 + */ + public function testTooShortIsbn(): void + { + $this->assertFalse($this->isbnVerifier->isValid('00')); + } + + /** + * uuid: 5458a128-a9b6-4ff8-8afb-674e74567cef + */ + public function testIsbnWithoutCheckDigit(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-21507')); + } + + /** + * uuid: 70b6ad83-d0a2-4ca7-a4d5-a9ab731800f7 + */ + public function testCheckDigitOfXShouldNotBeUsedForZero(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3-598-21515-X')); + } + + /** + * uuid: 94610459-55ab-4c35-9b93-ff6ea1a8e562 + */ + public function testEmptyIsbn(): void + { + $this->assertFalse($this->isbnVerifier->isValid('')); + } + + /** + * uuid: 7bff28d4-d770-48cc-80d6-b20b3a0fb46c + */ + public function testInputIs9Characters(): void + { + $this->assertFalse($this->isbnVerifier->isValid('134456729')); + } + + /** + * uuid: ed6e8d1b-382c-4081-8326-8b772c581fec + */ + public function testInvalidCharactersAreNotIgnoredAfterCheckingLength(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3132P34035')); + } + + /** + * uuid: daad3e58-ce00-4395-8a8e-e3eded1cdc86 + */ + public function testCatchInvalidCharactersInOnOtherwiseValidIsbn(): void + { + $this->assertFalse($this->isbnVerifier->isValid('3598P215088')); + } + + /** + * uuid: fb5e48d8-7c03-4bfb-a088-b101df16fdc3 + */ + public function testInputIsTooLongButContainsAValidIsbn(): void + { + $this->assertFalse($this->isbnVerifier->isValid('98245726788')); + } +} diff --git a/exercises/practice/strain/.docs/instructions.md b/exercises/practice/strain/.docs/instructions.md new file mode 100644 index 00000000..3469ae65 --- /dev/null +++ b/exercises/practice/strain/.docs/instructions.md @@ -0,0 +1,29 @@ +# Instructions + +Implement the `keep` and `discard` operation on collections. +Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false. + +For example, given the collection of numbers: + +- 1, 2, 3, 4, 5 + +And the predicate: + +- is the number even? + +Then your keep operation should produce: + +- 2, 4 + +While your discard operation should produce: + +- 1, 3, 5 + +Note that the union of keep and discard is all the elements. + +The functions may be called `keep` and `discard`, or they may need different names in order to not clash with existing functions or concepts in your language. + +## Restrictions + +Keep your hands off that filter/reject/whatchamacallit functionality provided by your standard library! +Solve this one yourself using other basic tools instead. diff --git a/exercises/practice/strain/.meta/config.json b/exercises/practice/strain/.meta/config.json new file mode 100644 index 00000000..896eef91 --- /dev/null +++ b/exercises/practice/strain/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "Strain.php" + ], + "test": [ + "StrainTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Implement the `keep` and `discard` operation on collections.", + "source": "Conversation with James Edward Gray II", + "source_url": "http://graysoftinc.com/" +} diff --git a/exercises/practice/strain/.meta/example.php b/exercises/practice/strain/.meta/example.php new file mode 100644 index 00000000..529d0347 --- /dev/null +++ b/exercises/practice/strain/.meta/example.php @@ -0,0 +1,27 @@ +filter($list, $predicate, true); + } + + public function discard(array $list, callable $predicate): array + { + return $this->filter($list, $predicate, false); + } + + private function filter(array $list, callable $predicate, bool $keepMatches): array + { + $results = []; + foreach ($list as $item) { + if ($predicate($item) === $keepMatches) { + $results[] = $item; + } + } + return $results; + } +} diff --git a/exercises/practice/strain/.meta/tests.toml b/exercises/practice/strain/.meta/tests.toml new file mode 100644 index 00000000..3a617b4a --- /dev/null +++ b/exercises/practice/strain/.meta/tests.toml @@ -0,0 +1,52 @@ +# 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. + +[26af8c32-ba6a-4eb3-aa0a-ebd8f136e003] +description = "keep on empty list returns empty list" + +[f535cb4d-e99b-472a-bd52-9fa0ffccf454] +description = "keeps everything" + +[950b8e8e-f628-42a8-85e2-9b30f09cde38] +description = "keeps nothing" + +[92694259-6e76-470c-af87-156bdf75018a] +description = "keeps first and last" + +[938f7867-bfc7-449e-a21b-7b00cbb56994] +description = "keeps neither first nor last" + +[8908e351-4437-4d2b-a0f7-770811e48816] +description = "keeps strings" + +[2728036b-102a-4f1e-a3ef-eac6160d876a] +description = "keeps lists" + +[ef16beb9-8d84-451a-996a-14e80607fce6] +description = "discard on empty list returns empty list" + +[2f42f9bc-8e06-4afe-a222-051b5d8cd12a] +description = "discards everything" + +[ca990fdd-08c2-4f95-aa50-e0f5e1d6802b] +description = "discards nothing" + +[71595dae-d283-48ca-a52b-45fa96819d2f] +description = "discards first and last" + +[ae141f79-f86d-4567-b407-919eaca0f3dd] +description = "discards neither first nor last" + +[daf25b36-a59f-4f29-bcfe-302eb4e43609] +description = "discards strings" + +[a38d03f9-95ad-4459-80d1-48e937e4acaf] +description = "discards lists" diff --git a/exercises/practice/strain/Strain.php b/exercises/practice/strain/Strain.php new file mode 100644 index 00000000..803b4957 --- /dev/null +++ b/exercises/practice/strain/Strain.php @@ -0,0 +1,38 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class Strain +{ + public function keep(array $list, callable $predicate): array + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } + + public function discard(array $list, callable $predicate): array + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/strain/StrainTest.php b/exercises/practice/strain/StrainTest.php new file mode 100644 index 00000000..dbe47996 --- /dev/null +++ b/exercises/practice/strain/StrainTest.php @@ -0,0 +1,229 @@ +strain = new Strain(); + } + + /** + * uuid: 26af8c32-ba6a-4eb3-aa0a-ebd8f136e003 + */ + public function testKeepOnEmptyListReturnsEmptyList(): void + { + $list = []; + $predicate = function ($x) { + return true; + }; + + $this->assertEquals([], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: f535cb4d-e99b-472a-bd52-9fa0ffccf454 + */ + public function testKeepsEverything(): void + { + $list = [1, 3, 5]; + $predicate = function ($x) { + return true; + }; + + $this->assertEquals([1, 3, 5], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: 950b8e8e-f628-42a8-85e2-9b30f09cde38 + */ + public function testKeepNothing(): void + { + $list = [1, 3, 5]; + $predicate = function ($x) { + return false; + }; + + $this->assertEquals([], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: 92694259-6e76-470c-af87-156bdf75018a + */ + public function testKeepFirstAndLast(): void + { + $list = [1, 2, 3]; + $predicate = function ($x) { + return $x % 2 === 1; + }; + + $this->assertEquals([1, 3], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: 938f7867-bfc7-449e-a21b-7b00cbb56994 + */ + public function testKeepNeitherFirstNorLast(): void + { + $list = [1, 2, 3]; + $predicate = function ($x) { + return $x % 2 === 0; + }; + + $this->assertEquals([2], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: 8908e351-4437-4d2b-a0f7-770811e4881 + */ + public function testKeepStrings(): void + { + $list = ["apple", "zebra", "banana", "zombies", "cherimoya", "zealot"]; + $predicate = function ($x) { + return str_starts_with($x, 'z'); + }; + + $this->assertEquals(["zebra", "zombies", "zealot"], $this->strain->keep($list, $predicate)); + } + + /** + * uuid: 2728036b-102a-4f1e-a3ef-eac6160d876a + */ + public function testKeepsLists(): void + { + $list = [ + [1, 2, 3], + [5, 5, 5], + [5, 1, 2], + [2, 1, 2], + [1, 5, 2], + [2, 2, 1], + [1, 2, 5] + ]; + $predicate = function ($x) { + return in_array(5, $x, true); + }; + + $expected = [ + [5, 5, 5], + [5, 1, 2], + [1, 5, 2], + [1, 2, 5] + ]; + + $this->assertEquals($expected, $this->strain->keep($list, $predicate)); + } + + /** + * uuid: ef16beb9-8d84-451a-996a-14e80607fce6 + */ + public function testDiscardOnEmptyListReturnsEmptyList(): void + { + $list = []; + $predicate = function ($x) { + return true; + }; + + $this->assertEquals([], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: 2f42f9bc-8e06-4afe-a222-051b5d8cd12a + */ + public function testDiscardEverything(): void + { + $list = [1, 3, 5]; + $predicate = function ($x) { + return true; + }; + + $this->assertEquals([], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: ca990fdd-08c2-4f95-aa50-e0f5e1d6802b + */ + public function testDiscardNothing(): void + { + $list = [1, 3, 5]; + $predicate = function ($x) { + return false; + }; + + $this->assertEquals([1, 3, 5], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: 71595dae-d283-48ca-a52b-45fa96819d2f + */ + public function testDiscardFirstAndLast(): void + { + $list = [1, 2, 3]; + $predicate = function ($x) { + return $x % 2 === 1; + }; + + $this->assertEquals([2], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: ae141f79-f86d-4567-b407-919eaca0f3dd + */ + public function testDiscardNeitherFirstNorLast(): void + { + $list = [1, 2, 3]; + $predicate = function ($x) { + return $x % 2 === 0; + }; + + $this->assertEquals([1,3], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: daf25b36-a59f-4f29-bcfe-302eb4e43609 + */ + public function testDiscardStrings(): void + { + $list = ["apple", "zebra", "banana", "zombies", "cherimoya", "zealot"]; + $predicate = function ($x) { + return str_starts_with($x, 'z'); + }; + + $this->assertEquals(["apple", "banana", "cherimoya"], $this->strain->discard($list, $predicate)); + } + + /** + * uuid: a38d03f9-95ad-4459-80d1-48e937e4acaf + */ + public function testDiscardLists(): void + { + $list = [ + [1, 2, 3], + [5, 5, 5], + [5, 1, 2], + [2, 1, 2], + [1, 5, 2], + [2, 2, 1], + [1, 2, 5] + ]; + $predicate = function ($x) { + return in_array(5, $x, true); + }; + + $expected = [ + [1, 2, 3], + [2, 1, 2], + [2, 2, 1] + ]; + + $this->assertEquals($expected, $this->strain->discard($list, $predicate)); + } +} diff --git a/exercises/practice/sublist/.docs/instructions.md b/exercises/practice/sublist/.docs/instructions.md new file mode 100644 index 00000000..7535931a --- /dev/null +++ b/exercises/practice/sublist/.docs/instructions.md @@ -0,0 +1,25 @@ +# Instructions + +Given any two lists `A` and `B`, determine if: + +- List `A` is equal to list `B`; or +- List `A` contains list `B` (`A` is a superlist of `B`); or +- List `A` is contained by list `B` (`A` is a sublist of `B`); or +- None of the above is true, thus lists `A` and `B` are unequal + +Specifically, list `A` is equal to list `B` if both lists have the same values in the same order. +List `A` is a superlist of `B` if `A` contains a sub-sequence of values equal to `B`. +List `A` is a sublist of `B` if `B` contains a sub-sequence of values equal to `A`. + +Examples: + +- If `A = []` and `B = []` (both lists are empty), then `A` and `B` are equal +- If `A = [1, 2, 3]` and `B = []`, then `A` is a superlist of `B` +- If `A = []` and `B = [1, 2, 3]`, then `A` is a sublist of `B` +- If `A = [1, 2, 3]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B` +- If `A = [3, 4, 5]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B` +- If `A = [3, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` is a sublist of `B` +- If `A = [1, 2, 3]` and `B = [1, 2, 3]`, then `A` and `B` are equal +- If `A = [1, 2, 3, 4, 5]` and `B = [2, 3, 4]`, then `A` is a superlist of `B` +- If `A = [1, 2, 4]` and `B = [1, 2, 3, 4, 5]`, then `A` and `B` are unequal +- If `A = [1, 2, 3]` and `B = [1, 3, 2]`, then `A` and `B` are unequal diff --git a/exercises/practice/sublist/.meta/config.json b/exercises/practice/sublist/.meta/config.json new file mode 100644 index 00000000..b4508ccf --- /dev/null +++ b/exercises/practice/sublist/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "Sublist.php" + ], + "test": [ + "SublistTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Write a function to determine if a list is a sublist of another list." +} diff --git a/exercises/practice/sublist/.meta/example.php b/exercises/practice/sublist/.meta/example.php new file mode 100644 index 00000000..f2249a95 --- /dev/null +++ b/exercises/practice/sublist/.meta/example.php @@ -0,0 +1,38 @@ + 0 && count($listTwo) === 0) { + return "SUPERLIST"; + } + + if (count($listOne) === 0 && count($listTwo) > 0) { + return "SUBLIST"; + } + + $one = implode(',', $listOne) . ','; + $two = implode(',', $listTwo) . ','; + + if ($one === $two) { + return "EQUAL"; + } + + if (str_contains($one, $two)) { + return "SUPERLIST"; + } + + if (str_contains($two, $one)) { + return "SUBLIST"; + } + + return "UNEQUAL"; + } +} diff --git a/exercises/practice/sublist/.meta/tests.toml b/exercises/practice/sublist/.meta/tests.toml new file mode 100644 index 00000000..de5020a9 --- /dev/null +++ b/exercises/practice/sublist/.meta/tests.toml @@ -0,0 +1,64 @@ +# 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. + +[97319c93-ebc5-47ab-a022-02a1980e1d29] +description = "empty lists" + +[de27dbd4-df52-46fe-a336-30be58457382] +description = "empty list within non empty list" + +[5487cfd1-bc7d-429f-ac6f-1177b857d4fb] +description = "non empty list contains empty list" + +[1f390b47-f6b2-4a93-bc23-858ba5dda9a6] +description = "list equals itself" + +[7ed2bfb2-922b-4363-ae75-f3a05e8274f5] +description = "different lists" + +[3b8a2568-6144-4f06-b0a1-9d266b365341] +description = "false start" + +[dc39ed58-6311-4814-be30-05a64bc8d9b1] +description = "consecutive" + +[d1270dab-a1ce-41aa-b29d-b3257241ac26] +description = "sublist at start" + +[81f3d3f7-4f25-4ada-bcdc-897c403de1b6] +description = "sublist in middle" + +[43bcae1e-a9cf-470e-923e-0946e04d8fdd] +description = "sublist at end" + +[76cf99ed-0ff0-4b00-94af-4dfb43fe5caa] +description = "at start of superlist" + +[b83989ec-8bdf-4655-95aa-9f38f3e357fd] +description = "in middle of superlist" + +[26f9f7c3-6cf6-4610-984a-662f71f8689b] +description = "at end of superlist" + +[0a6db763-3588-416a-8f47-76b1cedde31e] +description = "first list missing element from second list" + +[83ffe6d8-a445-4a3c-8795-1e51a95e65c3] +description = "second list missing element from first list" + +[7bc76cb8-5003-49ca-bc47-cdfbe6c2bb89] +description = "first list missing additional digits from second list" + +[0d7ee7c1-0347-45c8-9ef5-b88db152b30b] +description = "order matters to a list" + +[5f47ce86-944e-40f9-9f31-6368aad70aa6] +description = "same digits but different numbers" diff --git a/exercises/practice/sublist/Sublist.php b/exercises/practice/sublist/Sublist.php new file mode 100644 index 00000000..fdd9ce94 --- /dev/null +++ b/exercises/practice/sublist/Sublist.php @@ -0,0 +1,33 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class Sublist +{ + public function compare(array $listOne, array $listTwo): string + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/sublist/SublistTest.php b/exercises/practice/sublist/SublistTest.php new file mode 100644 index 00000000..da2c9fe7 --- /dev/null +++ b/exercises/practice/sublist/SublistTest.php @@ -0,0 +1,216 @@ +sublist = new Sublist(); + } + + /** + * uuid: 97319c93-ebc5-47ab-a022-02a1980e1d29 + */ + public function testEmptyLists(): void + { + $listOne = []; + $listTwo = []; + + $this->assertEquals('EQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: de27dbd4-df52-46fe-a336-30be58457382 + */ + public function testEmptyListWithinNonEmptyList(): void + { + $listOne = []; + $listTwo = [1, 2, 3]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 5487cfd1-bc7d-429f-ac6f-1177b857d4fb + */ + public function testNonEmptyListContainsEmptyList(): void + { + $listOne = [1, 2, 3]; + $listTwo = []; + + $this->assertEquals('SUPERLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 1f390b47-f6b2-4a93-bc23-858ba5dda9a6 + */ + public function testListEqualsItself(): void + { + $listOne = [1, 2, 3]; + $listTwo = [1, 2, 3]; + + $this->assertEquals('EQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 7ed2bfb2-922b-4363-ae75-f3a05e8274f5 + */ + public function testDifferentLists(): void + { + $listOne = [1, 2, 3]; + $listTwo = [2, 3, 4]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 3b8a2568-6144-4f06-b0a1-9d266b365341 + */ + public function testFalseStart(): void + { + $listOne = [1, 2, 5]; + $listTwo = [0, 1, 2, 3, 1, 2, 5, 6]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: dc39ed58-6311-4814-be30-05a64bc8d9b1 + */ + public function testConsecutive(): void + { + $listOne = [1, 1, 2]; + $listTwo = [0, 1, 1, 1, 2, 1, 2]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: d1270dab-a1ce-41aa-b29d-b3257241ac26 + */ + public function testSublistAtStart(): void + { + $listOne = [0, 1, 2]; + $listTwo = [0, 1, 2, 3, 4, 5]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 81f3d3f7-4f25-4ada-bcdc-897c403de1b6 + */ + public function testSublistInMiddle(): void + { + $listOne = [2, 3, 4]; + $listTwo = [0, 1, 2, 3, 4, 5]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 43bcae1e-a9cf-470e-923e-0946e04d8fdd + */ + public function testSublistAtEnd(): void + { + $listOne = [3, 4, 5]; + $listTwo = [0, 1, 2, 3, 4, 5]; + + $this->assertEquals('SUBLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 76cf99ed-0ff0-4b00-94af-4dfb43fe5caa + */ + public function testAtStartOfSuperlist(): void + { + $listOne = [0, 1, 2, 3, 4, 5]; + $listTwo = [0, 1, 2]; + + $this->assertEquals('SUPERLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: b83989ec-8bdf-4655-95aa-9f38f3e357fd + */ + public function testInMiddleOfSuperlist(): void + { + $listOne = [0, 1, 2, 3, 4, 5]; + $listTwo = [2, 3]; + + $this->assertEquals('SUPERLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 26f9f7c3-6cf6-4610-984a-662f71f8689b + */ + public function testAtEndOfSuperlist(): void + { + $listOne = [0, 1, 2, 3, 4, 5]; + $listTwo = [3, 4, 5]; + + $this->assertEquals('SUPERLIST', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 0a6db763-3588-416a-8f47-76b1cedde31e + */ + public function testFirstListMissingElementFromSecondList(): void + { + $listOne = [1, 3]; + $listTwo = [1, 2, 3]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 83ffe6d8-a445-4a3c-8795-1e51a95e65c3 + */ + public function testSecondListMissingElementFromFirstList(): void + { + $listOne = [1, 2, 3]; + $listTwo = [1, 3]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 7bc76cb8-5003-49ca-bc47-cdfbe6c2bb8 + */ + public function testFirstListMissingAdditionalDigitsFromSecondList(): void + { + $listOne = [1, 2]; + $listTwo = [1, 22]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 0d7ee7c1-0347-45c8-9ef5-b88db152b30b + */ + public function testOrderMattersToList(): void + { + $listOne = [1, 2, 3]; + $listTwo = [3, 2, 1]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } + + /** + * uuid: 5f47ce86-944e-40f9-9f31-6368aad70aa6 + */ + public function testSameDigitsButDifferentNumbers(): void + { + $listOne = [1, 0, 1]; + $listTwo = [10, 1]; + + $this->assertEquals('UNEQUAL', $this->sublist->compare($listOne, $listTwo)); + } +}