Hello sports fans!
We are back today to walk through a very small refactor as mentioned previously whilst solving Day 2: I Was Told There Would Be No Math (Part 2)
The reason for this refactor is to reduce duplication of code. A process which is going to be nice and easy thanks to test driven development.
So lets look at our duplicated code.
Example 1:
func CalculatePresentArea(str string) int {
s := strings.Split(str, "x")
var sides []int
for _, sideString := range s {
side, _ := strconv.Atoi(sideString)
sides = append(sides, side)
}
sort.Ints(sides)
return sides[0]*sides[1]*3 + sides[0]*sides[2]*2 + sides[1]*sides[2]*2
}
Example 2:
func CalculateRibbonLength(str string) int {
s := strings.Split(str, "x")
var sides []int
for _, sideString := range s {
side, _ := strconv.Atoi(sideString)
sides = append(sides, side)
}
sort.Ints(sides)
return sides[0] + sides[0] + sides[1] + sides[1] + sides[0]*sides[1]*sides[2]
}
As we can see, the bulk of these two functions are exactly the same.
So lets write a test for a function that we can use to make this process DRY.
func TestMakeSortedIntSlice(t *testing.T) {
assert.Equal(t, []int{5, 13, 19}, MakeSortedIntSlice([]string{"13x5x19"}))
assert.Equal(t, []int{22, 26, 28}, MakeSortedIntSlice([]string{"22x28x26"}))
assert.Equal(t, []int{12, 26, 29}, MakeSortedIntSlice([]string{"29x26x12"}))
assert.Equal(t, []int{4, 7, 17}, MakeSortedIntSlice([]string{"4x7x17"}))
assert.Equal(t, []int{14, 30, 30}, MakeSortedIntSlice([]string{"30x30x14"}))
}
So as we know, running go test
at this point will produce the following failures:
# github.com/damiensedgwick/aoc2015/day_2 [github.com/damiensedgwick/aoc2015/day_2.test]
./main_test.go:28:36: undefined: MakeSortedIntSlice
./main_test.go:29:37: undefined: MakeSortedIntSlice
./main_test.go:30:37: undefined: MakeSortedIntSlice
./main_test.go:31:35: undefined: MakeSortedIntSlice
./main_test.go:32:37: undefined: MakeSortedIntSlice
FAIL github.com/damiensedgwick/aoc2015/day_2 [build failed]
So lets write our function and get this test passing.
func MakeSortedIntSlice(str string) []int {
s := strings.Split(str, "x")
var sides []int
for _, sideString := range s {
side, _ := strconv.Atoi(sideString)
sides = append(sides, side)
}
sort.Ints(sides)
return sides
}
If we run our tests again, we will see that they are now passing, perfect.
We can now replace the duplicated code in both of the earlier examples so that they now look like this:
Example 1:
func CalculatePresentArea(str string) int {
s := MakeSortedIntSlice(str)
return s[0]*s[1]*3 + s[0]*s[2]*2 + s[1]*s[2]*2
}
Example 2:
func CalculateRibbonLength(str string) int {
s := MakeSortedIntSlice(str)
return s[0] + s[0] + s[1] + s[1] + s[0]*s[1]*s[2]
}
Much cleaner!
Although this was a rather simple example, using tests to refactor code is something I would highly recommend!
Next time we will take a look at Day 3, see you then.