JAVA 8 !

Berlin Clock is a classic code exercises. The problem itself is not difficult, but it is effective at testing the candidate analytical skills. It may take some time to get your head around but once you do it you should be able to code it fairly quickly.

TODO: Add Image

This is a real clock that exists in Berlin by the away.

The Berlin Clock is composed by four rows of lights and a yellow lamp on the top (see picture above for reference).

* The top yellow light blinks every couple of seconds (on for even seconds, off for odd seconds).
* The top two rows represent hours. The lights on the top row represent five hours each while the bottom row lamps represent one hour each.
* The bottom two rows represent minutes. Again, each third row lamp represents 5 minutes so we there are 11 of them. The bottom row lamp represent one minute each.

So for example, 4pm (16 hours) is represented by three lamps on of the first row and 1 light on of the second row. Equally, 27 minutes is represented by 5 lights on the third row and 2 on the very bottom row.

You will notice that the lamps on the third row are yellow, apart from the 3rd, 6th and 9th lamps which indicate quarters of an hour. This is just a visual convenience, they still represent 5 minutes like the yellow lamps.

Here are the colour code for lamps.
Y = Yellow
R = Red
O = Off

Here are some examples:


00:00:00    Y OOOO OOOO OOOOOOOOOOO OOOO

13:17:01    O RROO RRRO YYROOOOOOOO YYOO

23:59:59    O RRRR RRRO YYRYYRYYRYY YYYY

24:00:00    Y RRRR RRRR OOOOOOOOOOO OOOO

Solution:

As always, you should start with some tests. The advice here still applies though, be sensible, don’t go crazy with test driven development. In this case, I find it useful to test seconds, minutes and hours isolation. Here is the full list of tests, in a real interview you would write them one by one and develop the algorithm as you go along.

public class BerlinClockTest {
    private BerlinClock berlinClock = new BerlinClock();

    @Test
    public void testBerlinClock() {
        assertEquals("O RROO RRRO YYROOOOOOOO YYOO", berlinClock.berlinClock(13, 17, 1));
        assertEquals("Y RRRR RRRO YYRYYROOOOO YYYY", berlinClock.berlinClock(23, 34, 42));
    }

    @Test
    public void testSeconds() {
        assertEquals("Y", berlinClock.getSeconds(0));
        assertEquals("O", berlinClock.getSeconds(1));
        assertEquals("Y", berlinClock.getSeconds(42));
        assertEquals("O", berlinClock.getSeconds(59));
    }

    @Test
    public void testHours() {
        assertEquals("OOOO OOOO", berlinClock.getHours(0));
        assertEquals("RROO RRRO", berlinClock.getHours(13));
        assertEquals("RRRR RRRO", berlinClock.getHours(23));
    }

    @Test
    public void testMinutes() {
        assertEquals("YYROOOOOOOO YYOO", berlinClock.getMinutes(17));
        assertEquals("YYRYYROOOOO YYYY", berlinClock.getMinutes(34));

    }
}

For simplicity, we assume you already have hours, minutes and seconds as integers. The result is the concatenation of the representation of seconds, hours and minutes.

public String berlinClock(int hours, int minutes, int seconds) {
    return getSeconds(seconds) + " " + getHours(hours) + " " + getMinutes(minutes);
}

The seconds representation is the easiest. The top display blinks every seconds so we just need to show “Y” for even seconds and “O” odd seconds.

protected String getSeconds(int seconds) {
    return seconds % 2 == 0 ? "Y" : "O";
}

For hours, you can figure out the number of ON

protected String getHours(int hours) {
    int numberTopHourLamps = hours / 5;
    int numberBottomHourLamps = hours % 5;

    StringBuilder sb = new StringBuilder();
    sb.append(getLampRow(4, numberTopHourLamps, "R"))
            .append(" ")
            .append(getLampRow(4, numberBottomHourLamps, "R"));

    return sb.toString();
}
private String getLampRow(int totalNumberLamps, int numberLampsOn, String lampSymbol) {
    StringBuilder sb = new StringBuilder();
    IntStream.rangeClosed(1, totalNumberLamps)
            .forEach(i -> sb.append(i <= numberLampsOn ? lampSymbol : "O"));
    return sb.toString();
}

Lastly minutes

protected String getMinutes(int minutes) {
    int numberTopMinutesLamps = minutes / 5;
    int numberBottomMinutesLamps = minutes % 5;

    StringBuilder sb = new StringBuilder();
    IntStream.rangeClosed(1, 11)
            .forEach(i -> sb.append(i <= numberTopMinutesLamps ? getMinuteLampColour(i) : "O"));

    sb.append(" ");

    sb.append(getLampRow(4, numberBottomMinutesLamps, "Y"));

    return sb.toString();
}
private String getMinuteLampColour(int index) {
    return index % 3 == 0 ? "R" : "Y";
}

All together:

public class BerlinClock {
    public String berlinClock(int hours, int minutes, int seconds) {
        return getSeconds(seconds) + " " + getHours(hours) + " " + getMinutes(minutes);
    }

    protected String getSeconds(int seconds) {
        return seconds % 2 == 0 ? "Y" : "O";
    }

    protected String getHours(int hours) {
        int numberTopHourLamps = hours / 5;
        int numberBottomHourLamps = hours % 5;

        StringBuilder sb = new StringBuilder();
        sb.append(getLampRow(4, numberTopHourLamps, "R"))
                .append(" ")
                .append(getLampRow(4, numberBottomHourLamps, "R"));

        return sb.toString();
    }

    protected String getMinutes(int minutes) {
        int numberTopMinutesLamps = minutes / 5;
        int numberBottomMinutesLamps = minutes % 5;

        StringBuilder sb = new StringBuilder();
        IntStream.rangeClosed(1, 11)
                .forEach(i -> sb.append(i <= numberTopMinutesLamps ? getMinuteLampColour(i) : "O"));

        sb.append(" ");

        sb.append(getLampRow(4, numberBottomMinutesLamps, "Y"));

        return sb.toString();
    }

    private String getLampRow(int totalNumberLamps, int numberLampsOn, String lampSymbol) {
        StringBuilder sb = new StringBuilder();
        IntStream.rangeClosed(1, totalNumberLamps)
                .forEach(i -> sb.append(i <= numberLampsOn ? lampSymbol : "O"));
        return sb.toString();
    }

    private String getMinuteLampColour(int index) {
        return index % 3 == 0 ? "R" : "Y";
    }
}

Check online!

Several other solutions here.