TDD Kata 12 – Ugly Trivia Game

This is my weekly Kata post. Read the first one to learn what it is all about.

Last week: Reversed Binary Numbers

To the Kata description
Scroll down to this weeks Kata description

I started with a straightforward solution in PHP, using built-in functions:

function revert(int $input) : int
{
    return (int)bindec(strrev(decbin($input)));
}

That was quick (good, because I had little time), but boring. So the next time, I decided to go for a solution with bitwise operations. The result:

function revert(int $input) : int
{
    $result = 0;
    $exponent = bitLength($input);
    do {
        --$exponent;
        $lastBitValue = $input & 1;
        $result += $lastBitValue * 2**$exponent;
    } while ($input>>=1);
    return $result;
}

function bitLength(int $input) : int
{
    $result = 0;
    do {
        ++$result;
    } while ($input>>=1);
    return $result;
}

I extracted the bitLenght function early, when I noticed that I would need it, then tested that one seperately. Just as in the Print Diamond kata, it helped to develop and test parts of the algorithm separately.

Finally, I did the Kata again in Go, following the same approach.

Full code with test:

reverse.go

package reversebinary

func Reverse(i uint) (rev uint) {
	for len := Length(i); len > 0; len-- {
		bit := i & 1
		rev += bit * (1 << (len - 1))
		i>>=1
	}
	return
}

func Length(i uint) (len uint) {
	if (i == 0) {
		return 1
	}
	for len = 0; i > 0; len++ {
		i>>=1
	}
	return
}

reverse_test.go

package reversebinary

import "testing"

func TestLength(t *testing.T) {
	cases := []struct {
		in, want uint
	}{
		{0, 1},
		{1, 1},
		{2, 2},
		{3, 2},
		{7, 3},
		{8, 4},
	}
	for _, c := range cases {
		got := Length(c.in)
		if got != c.want {
			t.Errorf("Length(%v) == %v, want %v", c.in, got, c.want)
		}
	}
}
func TestReverse(t *testing.T) {
	cases := []struct {
		in, want uint
	}{
		{0, 0},
		{1, 1},
		{2, 1},
		{3, 3},
		{11, 13},
		{61, 47},
	}
	for _, c := range cases {
		got := Reverse(c.in)
		if got != c.want {
			t.Errorf("Reverse(0b%b) == 0b%b, want 0b%b", c.in, got, c.want)
		}
	}
}

Twelvth Kata: Ugly Trivia Game

The purpose of a legacy code kata is to practice adding test coverage to previously untested code and to clean up the code without breaking it. This kata in perticular should be tacked with a golden master test (a.k.a. characterization test or scaffolding test). The legacy code can be found at https://github.com/jbrains/trivia

The original description of the kata can be found at http://kata-log.rocks/ugly-trivia-kata.

Since this is a bigger task, my plan is to tackle the PHP version once, in multiple steps.

Leave a Reply

Your email address will not be published. Required fields are marked *