diff --git a/secretmessage/secretmessage.go b/secretmessage/secretmessage.go index a1f7401..144b448 100644 --- a/secretmessage/secretmessage.go +++ b/secretmessage/secretmessage.go @@ -1,6 +1,47 @@ package secretmessage -// Decode func +import ( + "sort" + "strings" +) + +// pair tracks frequency of a character +type pair struct { + c string + n int +} + +// Decode sorts encoded by descending rune frequency, discards all but one of each rune, then returns everything before "_" func Decode(encoded string) string { - return "" + var ( + chars = strings.Split(encoded, "") + m = make(map[string]int) + s = make([]pair, 1) + out = "" + i = -1 + ) + + // count frequencies: + for _, c := range chars { + m[c]++ + } + + // Order the runes by descending frequency: + for k, v := range m { + s = append(s, pair{c: k, n: v}) + } + sort.Slice(s, func(i, j int) bool { + return s[i].n > s[j].n + }) + + // Append each character to `out` until we reach _: + for { + i++ + if s[i].c == "_" { + break + } + out += s[i].c + } + + return out } diff --git a/secretmessage/secretmessage_test.go b/secretmessage/secretmessage_test.go index 966896f..83944fa 100644 --- a/secretmessage/secretmessage_test.go +++ b/secretmessage/secretmessage_test.go @@ -19,3 +19,17 @@ func BenchmarkDecode(b *testing.B) { Decode(encoded) } } + +func TestDecodeSimple(t *testing.T) { + actual := Decode("b_bcb_") + if actual != "b" { + t.Fatalf("Expected %s, got %s", "b", actual) + } +} + +func TestDecodeSimpleMultibyteUnicode(t *testing.T) { + actual := Decode("Ƃ_ƂcƂ_") + if actual != "Ƃ" { + t.Fatalf("Expected %s, got %s", "Ƃ", actual) + } +}