Return to problem list2019-1C Problem B
Final solution
func start() {
var t, F int
mustReadLineOfInts(&t, &F)
for i := 0; i < t; i++ {
test(F)
}
}
const A = byte('A')
type Pib struct {
id int
arr []byte
}
var fact [6]int = [6]int{1, 1, 2, 6, 24, 120}
func test(F int) {
query := func(pos int) byte {
fmt.Fprintf(stdout, "%d\n", pos+1)
stdout.Flush()
ret := mustReadLine()[0]
if ret == 'N' {
os.Exit(0)
}
return ret - A
}
leftToQuery := make([]Pib, 119)
for i := 0; i < len(leftToQuery); i++ {
leftToQuery[i].id = i
leftToQuery[i].arr = make([]byte, 5)
}
for prefixKnown := 0; prefixKnown < 3; prefixKnown++ {
counts := make([]int, 5)
for i := 0; i < len(leftToQuery); i++ {
lt := &leftToQuery[i]
res := query(lt.id*5 + prefixKnown)
counts[res]++
lt.arr[prefixKnown] = res
}
letterIs := byte(0)
expectedCount := 120
for i := 0; i <= prefixKnown; i++ {
expectedCount /= (5 - i)
}
for i, cnt := range counts {
if cnt == expectedCount-1 {
letterIs = byte(i)
break
} else if cnt != expectedCount {
assert(cnt == 0)
}
}
newLeftToQuery := make([]Pib, 0, len(leftToQuery))
for _, lt := range leftToQuery {
if lt.arr[prefixKnown] == letterIs {
newLeftToQuery = append(newLeftToQuery, lt)
}
}
assert(len(newLeftToQuery) == expectedCount-1)
leftToQuery = newLeftToQuery
}
assert(len(leftToQuery) == 1)
rsp := query(leftToQuery[0].id*5 + 3)
leftToQuery[0].arr[4] = rsp
missing := leftToQuery[0].arr
letterMissing := make(map[byte]bool)
for b := byte(0); b < 5; b++ {
letterMissing[b] = true
}
for _, l := range missing[0:3] {
delete(letterMissing, l)
}
delete(letterMissing, missing[4])
var msLetter byte
for l, _ := range letterMissing {
msLetter = l
break
}
missing[3] = msLetter
for _, b := range missing {
stdout.WriteByte(b + A)
}
stdout.WriteByte('\n')
stdout.Flush()
if mustReadLine() != "Y" {
os.Exit(0)
}
}