Exercism v3 launches on Sept 1st 2021. Learn more! πŸš€πŸš€πŸš€
Avatar of rootulp

rootulp's solution

to Micro Blog in the Java Track

Published at May 23 2020 · 0 comments
Instructions
Test suite
Solution

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.

Setup

Go through the setup instructions for Java to install the necessary dependencies:

https://exercism.io/tracks/java/installation

Running the tests

You can run all the tests for an exercise by entering the following in your terminal:

$ gradle test

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by removing the @Ignore("Remove to run test") annotation.

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

MicroBlogTest.java

import static org.junit.Assert.assertEquals;

import org.junit.Ignore;
import org.junit.Test;

public class MicroBlogTest {

    private final MicroBlog microBlog = new MicroBlog();
    
    @Test
    public void englishLanguageShort() {
        String expected = "Hi";
        assertEquals(expected, microBlog.truncate("Hi"));
    }

    @Ignore("Remove to run test")
    @Test
    public void englishLanguageLong() {
        String expected = "Hello";
        assertEquals(expected, microBlog.truncate("Hello there"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void germanLanguageShort_broth() {
        String expected = "brΓΌhe";
        assertEquals(expected, microBlog.truncate("brΓΌhe"));
    }

    @Ignore("Remove to run test")
    @Test
    public void germanLanguageLong_bearCarpet_to_beards() {
        String expected = "BΓ€rte";
        assertEquals(expected, microBlog.truncate("BΓ€rteppich"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void bulgarianLanguageShort_good() {
        String expected = "Π”ΠΎΠ±ΡŠΡ€";
        assertEquals(expected, microBlog.truncate("Π”ΠΎΠ±ΡŠΡ€"));
    }

    @Ignore("Remove to run test")
    @Test
    public void greekLanguageShort_health() {
        String expected = "υγΡιά";
        assertEquals(expected, microBlog.truncate("υγΡιά"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void mathsShort() {
        String expected = "a=Ο€rΒ²";
        assertEquals(expected, microBlog.truncate("a=Ο€rΒ²"));
    }

    @Ignore("Remove to run test")
    @Test
    public void mathsLong() {
        String expected = "βˆ…βŠŠβ„•βŠŠβ„€";
        assertEquals(expected, microBlog.truncate("βˆ…βŠŠβ„•βŠŠβ„€βŠŠβ„šβŠŠβ„βŠŠβ„‚"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void englishAndEmojiShort() {
        String expected = "Fly πŸ›«";
        assertEquals(expected, microBlog.truncate("Fly πŸ›«"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void emojiShort() {
        String expected = "πŸ’‡";
        assertEquals(expected, microBlog.truncate("πŸ’‡"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void emojiLong() {
        String expected = "β„πŸŒ‘πŸ€§πŸ€’πŸ₯";
        assertEquals(expected, microBlog.truncate("β„πŸŒ‘πŸ€§πŸ€’πŸ₯πŸ•°πŸ˜€"));
    }
    
    @Ignore("Remove to run test")
    @Test
    public void royalFlush() {
        String expected = "πŸƒŽπŸ‚ΈπŸƒ…πŸƒ‹πŸƒ";
        assertEquals(expected, microBlog.truncate("πŸƒŽπŸ‚ΈπŸƒ…πŸƒ‹πŸƒπŸƒπŸƒŠ"));
    }
}
import java.util.stream.Collectors;

class MicroBlog {
    public String truncate(String input) {
		return input.codePoints().limit(5).mapToObj(Character::toString).collect(Collectors.joining());
    }
}

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?