Here is a word-count function in Go
package wc
import (
"regexp"
"strings"
)
type Histogram map[string]int
func WordCount(input string) Histogram {
histogram := make(map[string]int)
re := regexp.MustCompile("[^a-zA-Z0-9 ]*")
input = re.ReplaceAllString(input, "")
for _, word := range strings.Split(input, " ") {
if word == "" {
continue
}
histogram[strings.ToLower(word)]++
}
return histogram
}
This code passes or fails the tests non-deterministically. Sometimes it failed due to not matching the expected map and the actual map. However, the contents of both are exactly the same. I think that there is some problem with map comparison. I don't know how can I fix it. Somebody help me please!
Here is the test-suite code
package wc
import (
"fmt"
"testing"
)
var testCases = []struct {
description string
input string
output Histogram
}{
{
description: "a single word",
input: "word",
output: Histogram{"word": 1},
},
{
description: "one of each",
input: "one of each",
output: Histogram{"one": 1, "of": 1, "each": 1},
},
{
description: "multiple occurrences",
input: "one fish two fish red fish blue fish",
output: Histogram{"one": 1, "fish": 4, "two": 1, "red": 1, "blue": 1},
},
{
description: "ignore punctuation",
input: "car : carpet as java : javascript!!&@$%^&",
output: Histogram{"car": 1, "carpet": 1, "as": 1, "java": 1, "javascript": 1},
},
{
description: "including numbers",
input: "testing, 1, 2 testing",
output: Histogram{"testing": 2, "1": 1, "2": 1},
},
{
description: "normalises case",
input: "go Go GO",
output: Histogram{"go": 3},
},
}
func TestWordCount(t *testing.T) {
for _, tt := range testCases {
expected := fmt.Sprintf("%v", tt.output)
actual := fmt.Sprintf("%v", WordCount(tt.input))
if expected != actual {
t.Fatalf("%s\n\tExpected: %v\n\tGot: %v", tt.description, expected, actual)
} else {
t.Logf("PASS: %s - WordCount(%s)", tt.description, tt.input)
}
}
}
Below are examples of the failure situation:
1.
Expected: map[two:1 red:1 blue:1 one:1 fish:4]
Got: map[one:1 fish:4 two:1 red:1 blue:1]
2.
Expected: map[one:1 fish:4 two:1 red:1 blue:1]
Got: map[red:1 blue:1 one:1 fish:4 two:1]
3.
Expected: map[java:1 javascript:1 car:1 carpet:1 as:1]
Got: map[javascript:1 car:1 carpet:1 as:1 java:1]
...
Additional information are here:
http://exercism.io/submissions/cf94f4732fd97335be2e755f
You can't compare expected
and actual
with !=
, because it compares the string representation of the maps, so it will work only randomly (if the values are printed in the same order).
What you have to do, is to use the reflect
package DeepEqual()
method to compare the maps :
import "reflect"
// ...
if !reflect.DeepEqual(tt.output, WordCount(tt.input)) {
// ...
It will first checks if both maps are nil
, then if they have the same length, then if they have the same set of (key, value) pairs.