Bulls and Cows


Task

Create a four digit random number from the digits   1   to   9,   without duplication.

The program should:

   ask for guesses to this number
   reject guesses that are malformed
   print the score for the guess


The score is computed as:

 The player wins if the guess is the same as the randomly chosen number, and the program ends.
 A score of one bull is accumulated for each digit in the guess that equals the corresponding digit in the randomly chosen initial number.
 A score of one cow is accumulated for each digit in the guess that also appears in the randomly chosen number, but in the wrong position.


Related tasks

   Bulls and cows/Player
   Guess the number
   Guess the number/With Feedback
   Mastermind


main =>
    Digits = to_array("123456789"),
    Size = 4,
    random_sample(Size,Size,[],ChosenIndecies),
    Chosen = {Digits[I] : I in ChosenIndecies},
    printf("I have chosen a number from %d unique digits from 1 to 9 arranged in a random order.\n", Size),
    printf("You need to input a %d digit, unique digit number as a guess at what I have chosen.\n", Size),
    guess(Chosen,Size,1).
 
guess(Chosen,Size,NGuess) =>
    Input = read_line(),
    Guess = Input.to_array(),
    if len(Guess) != Size || len(sort_remove_dups(Input)) != Size || (member(D, Input), (D @< '1' || D @> '9'))  then
        printf("Problem, try again. You need to enter %d unique digits from 1 to 9\n", Size),
        guess(Chosen,Size,NGuess)
    elseif Guess == Chosen then
        printf("\nCongratulations you guessed correctly in %d attempts\n", NGuess)
    else
        Bulls = sum([cond(Chosen[I] == Guess[I], 1, 0) : I in 1..Size]),
        Cows = sum([cond(member(Chosen[I], Input), 1, 0) : I in 1..Size]),
        printf("%d Bulls\n%d Cows\n", Bulls, Cows),
        guess(Chosen, Size, NGuess+1)
    end.
 
random_sample(_N,0,Chosen0,Chosen) => Chosen = Chosen0.
random_sample(N,I,Chosen0,Chosen) =>
    R = random() mod N + 1,
    (not member(R, Chosen0) ->
        random_sample(N,I-1,[R|Chosen0],Chosen)
    ;
        random_sample(N,I,Chosen0,Chosen)
    ).
 