package main import ( "fmt" "sort" ) func ThreeSum(numbers []int) { for i := 0; i < len(numbers); i++ { for j := 0; j < len(numbers); j++ { nSearch := -(numbers[i] + numbers[j]) index := sort.SearchInts(numbers, nSearch) if index < len(numbers) && numbers[index] == nSearch { fmt.Println(numbers[i], numbers[j], numbers[index]) } } } } func main() { numbers := []int{-40, 30, -10, 50, 20} sortedNumbers := sort.IntSlice(numbers) sort.Sort(sortedNumbers) ThreeSum(sortedNumbers) }
Tuesday, August 14, 2012
How to Solve 3-Sum Problem
Given a set S of n integers, are there elements a, b, c in S such that a + b + c = 0?
Monday, August 13, 2012
A Tool to Escape HTML Characters in Go
I created a handy tool to escape HTML characters, especially for pasting code in a blog like this.
Usage: ./escapehtmlIf the source is a directory, the tool will scan the whole directory and escape each file found and output the escaped string to stdout (if dest_dir isn't specified) or to a file (if dest_dir is specified).[dest_dir]
escapehtml.go
package main import ( "fmt" "os" "errors" "path/filepath" "io/ioutil" "html" "strings" ) func printUsage() { fmt.Println("Usage:", os.Args[0], "<source_file/source_dir>", "[dest_dir]") } func errorMessage(s string) string { return "Error: " + s } type fileType struct { directory bool regularFile bool } func fileExists(path string) (*fileType, error) { file, err := os.Open(path) if err != nil { if os.IsNotExist(err) { return nil, errors.New( errorMessage(path + " does not exist")) } } defer file.Close() fileInfo, err := file.Stat() if err != nil { return nil, err } if fileInfo.IsDir() { return &fileType{directory: true}, nil } return &fileType{regularFile: true}, nil } func validateArgs() (bool, error) { if len(os.Args) != 2 && len(os.Args) != 3 { return false, nil } if _, err := fileExists(os.Args[1]); err != nil { return false, err } if len(os.Args) == 3 { ft, _ := fileExists(os.Args[2]) if ft != nil && !ft.directory { return false, errors.New( errorMessage(os.Args[2] + " must be a directory")) } } return true, nil } func printHeader(header string) { fmt.Println(strings.Repeat("=", 72)) fmt.Println(header) fmt.Println(strings.Repeat("=", 72)) } func escapeHTML(srcPath string, destPath string) { filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error { if info.IsDir() { return nil } b, err := ioutil.ReadFile(path) if err != nil { return nil } escapedString := html.EscapeString(string(b)) if destPath == "" { printHeader(path) fmt.Println(escapedString) } else { if ft, _ := fileExists(destPath); ft == nil { if e := os.MkdirAll(destPath, 0775); e != nil { errors.New("Unable to create directory: " + destPath) } else { fmt.Println("Creating directory: " + destPath) } } newPath := filepath.Join(destPath, filepath.Base(path) + ".txt") fmt.Println("Creating", newPath) e := ioutil.WriteFile(newPath, []byte(escapedString), 0644) if e != nil { return e } } return nil }) } func main() { if valid, err := validateArgs(); !valid { if err != nil { fmt.Println(err) os.Exit(1) } else { printUsage() os.Exit(1) } } srcPath := os.Args[1] destPath := "" if len(os.Args) == 3 { destPath = os.Args[2] } escapeHTML(srcPath, destPath) }To build it, just type
go build escapehtml.go
Sunday, August 12, 2012
How to Implement Union Find Algorithms
package unionfind type UnionFind interface { Find(int, int) bool Union(int, int) } //================================================ type QuickFind struct { Nodes []int } func (qf *QuickFind) Find(x, y int) bool { return qf.Nodes[x] == qf.Nodes[y] } func (qf *QuickFind) Union(x, y int) { tmp := qf.Nodes[x] qf.Nodes[x] = qf.Nodes[y] for i := 0; i < len(qf.Nodes); i++ { if qf.Nodes[i] == tmp { qf.Nodes[i] = qf.Nodes[y] } } } //================================================ type QuickUnion struct { Nodes []int } func (qu *QuickUnion) Find(x, y int) bool { return qu.root(x) == qu.root(y) } func (qu *QuickUnion) Union(x, y int) { rootX := qu.root(x) rootY := qu.root(y) qu.Nodes[rootX] = qu.Nodes[rootY] } func (qu *QuickUnion) root(x int) int { for qu.Nodes[x] != x { x = qu.Nodes[x] } return x } //================================================ type WeightedQuickUnion struct { Nodes []int sizes []int } func (wqu *WeightedQuickUnion) Find(x, y int) bool { return wqu.root(x) == wqu.root(y) } func (wqu *WeightedQuickUnion) Union(x, y int) { rootX := wqu.root(x) rootY := wqu.root(y) if wqu.sizes[rootX] < wqu.sizes[rootY] { wqu.Nodes[rootX] = wqu.Nodes[rootY] wqu.sizes[rootY] += wqu.sizes[rootX] } else { wqu.Nodes[rootY] = wqu.Nodes[rootX] wqu.sizes[rootX] += wqu.sizes[rootY] } } func (wqu *WeightedQuickUnion) root(x int) int { for wqu.Nodes[x] != x { x = wqu.Nodes[x] } return x }
Subscribe to:
Posts (Atom)