Can someone help me with my logic, I can't think of how to calculate the cows?


  • 0
    J
    var getHint = function(secret, guess) {
    var bull = 0, cow = 0;
    for(var i = 0; i < secret.length; i++){
        if(secret[i] == guess[i]){
            bull += 1;
        }
        for(var j = 0; j < secret.length; j++){
            if(i == j){
                
            }
            else if (guess[i] == secret[j]){
                cow += 1;
                break;
            }
        }
        
    }
    return (bull+"A"+cow+"B"); 
    

    };


  • 0
    J

    btw, i know that this is incomplete... the else if statement in the nested for loop does not function the way it should. but i am having trouble figuring out how to modify the code so that it works..


  • 0
    R

    The problem in the algorithm is that it doesn't remember which numbers where already selected as bulls (or cows). Without that knowledge it counts the same numbers multiple times for cows.

    The straight forward solution would be to remember this in some data structure. Like this:

    var getHint = function(secret, guess) {
        var bull = 0, cow = 0;
        var usedSecrets = {};
        for(var i = 0; i < secret.length; i++){
            if(secret[i] == guess[i]){
                bull += 1;
                usedSecrets[i] = true;
                continue;
            } 
            for(var j = 0; j < secret.length; j++){
                if (!usedSecrets[j] && guess[i] == secret[j]){
                    cow += 1;
                    usedSecrets[j] = true;
                    break;
                }
            }    
        }
        return (bull+"A"+cow+"B");
    };
    

    This code doesn't pass tests though. The problem is that at the time when cows are counted (the inner for loop) there is no way to know whether secret[j] will be matched as a bull in the future. To solve this issue it is required to to it in two passes. The first pass to count all bulls and mark all numbers that were used, and the second pass is to count all cows:

    var getHint = function(secret, guess) {
        var bull = 0, cow = 0;
        var usedSecrets = {}, usedGuesses = {};
        for(var i = 0; i < secret.length; i++){
            if(secret[i] == guess[i]){
                bull += 1;
                usedSecrets[i] = true;
                usedGuesses[i] = true;
            } 
        }
        for(i = 0; i < secret.length; i++){
            if (usedGuesses[i]) continue;
            for(var j = 0; j < secret.length; j++){
                if (!usedSecrets[j] && guess[i] == secret[j]){
                    cow += 1;
                    usedSecrets[j] = true;
                    break;
                }
            }    
        }
        return (bull+"A"+cow+"B");
    };
    

    There is also an alternative solution where this can be done in one pass (see this post). The javascript version of it would be:

    var getHint = function(secret, guess) {
        var bulls = 0, cows = 0, numbers = [0,0,0,0,0,0,0,0,0,0];
        for (var i = 0; i<secret.length; i++) {
            if (secret[i] == guess[i]) bulls++;
            else {
                if (numbers[secret[i]]++ < 0) cows++;
                if (numbers[guess[i]]-- > 0) cows++;
            }
        }
        return bulls + "A" + cows + "B";
    }
    

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.