How to resolve the algorithm Bulls and cows/Player step by step in the Go programming language

Published on 12 May 2024 09:40 PM
#Go

How to resolve the algorithm Bulls and cows/Player step by step in the Go programming language

Table of Contents

Problem Statement

Write a player of the Bulls and Cows game, rather than a scorer. The player should give intermediate answers that respect the scores to previous attempts. One method is to generate a list of all possible numbers that could be the answer, then to prune the list by keeping only those numbers that would give an equivalent score to how your last guess was scored. Your next guess can be any number from the pruned list. Either you guess correctly or run out of numbers to guess, which indicates a problem with the scoring.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Bulls and cows/Player step by step in the Go programming language

Detailed Explanation of the Go Source Code

This Go program simulates the classic game of "Cows and Bulls." Here's a breakdown of what it does:

Initialization

  • The program starts by generating a list of all possible four-digit patterns using unique digits from 1 to 9. It stores them in a map for efficient lookup later.

Guessing Loop

The program enters a loop where it:

  1. Picks a guess: It selects a candidate guess from the remaining possible patterns.

  2. Gets a score from the user: The program prompts the user to enter a score for the guess, consisting of two numbers separated by a space: the number of "cows" (correct digits in the wrong place) and "bulls" (correct digits in the correct place).

  3. Parses the score: The user's input is read and parsed into separate "cows" and "bulls" values.

  4. Checks for a win: If the "bulls" value is 4, the program declares victory.

  5. Eliminates patterns: It removes from the list of possible patterns any that don't match the given score.

Inconsistency Check

After each round of guessing and elimination, the program checks if the list of possible patterns is empty. If it is, it means the user's scoring is inconsistent, and the game cannot continue.

Implementation Details

  • Guessing: The program picks a candidate guess from the remaining possible patterns using a simple iteration.
  • Score Parsing: User input is handled using a bufio.Reader and parsed into separate numbers using strconv.ParseUint.
  • Pattern Elimination: The program iterates over the possible patterns and checks for a match with the given score, eliminating those that don't match.

Source code in the go programming language

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    fmt.Println(`Cows and bulls/player
You think of four digit number of unique digits in the range 1 to 9.
I guess.  You score my guess:
    A correct digit but not in the correct place is a cow.
    A correct digit in the correct place is a bull.
You give my score as two numbers separated with a space.`)

    // generate possible patterns, store in map
    m := make(map[string]int)
    var g func([]byte, int)
    g = func(digits []byte, fixed int) {
        if fixed == 4 {
            m[string(digits[:4])] = 0
            return
        }
        for i := fixed; i < len(digits); i++ {
            digits[fixed], digits[i] = digits[i], digits[fixed]
            g(digits, fixed+1)
            digits[fixed], digits[i] = digits[i], digits[fixed]
        }
    }
    g([]byte("123456789"), 0)

    // guess/score/eliminate loop
    for in := bufio.NewReader(os.Stdin);; {
        // pick a value, ie, guess
        var guess string
        for guess = range m {
            delete(m, guess)
            break
        }

        // get and parse score
        var c, b uint
        for ;; fmt.Println("Score guess as two numbers: cows bulls") {
            fmt.Printf("My guess: %s.  Score? (c b) ", guess)
            score, err := in.ReadString('\n')
            if err != nil {
                fmt.Println("\nSo, bye.")
                return
            }
            s2 := strings.Fields(score)
            if len(s2) == 2 {
                c2, err := strconv.ParseUint(s2[0], 10, 0)
                if err == nil && c2 <= 4 {
                    b2, err := strconv.ParseUint(s2[1], 10, 0)
                    if err == nil && c2+b2 <= 4 {
                        c = uint(c2)
                        b = uint(b2)
                        break
                    }
                }
            }
        }

        // check for win
        if b == 4 {
            fmt.Println("I did it. :)")
            return
        }

        // eliminate patterns with non-matching scores
        for pat := range m {
            var cows, bulls uint
            for ig, cg := range guess {
                switch strings.IndexRune(pat, cg) {
                case -1:
                default: // I just think cows should go first
                    cows++
                case ig:
                    bulls++
                }
            }
            if cows != c || bulls != b {
                delete(m, pat)
            }
        }

        // check for inconsistency
        if len(m) == 0 {
            fmt.Println("Oops, check scoring.")
            return
        }
    }
}


  

You may also check:How to resolve the algorithm Read entire file step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Empty program step by step in the OOC programming language
You may also check:How to resolve the algorithm Legendre prime counting function step by step in the Python programming language
You may also check:How to resolve the algorithm Left factorials step by step in the C++ programming language
You may also check:How to resolve the algorithm Longest increasing subsequence step by step in the Erlang programming language