Skip to main content
Edited in requested clarification.
Source Link
Eman Yalpsid
  • 1.5k
  • 11
  • 16

You can check if all the counters are non-negative like so.
Set a variable allnonneg to true if the first counter is non-negative. Then loop through the remaining counters.

If during the \$i\$-th iteration you find a counter, which is negative, then you change allnonneg to false. Otherwise you keep allnonneg as it is. If in the end allnonneg is true, then you know that every counter was non-negative. If it's false, then you'll know that there was a counter which was negative. This is because the only way the value of allnonneg can change is if there is a counter which is negative.

To do this manipulation, you need a function f, such that f(allnonneg, charset[i] >= 0) is true precisely when both allnonneg, and charset[i] >= 0 are true. Luckily there's already an operator && which does this, so we get

allnonneg = f(allnonneg, charset[i] >= 0) = allnonneg && (charset[i] >= 0)

which is the same as allnonneg &= (charset[i] >= 0).


private static int decide(String sa, String sb){
    int [] charset = new int[26];

    for(int i = 0; i < sa.length(); charset[sa.charAt(i) - 97] ++, i++);
    for(int i = 0; i < sb.length(); charset[sb.charAt(i) - 97] --, i++);

    boolean allnonneg = true;charset[i] >= 0;
    boolean allnonpos = true;charset[i] <= 0;

    for(int i = 0;1; i < 25; i++) {
        allnonneg &= (charset[i] >= 0);
        allnonpos &= (charset[i] <= 0);
    }

    if(allnonneg && allnonpos)
        return 0; // every counter 0 => draw
    if(allnonneg)
        return 1; // 1st won
    if(allnonpos)
        return 2; // 2nd won
    else
        return 0; // mixed signs => draw
}
private static int decide(String sa, String sb){
    int [] charset = new int[26];

    for(int i = 0; i < sa.length(); charset[sa.charAt(i) - 97] ++, i++);
    for(int i = 0; i < sb.length(); charset[sb.charAt(i) - 97] --, i++);

    boolean allnonneg = true;
    boolean allnonpos = true;

    for(int i = 0; i < 25; i++) {
        allnonneg &= (charset[i] >= 0);
        allnonpos &= (charset[i] <= 0);
    }

    if(allnonneg && allnonpos)
        return 0; // every counter 0 => draw
    if(allnonneg)
        return 1; // 1st won
    if(allnonpos)
        return 2; // 2nd won
    else
        return 0; // mixed signs => draw
}

You can check if all the counters are non-negative like so.
Set a variable allnonneg to true if the first counter is non-negative. Then loop through the remaining counters.

If during the \$i\$-th iteration you find a counter, which is negative, then you change allnonneg to false. Otherwise you keep allnonneg as it is. If in the end allnonneg is true, then you know that every counter was non-negative. If it's false, then you'll know that there was a counter which was negative. This is because the only way the value of allnonneg can change is if there is a counter which is negative.

To do this manipulation, you need a function f, such that f(allnonneg, charset[i] >= 0) is true precisely when both allnonneg, and charset[i] >= 0 are true. Luckily there's already an operator && which does this, so we get

allnonneg = f(allnonneg, charset[i] >= 0) = allnonneg && (charset[i] >= 0)

which is the same as allnonneg &= (charset[i] >= 0).


private static int decide(String sa, String sb){
    int [] charset = new int[26];

    for(int i = 0; i < sa.length(); charset[sa.charAt(i) - 97] ++, i++);
    for(int i = 0; i < sb.length(); charset[sb.charAt(i) - 97] --, i++);

    boolean allnonneg = charset[i] >= 0;
    boolean allnonpos = charset[i] <= 0;

    for(int i = 1; i < 25; i++) {
        allnonneg &= (charset[i] >= 0);
        allnonpos &= (charset[i] <= 0);
    }

    if(allnonneg && allnonpos)
        return 0; // every counter 0 => draw
    if(allnonneg)
        return 1; // 1st won
    if(allnonpos)
        return 2; // 2nd won
    else
        return 0; // mixed signs => draw
}
Source Link
Eman Yalpsid
  • 1.5k
  • 11
  • 16

I hate this code, but it is faster.

You said you are only working with strings made of characters from a-z. That means 26 characters. The idea is to use 26 counters, each belonging to a character from a-z.

Go through the first(second) string, and every time you find a character c, you increment(decrement) c's counter by 1.

If every counter is zero, that means the strings are permutations of each other, i.e. it's a draw.

Otherwise if every counter is non-negative, you'll know that the first string won; if every counter is non-positive, you'll know that the second string won.

Finally, if some counters have different signs, then it's again a draw.

private static int decide(String sa, String sb){
    int [] charset = new int[26];

    for(int i = 0; i < sa.length(); charset[sa.charAt(i) - 97] ++, i++);
    for(int i = 0; i < sb.length(); charset[sb.charAt(i) - 97] --, i++);

    boolean allnonneg = true;
    boolean allnonpos = true;

    for(int i = 0; i < 25; i++) {
        allnonneg &= (charset[i] >= 0);
        allnonpos &= (charset[i] <= 0);
    }

    if(allnonneg && allnonpos)
        return 0; // every counter 0 => draw
    if(allnonneg)
        return 1; // 1st won
    if(allnonpos)
        return 2; // 2nd won
    else
        return 0; // mixed signs => draw
}