Task: Bulls and cows




Go: package main

import (
    "bufio"
    "bytes"
    "fmt"
    "math/rand"
    "os"
    "strings"
    "time"
)

func main() {
    fmt.Println(`Cows and Bulls
Guess four digit number of unique digits in the range 1 to 9.
A correct digit but not in the correct place is a cow.
A correct digit in the correct place is a bull.`)
    
    pat := make([]byte, 4)
    rand.Seed(time.Now().Unix())
    r := rand.Perm(9)
    for i := range pat {
        pat[i] = '1' + byte(r[i])
    }

    
    valid := []byte("123456789")
guess:
    for in := bufio.NewReader(os.Stdin); ; {
        fmt.Print("Guess: ")
        guess, err := in.ReadString('\n')
        if err != nil {
            fmt.Println("\nSo, bye.")
            return
        }
        guess = strings.TrimSpace(guess)
        if len(guess) != 4 {
            
            fmt.Println("Please guess a four digit number.")
            continue
        }
        var cows, bulls int
        for ig, cg := range guess {
            if strings.IndexRune(guess[:ig], cg) >= 0 {
                
                fmt.Printf("Repeated digit: %c\n", cg)
                continue guess
            }
            switch bytes.IndexByte(pat, byte(cg)) {
            case -1:
                if bytes.IndexByte(valid, byte(cg)) == -1 {
                    
                    fmt.Printf("Invalid digit: %c\n", cg)
                    continue guess
                }
            default: 
                cows++
            case ig:
                bulls++
            }
        }
        fmt.Printf("Cows: %d, bulls: %d\n", cows, bulls)
        if bulls == 4 {
            fmt.Println("You got it.")
            return
        }
    }
}








Ada: with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Bulls_And_Cows is
   package Random_Natural is new Ada.Numerics.Discrete_Random (Natural);
   Number : String (1..4);
begin
   declare 
      use Random_Natural;
      Digit    : String   := "123456789";
      Size     : Positive := 9;
      Dice     : Generator;
      Position : Natural;
   begin
      Reset (Dice);
      for I in Number'Range loop
         Position := Random (Dice) mod Size + 1;
         Number (I) := Digit (Position);
         Digit (Position..Size - 1) := Digit (Position + 1..Size);
         Size := Size - 1;
      end loop;
   end;
   loop 
      Put ("Enter four digits:");
      declare
         Guess : String  := Get_Line;
         Bulls : Natural := 0;
         Cows  : Natural := 0;
      begin
         if Guess'Length /= 4 then
            raise Data_Error;
         end if;
         for I in Guess'Range loop
            for J in Number'Range loop                  
               if Guess (I) not in '1'..'9' or else (I < J and then Guess (I) = Guess (J)) then
                  raise Data_Error;
               end if;
               if Number (I) = Guess (J) then
                  if I = J then
                     Bulls := Bulls + 1;
                  else
                     Cows := Cows + 1;
                  end if;
               end if;
            end loop;
         end loop;
         exit when Bulls = 4;
         Put_Line (Integer'Image (Bulls) & " bulls," & Integer'Image (Cows) & " cows");
      exception
         when Data_Error => Put_Line ("You should enter four different digits 1..9");
      end;
   end loop;
end Bulls_And_Cows;