forked from ociule/codeeval
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbeautiful_strings.go
More file actions
89 lines (77 loc) · 1.85 KB
/
beautiful_strings.go
File metadata and controls
89 lines (77 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import "fmt"
import "log"
import "bufio"
import "os"
import "unicode"
import "sort"
// Start of Counter module - this should be in a different import but no easy way to import my own module in codeeval
// This Counter is inspired by python's collections.Counter
type Counter struct {
Data map[interface{}]int
}
func (c *Counter) Add(o interface{}) {
if c.Data == nil {
c.Data = make(map[interface{}]int)
}
c.Data[o] += 1
}
type ItemWithCount struct {
Item interface{}
Count int
}
// Used by MostCommon for sorting the list of ItemWithCount
type ByCount []ItemWithCount
func (this ByCount) Len() int {
return len(this)
}
func (this ByCount) Less(i, j int) bool {
return this[i].Count < this[j].Count
}
func (this ByCount) Swap(i, j int) {
this[i], this[j] = this[j], this[i]
}
// Returns a list of the n most common elements, from most common to least. If howMany is 0, MostCommon returns all the elements.
func (c *Counter) MostCommon(howMany int) []ItemWithCount {
if howMany == 0 {
howMany = len(c.Data)
}
out := make([]ItemWithCount, 0, len(c.Data))
for k, v := range c.Data {
out = append(out, ItemWithCount{k, v})
}
sort.Sort(sort.Reverse(ByCount(out)))
return out[0:howMany]
}
// End of counter module
func beautyScore(line string) int {
freqs := make(map[rune]int)
c := Counter{}
for _, char := range line {
if unicode.IsLetter(char) {
char = unicode.ToLower(char)
freqs[char] += 1
c.Add(char)
}
}
mc := c.MostCommon(0)
score := 26 // We know we must start at 26 and then go down
beauty := 0
for ix, item := range mc {
count := item.Count
beauty += count * (score - ix)
}
return beauty
}
func main() {
file, err := os.Open(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
fmt.Println(beautyScore(line))
}
}