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 | 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.
To build it, just type
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
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 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) } |
go build escapehtml.go
Sunday, August 12, 2012
How to Implement Union Find Algorithms
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 | 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)