Skip to content

Commit

Permalink
Merge pull request #352 from runnerdave/letter-frequency
Browse files Browse the repository at this point in the history
Letter frequency
  • Loading branch information
runnerdave authored Jul 1, 2019
2 parents 1fb10a5 + e8def3c commit 25cd3bf
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
48 changes: 48 additions & 0 deletions 03_letters/runnerdave/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package main

import (
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)

var out io.Writer = os.Stdout

func letters(s string) map[rune]int {
stats := make(map[rune]int)
for _, char := range s {
stats[char]++
}
return stats
}

func sortLetters(m map[rune]int) []string {
keys := make([]rune, 0)
for k := range m {
keys = append(keys, k)
}
sorted(keys)
sortedArray := make([]string, len(keys))
for i, k := range keys {
sortedArray[i] = fmt.Sprintf("%s:%s", string(k), strconv.Itoa(m[k]))
}
return sortedArray
}

func main() {
fmt.Fprintln(out, strings.Join(sortLetters(letters("aba")), "\n"))
}

type runeSlice []rune

func (p runeSlice) Len() int { return len(p) }
func (p runeSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p runeSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func sorted(runes []rune) string {
sort.Sort(runeSlice(runes))
return string(runes)
}
69 changes: 69 additions & 0 deletions 03_letters/runnerdave/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

import (
"bytes"
"reflect"
"strconv"
"testing"
)

func TestMainOutput(t *testing.T) {
var buf bytes.Buffer
out = &buf

main()

expected := strconv.Quote(`a:2
b:1
`)
actual := strconv.Quote(buf.String())
t.Logf("expected:%s", expected)
t.Logf("actual:%s", actual)

if expected != actual {
t.Errorf("Unexpected output in main()")
}
}

func TestLetters(t *testing.T) {
tables := []struct {
n string
x map[rune]int
}{
{"aaa", map[rune]int{'a': 3}},
{"bbbb", map[rune]int{'b': 4}},
{"B", map[rune]int{'B': 1}},
{"bbbB", map[rune]int{'b': 3, 'B': 1}},
{"bbbBCcccc", map[rune]int{'b': 3, 'B': 1, 'C': 1, 'c': 4}},
{"bbbBCbbbb", map[rune]int{'b': 7, 'B': 1, 'C': 1}},
{"", map[rune]int{}},
}
for _, table := range tables {
result := letters(table.n)
if !reflect.DeepEqual(result, table.x) {
t.Errorf("Function Letters for (%s) was incorrect, got: %v, want: %v.", table.n, result, table.x)
}
}
}

func TestSortingLetters(t *testing.T) {
tables := []struct {
x map[rune]int
n []string
}{
{map[rune]int{'a': 1, 'b': 3}, []string{"a:1", "b:3"}},
{map[rune]int{'c': 1, 'b': 3}, []string{"b:3", "c:1"}},
{map[rune]int{'m': 1, 'b': 3, 'd': 5}, []string{"b:3", "d:5", "m:1"}},
{map[rune]int{'a': 1, 'A': 3}, []string{"A:3", "a:1"}},
{map[rune]int{'n': 1, 'N': 3}, []string{"N:3", "n:1"}},
{map[rune]int{'n': 0, 'N': 3}, []string{"N:3", "n:0"}},
{map[rune]int{}, []string{}},
}

for _, table := range tables {
sorted := sortLetters(table.x)
if !reflect.DeepEqual(sorted, table.n) {
t.Errorf("Sorting of (%v) was incorrect, got: %v, want: %v.", table.x, sorted, table.n)
}
}
}

0 comments on commit 25cd3bf

Please sign in to comment.