From 732d67799f35b36c88bf08f6e78774273ddfaac7 Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Thu, 29 Feb 2024 12:59:18 +0100 Subject: [PATCH] Add Micro Blog Exercise (#649) --- config.json | 8 ++ .../practice/micro-blog/.docs/instructions.md | 37 ++++++ .../practice/micro-blog/.meta/config.json | 17 +++ .../practice/micro-blog/.meta/example.php | 11 ++ .../practice/micro-blog/.meta/tests.toml | 46 +++++++ exercises/practice/micro-blog/MicroBlog.php | 33 +++++ .../practice/micro-blog/MicroBlogTest.php | 114 ++++++++++++++++++ 7 files changed, 266 insertions(+) create mode 100644 exercises/practice/micro-blog/.docs/instructions.md create mode 100644 exercises/practice/micro-blog/.meta/config.json create mode 100644 exercises/practice/micro-blog/.meta/example.php create mode 100644 exercises/practice/micro-blog/.meta/tests.toml create mode 100644 exercises/practice/micro-blog/MicroBlog.php create mode 100644 exercises/practice/micro-blog/MicroBlogTest.php diff --git a/config.json b/config.json index ef32d083..5c32a837 100644 --- a/config.json +++ b/config.json @@ -1148,6 +1148,14 @@ "prerequisites": [], "difficulty": 5 }, + { + "slug": "micro-blog", + "name": "Micro Blog", + "uuid": "203ba680-cdbd-494d-a1b6-af426bc84e59", + "practices": [], + "prerequisites": [], + "difficulty": 1 + }, { "slug": "yacht", "name": "Yacht", diff --git a/exercises/practice/micro-blog/.docs/instructions.md b/exercises/practice/micro-blog/.docs/instructions.md new file mode 100644 index 00000000..d6c6cf65 --- /dev/null +++ b/exercises/practice/micro-blog/.docs/instructions.md @@ -0,0 +1,37 @@ +# Instructions + +You have identified a gap in the social media market for very very short posts. +Now that Twitter allows 280 character posts, people wanting quick social media updates aren't being served. +You decide to create your own social media network. + +To make your product noteworthy, you make it extreme and only allow posts of 5 or less characters. +Any posts of more than 5 characters should be truncated to 5. + +To allow your users to express themselves fully, you allow Emoji and other Unicode. + +The task is to truncate input strings to 5 characters. + +## Text Encodings + +Text stored digitally has to be converted to a series of bytes. +There are 3 ways to map characters to bytes in common use. + +- **ASCII** can encode English language characters. + All characters are precisely 1 byte long. +- **UTF-8** is a Unicode text encoding. + Characters take between 1 and 4 bytes. +- **UTF-16** is a Unicode text encoding. + Characters are either 2 or 4 bytes long. + +UTF-8 and UTF-16 are both Unicode encodings which means they're capable of representing a massive range of characters including: + +- Text in most of the world's languages and scripts +- Historic text +- Emoji + +UTF-8 and UTF-16 are both variable length encodings, which means that different characters take up different amounts of space. + +Consider the letter 'a' and the emoji 'πŸ˜›'. +In UTF-16 the letter takes 2 bytes but the emoji takes 4 bytes. + +The trick to this exercise is to use APIs designed around Unicode characters (codepoints) instead of Unicode codeunits. diff --git a/exercises/practice/micro-blog/.meta/config.json b/exercises/practice/micro-blog/.meta/config.json new file mode 100644 index 00000000..acb879ec --- /dev/null +++ b/exercises/practice/micro-blog/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "MicroBlog.php" + ], + "test": [ + "MicroBlogTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Given an input string, truncate it to 5 characters." +} diff --git a/exercises/practice/micro-blog/.meta/example.php b/exercises/practice/micro-blog/.meta/example.php new file mode 100644 index 00000000..5be2e0d0 --- /dev/null +++ b/exercises/practice/micro-blog/.meta/example.php @@ -0,0 +1,11 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class MicroBlog +{ + public function truncate(string $text): string + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/micro-blog/MicroBlogTest.php b/exercises/practice/micro-blog/MicroBlogTest.php new file mode 100644 index 00000000..5f3ce650 --- /dev/null +++ b/exercises/practice/micro-blog/MicroBlogTest.php @@ -0,0 +1,114 @@ +microBlog = new MicroBlog(); + } + + /** + * uuid: b927b57f-7c98-42fd-8f33-fae091dc1efc + */ + public function testEnglishLanguageShort(): void + { + $this->assertEquals('Hi', $this->microBlog->truncate('Hi')); + } + + /** + * uuid: a3fcdc5b-0ed4-4f49-80f5-b1a293eac2a0 + */ + public function testEnglishLanguageLong(): void + { + $this->assertEquals('Hello', $this->microBlog->truncate('Hello there')); + } + + /** + * uuid: 01910864-8e15-4007-9c7c-ac956c686e60 + */ + public function testGermanLanguageShortBroth(): void + { + $this->assertEquals('brΓΌhe', $this->microBlog->truncate('brΓΌhe')); + } + + /** + * uuid: f263e488-aefb-478f-a671-b6ba99722543 + */ + public function testGermanLanguageLongBearCarpetToBeards(): void + { + $this->assertEquals('BΓ€rte', $this->microBlog->truncate('BΓ€rteppich')); + } + + /** + * uuid: 0916e8f1-41d7-4402-a110-b08aa000342c + */ + public function testBulgarianLanguageShortGood(): void + { + $this->assertEquals('Π”ΠΎΠ±ΡŠΡ€', $this->microBlog->truncate('Π”ΠΎΠ±ΡŠΡ€')); + } + + /** + * uuid: bed6b89c-03df-4154-98e6-a61a74f61b7d + */ + public function testGreekLanguageShortHealth(): void + { + $this->assertEquals('υγΡιά', $this->microBlog->truncate('υγΡιά')); + } + + /** + * uuid: 485a6a70-2edb-424d-b999-5529dbc8e002 + */ + public function testMathShort(): void + { + $this->assertEquals('a=Ο€rΒ²', $this->microBlog->truncate('a=Ο€rΒ²')); + } + + /** + * uuid: 8b4b7b51-8f48-4fbe-964e-6e4e6438be28 + */ + public function testMathLong(): void + { + $this->assertEquals('βˆ…βŠŠβ„•βŠŠβ„€', $this->microBlog->truncate('βˆ…βŠŠβ„•βŠŠβ„€βŠŠβ„šβŠŠβ„βŠŠβ„‚')); + } + + /** + * uuid: 71f4a192-0566-4402-a512-fe12878be523 + */ + public function testEnglishAndEmojiShort(): void + { + $this->assertEquals('Fly πŸ›«', $this->microBlog->truncate('Fly πŸ›«')); + } + + /** + * uuid: 6f0f71f3-9806-4759-a844-fa182f7bc203 + */ + public function testEmojiShort(): void + { + $this->assertEquals('πŸ’‡', $this->microBlog->truncate('πŸ’‡')); + } + + /** + * uuid: ce71fb92-5214-46d0-a7f8-d5ba56b4cc6e + */ + public function testEmojiLong(): void + { + $this->assertEquals('β„πŸŒ‘πŸ€§πŸ€’πŸ₯', $this->microBlog->truncate('β„πŸŒ‘πŸ€§πŸ€’πŸ₯πŸ•°πŸ˜€')); + } + + /** + * uuid: 5dee98d2-d56e-468a-a1f2-121c3f7c5a0b + */ + public function testRoyalFlush(): void + { + $this->assertEquals('πŸƒŽπŸ‚ΈπŸƒ…πŸƒ‹πŸƒ', $this->microBlog->truncate('πŸƒŽπŸ‚ΈπŸƒ…πŸƒ‹πŸƒπŸƒπŸƒŠ')); + } +}