← Home
```go
package main

import (
	"fmt"
	"os"
)

var poss []string

func generate() {
	for a := 0; a < 10; a++ {
		for b := 0; b < 10; b++ {
			if b == a {
				continue
			}
			for c := 0; c < 10; c++ {
				if c == a || c == b {
					continue
				}
				for d := 0; d < 10; d++ {
					if d == a || d == b || d == c {
						continue
					}
					s := fmt.Sprintf("%d%d%d%d", a, b, c, d)
					poss = append(poss, s)
				}
			}
		}
	}
}

func compute(guess, secret string) (int, int) {
	bulls := 0
	matched := [4]bool{}
	for i := 0; i < 4; i++ {
		if guess[i] == secret[i] {
			bulls++
			matched[i] = true
		}
	}
	cows := 0
	for i := 0; i < 4; i++ {
		if guess[i] == secret[i] {
			continue
		}
		for j := 0; j < 4; j++ {
			if !matched[j] && guess[i] == secret[j] {
				cows++
				matched[j] = true
				break
			}
		}
	}
	return bulls, cows
}

func main() {
	generate()
	currentPoss := append([]string{}, poss...)
	queries := 0
	for {
		if len(currentPoss) == 0 || queries >= 50 {
			break
		}
		var bestGuess string
		bestScore := 999999
		for _, g := range currentPoss {
			counts := make(map[int]int)
			for _, s := range currentPoss {
				b, c := compute(g, s)
				key := b*5 + c
				counts[key]++
			}
			maxBucket := 0
			for _, v := range counts {
				if v > maxBucket {
					maxBucket = v
				}
			}
			if maxBucket < bestScore {
				bestScore = maxBucket
				bestGuess = g
			} else if maxBucket == bestScore {
				if g < bestGuess {
					bestGuess = g
				}
			}
		}
		fmt.Println(bestGuess)
		os.Stdout.Sync()
		var b, c int
		_, err := fmt.Scan(&b, &c)
		if err != nil {
			break
		}
		if b == 4 && c == 0 {
			break
		}
		newPoss := []string{}
		for _, s := range currentPoss {
			bb, cc := compute(bestGuess, s)
			if bb == b && cc == c {
				newPoss = append(newPoss, s)
			}
		}
		currentPoss = newPoss
		queries++
	}
}
```