Skip to content

Instantly share code, notes, and snippets.

@rocky
Last active December 29, 2015 14:59
Show Gist options
  • Save rocky/7687420 to your computer and use it in GitHub Desktop.
Save rocky/7687420 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
// A PathCount object contains the data that we want to sort on.
type PathCount struct {
path string
count int
}
// By is the type of a "less" function that defines the ordering of
// its arguments.
type By func(p1, p2 *PathCount) bool
// Sort is a method on the function type, By, that sorts the argument
// slice according to the function.
func (by By) Sort(pathcounts []PathCount) {
ps := &pathSorter{
pathcounts: pathcounts,
// The Sort method's receiver is the function (closure) that
// defines the sort order.
by : by,
}
sort.Sort(ps)
}
// pathSorter joins a By function and slice Pathcounts to be sorted.
type pathSorter struct {
pathcounts []PathCount
by func(p1, p2 *PathCount) bool // Closure used in the Less method.
}
// Len is part of sort.Interface.
func (s *pathSorter) Len() int {
return len(s.pathcounts)
}
// Swap is part of sort.Interface.
func (s *pathSorter) Swap(i, j int) {
s.pathcounts[i], s.pathcounts[j] = s.pathcounts[j], s.pathcounts[i]
}
// Less is part of sort.Interface. It is implemented by calling the
// "by" closure in the sorter.
func (s *pathSorter) Less(i, j int) bool {
return s.by(&s.pathcounts[i], &s.pathcounts[j])
}
func main() {
path_map := make(map[string]int)
// f, err := os.Open("/tmp/small.words")
// if err != nil {
// fmt.Printf("error opening file: %s\n", err)
// os.Exit(1)
// }
//scanner := bufio.NewScanner(f)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
path_map[scanner.Text()]++
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
path_counts := make([]PathCount, len(path_map))
i := 0
for path, count := range path_map {
path_counts[i] = PathCount{path: path, count: count}
i++
}
// Closure that orders the path_counts.
reverse_size := func(p1, p2 *PathCount) bool {
return p1.count > p2.count
}
// Sort the path_counts by reverse count value
By(reverse_size).Sort(path_counts)
for i := 0; i<10; i++ {
fmt.Printf("%s %d\n", path_counts[i].path, path_counts[i].count)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment