Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lab 03 updated, issue fixed #457

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions 03_letters/marchitect/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

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

var out io.Writer = os.Stdout

func letters(s string) map[rune]int {
m := make(map[rune]int)
// keep a list of what characters exist in the string s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what for?

chars := ""
for _, c := range s {
if !strings.ContainsAny(chars, string(c)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inefficient. ContainsAny is O(n) and so it strings.Count(s, string(c)), updating a map is O(1).
I accept that runtime is irrelevant for the size of strings expected in this program, but it is good practise to be aware.

for _, c := range s {
    m[c]++
}

should do the trick

numberOfc := strings.Count(s, string(c))
m[c] = numberOfc
chars += string(c)
}
}
return m
}

func sortLetters(m map[rune]int) []string {
result := make([]string, 0)
keys := make([]int, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the capacity to make as you know it len(m).

for k := range m {
keys = append(keys, int(k))
}
sort.Ints(keys)
for _, k := range keys {
unquoted, _ := strconv.Unquote(strconv.QuoteRune(rune(k)))
result = append(result, unquoted+":"+strconv.Itoa(m[rune(k)]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s := fmt.Sprintf("%c:%d", rune(k), m[rune(k)])
result = append(result, s)

}
return result
}

func main() {
fmt.Fprintln(out, strings.Join(sortLetters(letters("aba")), "\n"))
}
47 changes: 47 additions & 0 deletions 03_letters/marchitect/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

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

// this testing function aims to test two functions letters() and sortLetters() from main, together
func Test_letters_and_sortLetters(t *testing.T) {
tables := []struct {
nameOfTestcase string
input string
output []string
}{
{"normal test 1", "test", []string{"e:1", "s:1", "t:2"}},
{"normal test 2", "$Bfs`BY", []string{"$:1", "B:2", "Y:1", "`:1", "f:1", "s:1"}},
{"empty input", "", []string{}},
{"Mandarin Characters Hello", "你好", []string{"你:1", "好:1"}},
{"normal test 3", "Brain drained", []string{" :1", "B:1", "a:2", "d:2", "e:1", "i:2", "n:2", "r:2"}},
}
for _, table := range tables {
expected := sortLetters(letters(table.input))
actual := table.output
// reference: https://yourbasic.org/golang/compare-slices/
if !reflect.DeepEqual(actual, expected) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use testify assert.Equal to turn these three lines into a oneliner.

t.Errorf("Unexpected output from test %s, expected = %s, actual = %s", table.nameOfTestcase, expected, actual)
}
}
}

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

main()

expected := strconv.Quote(`a:2
b:1
`)
actual := strconv.Quote(buf.String())

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