-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path843-GuessTheWord.go
More file actions
163 lines (149 loc) · 5.9 KB
/
843-GuessTheWord.go
File metadata and controls
163 lines (149 loc) · 5.9 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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package main
// 843. Guess the Word
// You are given an array of unique strings words where words[i] is six letters long.
// One word of words was chosen as a secret word.
// You are also given the helper object Master.
// You may call Master.guess(word) where word is a six-letter-long string, and it must be from words.
// Master.guess(word) returns:
// -1 if word is not from words, or
// an integer representing the number of exact matches (value and position) of your guess to the secret word.
// There is a parameter allowedGuesses for each test case where allowedGuesses is the maximum number of times you can call Master.guess(word).
// For each test case, you should call Master.guess with the secret word without exceeding the maximum number of allowed guesses. You will get:
// 1. "Either you took too many guesses, or you did not find the secret word."
// if you called Master.guess more than allowedGuesses times or
// if you did not call Master.guess with the secret word, or
// 2. "You guessed the secret word correctly."
// if you called Master.guess with the secret word with the number of calls to Master.guess less than or equal to allowedGuesses.
// The test cases are generated such that you can guess the secret word with a reasonable strategy (other than using the bruteforce method).
// Example 1:
// Input: secret = "acckzz", words = ["acckzz","ccbazz","eiowzz","abcczz"], allowedGuesses = 10
// Output: You guessed the secret word correctly.
// Explanation:
// master.guess("aaaaaa") returns -1, because "aaaaaa" is not in wordlist.
// master.guess("acckzz") returns 6, because "acckzz" is secret and has all 6 matches.
// master.guess("ccbazz") returns 3, because "ccbazz" has 3 matches.
// master.guess("eiowzz") returns 2, because "eiowzz" has 2 matches.
// master.guess("abcczz") returns 4, because "abcczz" has 4 matches.
// We made 5 calls to master.guess, and one of them was the secret, so we pass the test case.
// Example 2:
// Input: secret = "hamada", words = ["hamada","khaled"], allowedGuesses = 10
// Output: You guessed the secret word correctly.
// Explanation: Since there are two words, you can guess both.
// Constraints:
// 1 <= words.length <= 100
// words[i].length == 6
// words[i] consist of lowercase English letters.
// All the strings of wordlist are unique.
// secret exists in words.
// 10 <= allowedGuesses <= 30
import "fmt"
type Master struct {
}
func (this *Master) Guess(word string) int {
return 1
}
/**
* // This is the Master's API interface.
* // You should not implement it, or speculate about its implementation
* type Master struct {
* }
*
* func (this *Master) Guess(word string) int {}
*/
func findSecretWord(wordlist []string, master *Master) {
// map word to a score
wordMap := make(map[string]int)
for i := range wordlist {
wordMap[wordlist[i]] = 0
}
getMaxKey := func(m map[string]int) string {
res, max := "", -1
for k, v := range m {
if v > max {
max = v
res = k
}
}
delete(m, res)
return res
}
pruneMap := func(m map[string]int, word string, score int) string {
maxScore, bestGuess := -1, ""
for k := range m {
for i := range word {
if k[i] == word[i] {
m[k] += score
if score == 0 {
delete(m, k)
}
}
}
if m[k] > maxScore {
maxScore = m[k]
bestGuess = k
}
}
delete(m, bestGuess)
return bestGuess
}
// just use first word as first guess
guess := wordlist[0]
for i := 0; i < 10; i++ {
score := master.Guess(guess)
if score == -1 {
guess = getMaxKey(wordMap) // if there were no matches to guess, then use the less best guess
}
guess = pruneMap(wordMap, guess, score) // re-update map scores and return best guess with highest score
}
}
func findSecretWord1(words []string, master *Master) {
mp, g := map[string]bool{}, ""
for _, w := range words {
mp[w] = true
}
check := func (a, b string) int {
res := 0
for i := 0; i < 6; i++ {
if a[i] == b[i] {
res++
}
}
return res
}
for {
// pick a word and remove from map
for w, _ := range mp {
g = w
delete(mp,g)
break
}
n := master.Guess(g)
if n == 6 { // correct guess
return
}
// remove all impossible words
for w, _ := range mp {
if check(g,w) != n {
delete(mp,w)
}
}
}
}
func main() {
// Example 1:
// Input: secret = "acckzz", words = ["acckzz","ccbazz","eiowzz","abcczz"], allowedGuesses = 10
// Output: You guessed the secret word correctly.
// Explanation:
// master.guess("aaaaaa") returns -1, because "aaaaaa" is not in wordlist.
// master.guess("acckzz") returns 6, because "acckzz" is secret and has all 6 matches.
// master.guess("ccbazz") returns 3, because "ccbazz" has 3 matches.
// master.guess("eiowzz") returns 2, because "eiowzz" has 2 matches.
// master.guess("abcczz") returns 4, because "abcczz" has 4 matches.
// We made 5 calls to master.guess, and one of them was the secret, so we pass the test case.
fmt,Println(findSecretWord([]string{"acckzz","ccbazz","eiowzz","abcczz"}, master1)) // You guessed the secret word correctly.
// Example 2:
// Input: secret = "hamada", words = ["hamada","khaled"], allowedGuesses = 10
// Output: You guessed the secret word correctly.
// Explanation: Since there are two words, you can guess both.
fmt,Println(findSecretWord([]string{"hamada","khaled"}, master2)) // You guessed the secret word correctly.
}