-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy path148.go
134 lines (120 loc) · 1.96 KB
/
148.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
125
126
127
128
129
130
131
132
133
134
// UVa 148 - Anagram checker
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
)
var (
words []string
visited map[string]bool
charMap map[byte]int
paths [][]string
)
func getMap(line string) map[byte]int {
m := make(map[byte]int)
for i := range line {
if line[i] != ' ' {
m[line[i]]++
}
}
return m
}
func contains(word string) bool {
cm := getMap(word)
for k, v1 := range cm {
if v2, ok := charMap[k]; !ok || v2 < v1 {
return false
}
}
return true
}
func remove(word string) {
cm := getMap(word)
for k, v := range cm {
charMap[k] -= v
}
}
func add(word string) {
cm := getMap(word)
for k, v := range cm {
charMap[k] += v
}
}
func full() bool {
for _, v := range charMap {
if v != 0 {
return false
}
}
return true
}
func newPath(path []string) bool {
here:
for _, p := range paths {
if len(p) == len(path) {
for i := range path {
if path[i] != p[i] {
continue here
}
}
return false
}
}
return true
}
func dfs(path []string) {
if full() {
cp := make([]string, len(path))
copy(cp, path)
sort.Strings(cp)
if newPath(cp) {
paths = append(paths, cp)
}
return
}
for _, word := range words {
if !visited[word] && contains(word) {
visited[word] = true
remove(word)
dfs(append(path, word))
visited[word] = false
add(word)
}
}
}
func solve(line string) {
charMap = getMap(line)
visited = make(map[string]bool)
paths = nil
for _, word := range strings.Fields(line) {
visited[word] = true
}
dfs(nil)
}
func main() {
in, _ := os.Open("148.in")
defer in.Close()
out, _ := os.Create("148.out")
defer out.Close()
s := bufio.NewScanner(in)
s.Split(bufio.ScanLines)
var line string
for s.Scan() {
if line = s.Text(); line == "#" {
break
}
words = append(words, line)
}
for s.Scan() {
if line = s.Text(); line == "#" {
break
}
solve(line)
for _, path := range paths {
fmt.Fprintf(out, "%s = %s\n", line, strings.Join(path, " "))
}
}
}