use warnings;
use strict;
use v5.10;





my @candidates = grep {not /0 | (\d) .* \1 /x} 1234 .. 9876;





sub read_score($) {
    (my $guess) = @_;

    for (;;) {
        say "My guess: $guess   (from ", 0+@candidates, " possibilities)"; 
        if (<> =~ / ^ \h* (?<BULLS> \d) \h* (?<COWS> \d) \h* $ /x and
            $+{BULLS} + $+{COWS} <= 4) {
                return ($+{BULLS}, $+{COWS});
        }

        say "Please specify the number of bulls and the number of cows";
    }
}

sub score_correct($$$$) {
    my ($a, $b, $bulls, $cows) = @_;

    
    my $exact = () = grep {substr($a, $_, 1) eq substr($b, $_, 1)} 0 .. 3;

    
    
    my $loose = () = $a =~ /[$b]/g;

    return $bulls == $exact && $cows == $loose - $exact;
}

do {
    
    
    my $guess = @candidates[rand @candidates];
    my ($bulls, $cows) = read_score $guess;
    @candidates = grep {score_correct $_, $guess, $bulls, $cows} @candidates;
} while (@candidates > 1);

say(@candidates?
    "Your secret number is @candidates":
    "I think you made a mistake with your scoring");