Sprawdź, czy co najmniej dwie z trzech wartości logicznych są prawdziwe

Ankieter zadał mi ostatnio takie pytanie: biorąc pod uwagę trzy zmienne logiczne, a, b I c, zwraca true, jeśli co najmniej dwie z trzech są prawdziwe.

Moje rozwiązanie:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    else{
        return false;
    }
}
Powiedział, że można to jeszcze poprawić, ale jak?
Author: user282886, 2010-06-19

30 answers

Zamiast pisać:

if (someExpression) {
    return true;
} else {
    return false;
}

Napisz:

return someExpression;

Co do samego wyrażenia, coś takiego:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a ? (b || c) : (b && c);
}

Lub to (cokolwiek znajdziesz łatwiejsze do uchwycenia):

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return a && (b || c) || (b && c);
}

Testuje a i b dokładnie raz, a c co najwyżej raz.

Referencje

 803
Author: polygenelubricants,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 08:41:47

Tylko ze względu na użycie XOR do odpowiedzi na stosunkowo prosty problem...

return a ^ b ? c : a
 480
Author: Tim Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-21 17:43:51

Dlaczego nie zaimplementować go dosłownie? :)

(a?1:0)+(b?1:0)+(c?1:0) >= 2

W C możesz po prostu napisać a+b+c >= 2 (lub !!a+!!b+!!c >= 2, aby być bardzo bezpiecznym).

W odpowiedzi na tofubeer porównanie kodu bajtowego Javy, Oto prosty test wydajności:

class Main
{
    static boolean majorityDEAD(boolean a,boolean b,boolean c)
    {
        return a;
    }

    static boolean majority1(boolean a,boolean b,boolean c)
    {
        return a&&b || b&&c || a&&c;
    }

    static boolean majority2(boolean a,boolean b,boolean c)
    {
        return a ? b||c : b&&c;
    }

    static boolean majority3(boolean a,boolean b,boolean c)
    {
        return a&b | b&c | c&a;
    }

    static boolean majority4(boolean a,boolean b,boolean c)
    {
        return (a?1:0)+(b?1:0)+(c?1:0) >= 2;
    }

    static int loop1(boolean[] data, int i, int sz1, int sz2)
    {
        int sum = 0;
        for(int j=i;j<i+sz1;j++)
        {
            for(int k=j;k<j+sz2;k++)
            {
                sum += majority1(data[i], data[j], data[k])?1:0; 
                sum += majority1(data[i], data[k], data[j])?1:0; 
                sum += majority1(data[j], data[k], data[i])?1:0; 
                sum += majority1(data[j], data[i], data[k])?1:0; 
                sum += majority1(data[k], data[i], data[j])?1:0; 
                sum += majority1(data[k], data[j], data[i])?1:0; 
            }
        }
        return sum;
    }

    static int loop2(boolean[] data, int i, int sz1, int sz2)
    {
        int sum = 0;
        for(int j=i;j<i+sz1;j++)
        {
            for(int k=j;k<j+sz2;k++)
            {
                sum += majority2(data[i], data[j], data[k])?1:0; 
                sum += majority2(data[i], data[k], data[j])?1:0; 
                sum += majority2(data[j], data[k], data[i])?1:0; 
                sum += majority2(data[j], data[i], data[k])?1:0; 
                sum += majority2(data[k], data[i], data[j])?1:0; 
                sum += majority2(data[k], data[j], data[i])?1:0; 
            }
        }
        return sum;
    }

    static int loop3(boolean[] data, int i, int sz1, int sz2)
    {
        int sum = 0;
        for(int j=i;j<i+sz1;j++)
        {
            for(int k=j;k<j+sz2;k++)
            {
                sum += majority3(data[i], data[j], data[k])?1:0; 
                sum += majority3(data[i], data[k], data[j])?1:0; 
                sum += majority3(data[j], data[k], data[i])?1:0; 
                sum += majority3(data[j], data[i], data[k])?1:0; 
                sum += majority3(data[k], data[i], data[j])?1:0; 
                sum += majority3(data[k], data[j], data[i])?1:0; 
            }
        }
        return sum;
    }

    static int loop4(boolean[] data, int i, int sz1, int sz2)
    {
        int sum = 0;
        for(int j=i;j<i+sz1;j++)
        {
            for(int k=j;k<j+sz2;k++)
            {
                sum += majority4(data[i], data[j], data[k])?1:0; 
                sum += majority4(data[i], data[k], data[j])?1:0; 
                sum += majority4(data[j], data[k], data[i])?1:0; 
                sum += majority4(data[j], data[i], data[k])?1:0; 
                sum += majority4(data[k], data[i], data[j])?1:0; 
                sum += majority4(data[k], data[j], data[i])?1:0; 
            }
        }
        return sum;
    }

    static int loopDEAD(boolean[] data, int i, int sz1, int sz2)
    {
        int sum = 0;
        for(int j=i;j<i+sz1;j++)
        {
            for(int k=j;k<j+sz2;k++)
            {
                sum += majorityDEAD(data[i], data[j], data[k])?1:0; 
                sum += majorityDEAD(data[i], data[k], data[j])?1:0; 
                sum += majorityDEAD(data[j], data[k], data[i])?1:0; 
                sum += majorityDEAD(data[j], data[i], data[k])?1:0; 
                sum += majorityDEAD(data[k], data[i], data[j])?1:0; 
                sum += majorityDEAD(data[k], data[j], data[i])?1:0; 
            }
        }
        return sum;
    }

    static void work()
    {
        boolean [] data = new boolean [10000];
        java.util.Random r = new java.util.Random(0);
        for(int i=0;i<data.length;i++)
            data[i] = r.nextInt(2) > 0;
        long t0,t1,t2,t3,t4,tDEAD;
        int sz1 = 100;
        int sz2 = 100;
        int sum = 0;

        t0 = System.currentTimeMillis();

        for(int i=0;i<data.length-sz1-sz2;i++)
            sum += loop1(data, i, sz1, sz2);

        t1 = System.currentTimeMillis();

        for(int i=0;i<data.length-sz1-sz2;i++)
            sum += loop2(data, i, sz1, sz2);

        t2 = System.currentTimeMillis();

        for(int i=0;i<data.length-sz1-sz2;i++)
            sum += loop3(data, i, sz1, sz2);

        t3 = System.currentTimeMillis();

        for(int i=0;i<data.length-sz1-sz2;i++)
            sum += loop4(data, i, sz1, sz2);

        t4 = System.currentTimeMillis();

        for(int i=0;i<data.length-sz1-sz2;i++)
            sum += loopDEAD(data, i, sz1, sz2);

        tDEAD = System.currentTimeMillis();

        System.out.println("a&&b || b&&c || a&&c : " + (t1-t0) + " ms");
        System.out.println("   a ? b||c : b&&c   : " + (t2-t1) + " ms");
        System.out.println("   a&b | b&c | c&a   : " + (t3-t2) + " ms");
        System.out.println("   a + b + c >= 2    : " + (t4-t3) + " ms");
        System.out.println("       DEAD          : " + (tDEAD-t4) + " ms");
        System.out.println("sum: "+sum);
    }

    public static void main(String[] args) throws InterruptedException
    {
        while(true)
        {
            work();
            Thread.sleep(1000);
        }
    }
}

To wyświetla na mojej maszynie (z Ubuntu na Intel Core 2 + Sun java 1.6.0_15-B03 z HotSpot Server VM (14.1-b02, tryb mieszany)):

Pierwsza i druga iteracja:

a&&b || b&&c || a&&c : 1740 ms
   a ? b||c : b&&c   : 1690 ms
   a&b | b&c | c&a   : 835 ms
   a + b + c >= 2    : 348 ms
       DEAD          : 169 ms
sum: 1472612418

Później iteracja:

a&&b || b&&c || a&&c : 1638 ms
   a ? b||c : b&&c   : 1612 ms
   a&b | b&c | c&a   : 779 ms
   a + b + c >= 2    : 905 ms
       DEAD          : 221 ms

Zastanawiam się, co java VM może zrobić, że obniża wydajność w czasie dla (A + b + c >= 2) przypadku.

A oto, co się stanie, jeśli uruchomię Javę z przełącznikiem VM -client:

a&&b || b&&c || a&&c : 4034 ms
   a ? b||c : b&&c   : 2215 ms
   a&b | b&c | c&a   : 1347 ms
   a + b + c >= 2    : 6589 ms
       DEAD          : 1016 ms
Tajemnica...

I jeśli uruchomię go w GNU Java Interpreter, będzie prawie 100 razy wolniejszy, ale wtedy wygrywa wersja a&&b || b&&c || a&&c.

Wyniki z Tofubeer z najnowszym kodem z systemem OS X:

a&&b || b&&c || a&&c : 1358 ms
   a ? b||c : b&&c   : 1187 ms
   a&b | b&c | c&a   : 410 ms
   a + b + c >= 2    : 602 ms
       DEAD          : 161 ms

Wyniki Paula Waglanda z Mac Java 1.6.0_26-b03-383-11a511

a&&b || b&&c || a&&c : 394 ms 
   a ? b||c : b&&c   : 435 ms
   a&b | b&c | c&a   : 420 ms
   a + b + c >= 2    : 640 ms
   a ^ b ? c : a     : 571 ms
   a != b ? c : a    : 487 ms
       DEAD          : 170 ms
 212
Author: Rotsor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 11:20:25

Tego typu pytania można rozwiązać za pomocą mapy Karnaugha :

      | C | !C
------|---|----
 A  B | 1 | 1 
 A !B | 1 | 0
!A !B | 0 | 0
!A  B | 1 | 0

Z którego wnioskujesz, że potrzebujesz grupy dla pierwszego wiersza i dwóch grup dla pierwszej kolumny, uzyskując optymalne rozwiązanie poligenelubricants:

(C && (A || B)) || (A && B)  <---- first row
       ^
       |
   first column without third case
 142
Author: Jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 16:10:17

Czytelność powinna być celem. Ktoś, kto czyta kod musi natychmiast zrozumieć twoje intencje. Oto moje rozwiązanie.

int howManyBooleansAreTrue =
      (a ? 1 : 0)
    + (b ? 1 : 0)
    + (c ? 1 : 0);

return howManyBooleansAreTrue >= 2;
 139
Author: danatel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:33:14
return (a==b) ? a : c;

Wyjaśnienie:

If a==b, then both are true or both are false. Jeśli oba są prawdziwe, znaleźliśmy nasze dwa prawdziwe booleany i możemy zwrócić true (zwracając a). Jeśli obie wartości są fałszywe, nie mogą istnieć dwie wartości logiczne prawdziwe, nawet jeśli c jest prawdziwe, więc zwracamy false (zwracając a). To jest (a==b) ? a część. A co z : c ? Cóż, jeśli a==b jest false, to dokładnie jeden z a lub b musi być true, więc znaleźliśmy pierwszy true boolean i jedyne, co się liczy, to jeśli c jest również prawdą, to zwracamy c jako odpowiedź.

 129
Author: Boann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 18:09:08

Nie musisz używać form zwarciowych operatorów.

return (a & b) | (b & c) | (c & a);

To wykonuje taką samą liczbę operacji logicznych jak twoja wersja, Jednak jest całkowicie bez rozgałęzień.

 34
Author: moonshadow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 15:51:42

Oto ogólne podejście oparte na testach. Nie tak "wydajne" jak większość dotychczas oferowanych rozwiązań, ale jasne, sprawdzone, działające i uogólnione.

public class CountBooleansTest extends TestCase {
    public void testThreeFalse() throws Exception {
        assertFalse(atLeastTwoOutOfThree(false, false, false));
    }

    public void testThreeTrue() throws Exception {
        assertTrue(atLeastTwoOutOfThree(true, true, true));
    }

    public void testOnes() throws Exception {
        assertFalse(atLeastTwoOutOfThree(true, false, false));
        assertFalse(atLeastTwoOutOfThree(false, true, false));
        assertFalse(atLeastTwoOutOfThree(false, false, true));
    }

    public void testTwos() throws Exception {
        assertTrue(atLeastTwoOutOfThree(false, true, true));
        assertTrue(atLeastTwoOutOfThree(true, false, true));
        assertTrue(atLeastTwoOutOfThree(true, true, false));
    }

    private static boolean atLeastTwoOutOfThree(boolean b, boolean c, boolean d) {
        return countBooleans(b, c, d) >= 2;
    }

    private static int countBooleans(boolean... bs) {
        int count = 0;
        for (boolean b : bs)
            if (b)
                count++;
        return count;
    }
}
 27
Author: Carl Manaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 19:58:30

Summ it up. Nie bez powodu nazywa się algebrą Boole ' a:

  0 x 0 = 0
  1 x 0 = 0
  1 x 1 = 1

  0 + 0 = 0
  1 + 0 = 1
  1 + 1 = 0 (+ carry)

Jeśli spojrzysz na tabele prawdy, zobaczysz, że mnożenie jest boolowskie i, a po prostu dodawanie jest xor.

Aby odpowiedzieć na twoje pytanie:

return (a + b + c) >= 2
 24
Author: memet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-21 20:00:25
boolean atLeastTwo(boolean a, boolean b, boolean c) 
{
  return ((a && b) || (b && c) || (a && c));
}
 15
Author: malu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 17:38:56

To naprawdę zależy co masz na myśli przez "poprawione":

/ Align = "left" /
boolean twoOrMoreAreTrue(boolean a, boolean b, boolean c)
{
    return (a && b) || (a && c) || (b && c);
}
Terser?
boolean moreThanTwo(boolean a, boolean b, boolean c)
{
    return a == b ? a : c;
}
Bardziej ogólne?
boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(boolean b : bs)
    {
        count += b ? 1 : 0;

        if(count > x) return true;
    }

    return false;
}
Bardziej skalowalne?
boolean moreThanXTrue(int x, boolean[] bs)
{
    int count = 0;

    for(int i < 0; i < bs.length; i++)
    {
        count += bs[i] ? 1 : 0;

        if(count > x) return true;

        int needed = x - count;
        int remaining = bs.length - i;

        if(needed >= remaining) return false;
    }

    return false;
}
Szybciej?
// Only profiling can answer this.

Który z nich jest "ulepszony" zależy w dużej mierze od sytuacji.

 15
Author: kerkeslager,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 22:31:13

Oto kolejna implementacja wykorzystująca map/reduce. To dobrze skaluje się do miliardów booleanów© w środowisku rozproszonym. Użycie MongoDB:

Tworzenie bazy danych values booleanów:

db.values.insert({value: true});
db.values.insert({value: false});
db.values.insert({value: true});

Tworzenie mapy, redukcja funkcji:

Edit : I like CurtainDog ' S odpowiedź o map/reduce stosuje się do list generycznych, więc oto funkcja mapy, która pobiera wywołanie zwrotne, które określa, czy wartość powinna być zliczona, czy nie.

var mapper = function(shouldInclude) {
    return function() {
        emit(null, shouldInclude(this) ? 1 : 0);
    };
}

var reducer = function(key, values) {
    var sum = 0;
    for(var i = 0; i < values.length; i++) {
        sum += values[i];
    }
    return sum;
}

Running map/reduce:

var result = db.values.mapReduce(mapper(isTrue), reducer).result;

containsMinimum(2, result); // true
containsMinimum(1, result); // false


function isTrue(object) {
    return object.value == true;
}

function containsMinimum(count, resultDoc) {
    var record = db[resultDoc].find().next();
    return record.value >= count;
}
 14
Author: Anurag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:41

Biorąc odpowiedzi (jak dotąd) tutaj:

public class X
{
    static boolean a(final boolean a, final boolean b, final boolean c)
    {
    return ((a && b) || (b && c) || (a && c));
    }

    static boolean b(final boolean a, final boolean b, final boolean c)
    {
    return a ? (b || c) : (b && c);
    }

    static boolean c(final boolean a, final boolean b, final boolean c)
    {
    return ((a & b) | (b & c) | (c & a));
    }

    static boolean d(final boolean a, final boolean b, final boolean c)
    {
    return ((a?1:0)+(b?1:0)+(c?1:0) >= 2);
    }
}

I uruchamianie ich przez dekompiler (javap - C x > results.txt):

Compiled from "X.java"
public class X extends java.lang.Object{
public X();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

static boolean a(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iload_1
   5:   ifne    24
   8:   iload_1
   9:   ifeq    16
   12:  iload_2
   13:  ifne    24
   16:  iload_0
   17:  ifeq    28
   20:  iload_2
   21:  ifeq    28
   24:  iconst_1
   25:  goto    29
   28:  iconst_0
   29:  ireturn

static boolean b(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    20
   4:   iload_1
   5:   ifne    12
   8:   iload_2
   9:   ifeq    16
   12:  iconst_1
   13:  goto    33
   16:  iconst_0
   17:  goto    33
   20:  iload_1
   21:  ifeq    32
   24:  iload_2
   25:  ifeq    32
   28:  iconst_1
   29:  goto    33
   32:  iconst_0
   33:  ireturn

static boolean c(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   iload_1
   2:   iand
   3:   iload_1
   4:   iload_2
   5:   iand
   6:   ior
   7:   iload_2
   8:   iload_0
   9:   iand
   10:  ior
   11:  ireturn

static boolean d(boolean, boolean, boolean);
  Code:
   0:   iload_0
   1:   ifeq    8
   4:   iconst_1
   5:   goto    9
   8:   iconst_0
   9:   iload_1
   10:  ifeq    17
   13:  iconst_1
   14:  goto    18
   17:  iconst_0
   18:  iadd
   19:  iload_2
   20:  ifeq    27
   23:  iconst_1
   24:  goto    28
   27:  iconst_0
   28:  iadd
   29:  iconst_2
   30:  if_icmplt   37
   33:  iconst_1
   34:  goto    38
   37:  iconst_0
   38:  ireturn
}
Widzisz to ?: te są nieco lepsze niż poprawiona wersja oryginału. Ten, który jest najlepszy, to ten, który całkowicie unika rozgałęziania. Jest to dobre z punktu widzenia mniejszej liczby instrukcji (w większości przypadków) i lepsze dla części predykcji gałęzi CPU, ponieważ błędne odgadnięcie w predykcji gałęzi może spowodować procesor przeciąganie. Powiedziałbym, że najskuteczniejszy jest ten z moonshadow. Wykorzystuje on średnio najmniejszą liczbę instrukcji i zmniejsza szansę na zablokowanie rurociągów w procesorze.

Aby być w 100% pewnym, musisz poznać koszt (w cyklach CPU) dla każdej instrukcji, która niestety nie jest łatwo dostępna (musisz spojrzeć na źródło hotspotu, a następnie specyfikacje dostawców CPU dla czasu potrzebnego dla każdej Wygenerowanej instrukcji).

Zobacz zaktualizowaną odpowiedź przez Rotsor do analizy kodu w trybie runtime.

 13
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-19 19:52:48

Inny przykład kodu bezpośredniego:

int  n = 0;
if (a) n++;
if (b) n++;
if (c) n++;
return (n >= 2);

To nie jest najbardziej zwięzły kod, oczywiście.

Dodatek

Kolejna (nieco zoptymalizowana) wersja tego:

int  n = -2;
if (a) n++;
if (b) n++;
if (c) n++;
return (n >= 0);

Może to przebiegać nieco szybciej, zakładając, że porównanie z 0 użyje szybszego (a może mniej) kodu niż porównanie z 2.

 13
Author: David R Tribble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-10 16:02:00

Yet another way to do this but not a good one:

return (Boolean.valueOf(a).hashCode() + Boolean.valueOf(b).hashCode() + Boolean.valueOf(c).hashCode()) < 3705);

Wartości hashcode są ustalone na 1231 dla true i 1237 dla false, więc równie dobrze można było użyć <= 3699

 12
Author: barrowc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-20 04:32:35

Najbardziej oczywistym zestawem ulepszeń są:

// There is no point in an else if you already returned.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a && b) || (b && c) || (a && c)) {
        return true;
    }
    return false;
}

A następnie

// There is no point in an if(true) return true otherwise return false.
boolean atLeastTwo(boolean a, boolean b, boolean c) {
    return ((a && b) || (b && c) || (a && c));
}
Ale te ulepszenia są niewielkie.
 12
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:32:07

Nie podoba mi się ternary (return a ? (b || c) : (b && c); od pierwszej odpowiedzi) i chyba nikt o tym nie wspomniał. Jest napisane tak:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if (a) {
        return b||c;
    } 
    else {
        return b&&C;
    }
 10
Author: Roman A. Taycher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:38:54

W Clojure :

(defn at-least [n & bools]
  (>= (count (filter true? bools)) n)

Użycie:

(at-least 2 true false true)
 8
Author: Vagif Verdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:40:57

Chyba jeszcze nie widziałem takiego rozwiązania:

boolean atLeast(int howMany, boolean[] boolValues) {
  // check params for valid values

  int counter = 0;
  for (boolean b : boolValues) {
    if (b) {
      counter++;

      if (counter == howMany) {
        return true;
      }
    }
  }
  return false;
}

Jego zaletą jest to, że gdy osiągnie liczbę, której szukasz, pęka. Jeśli więc było to "co najmniej 2 z tych 1 000 000 wartości są prawdziwe", gdzie pierwsze dwa są rzeczywiście prawdziwe, to powinno pójść szybciej niż niektóre z bardziej "normalnych" rozwiązań.

 6
Author: Joe Enos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-21 22:23:18

Możemy przekonwertować Boole na liczby całkowite i wykonać to proste sprawdzenie:

(int(a) + int(b) + int(c)) >= 2
 6
Author: vine'th,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:53:11

Ponieważ nie sprecyzowano, jak należy poprawić kod, postaram się go poprawić, czyniąc go bardziej zabawnym. Oto moje rozwiązanie:

boolean atLeastTwo(boolean t, boolean f, boolean True) {
    boolean False = True;
    if ((t || f) && (True || False)) 
        return "answer" != "42";
    if (t && f) 
        return !"France".contains("Paris");
    if (False == True) 
        return true == false;
    return Math.random() > 0.5;
}

Gdyby ktoś się zastanawiał, czy ten kod działa, oto uproszczenie przy użyciu tej samej logiki:

boolean atLeastTwo(boolean a, boolean b, boolean c) {
    if ((a || b) && (c)) 
        return true;
    if (a && b) 
        return true;
    if (true) 
        return false;
    // The last line is a red herring, as it will never be reached:
    return Math.random() > 0.5; 

}

Można to podzielić na:

return ((a || b) && (c)) || (a && b);
Ale teraz to już nie jest śmieszne.
 6
Author: Bruce Attah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:55:00
Function ReturnTrueIfTwoIsTrue(bool val1, val2, val3))
{
     return (System.Convert.ToInt16(val1) +
             System.Convert.ToInt16(val2) +
             System.Convert.ToInt16(val3)) > 1;
}
Zbyt wiele sposobów na to...
 5
Author: Duby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-21 17:20:52

Roztwór C.

int two(int a, int b, int c) {
  return !a + !b + !c < 2;
}

Lub wolisz:

int two(int a, int b, int c) {
  return !!a + !!b + !!c >= 2;
}
 5
Author: Mark Edgar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 11:36:42
return 1 << $a << $b << $c >= 1 << 2;
 4
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 12:44:43

Najprostszy sposób (IMO), który nie jest mylący i łatwy do odczytania:

// Three booleans, check if two or more are true

return ( a && ( b || c ) ) || ( b && c );
 4
Author: abelito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:37:33

Literalna interpretacja będzie działać we wszystkich głównych językach:

return (a ? 1:0) + (b ? 1:0) + (c ? 1:0) >= 2;

Ale prawdopodobnie ułatwi to ludziom czytanie i rozszerzy do więcej niż trzech - coś, co wydaje się być zapomniane przez wielu programistów:

boolean testBooleans(Array bools)
{
     int minTrue = ceil(bools.length * .5);
     int trueCount = 0;

     for(int i = 0; i < bools.length; i++)
     {
          if(bools[i])
          {
               trueCount++;
          }
     }
     return trueCount >= minTrue;
}
 4
Author: blakecallens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:40:17

[[3]} jako dodatek do doskonałego postu @tofubeer tofubeer, rozważ odpowiedź @pdox pdox:

static boolean five(final boolean a, final boolean b, final boolean c)
{
    return a == b ? a : c;
}

Rozważ również jego zdemontowaną wersję podaną przez "javap-C":

static boolean five(boolean, boolean, boolean);
  Code:
    0:    iload_0
    1:    iload_1
    2:    if_icmpne    9
    5:    iload_0
    6:    goto    10
    9:    iload_2
   10:    ireturn

Odpowiedź Pdox kompiluje się do mniej bajtowego kodu niż jakakolwiek z poprzednich odpowiedzi. Jak wypada jego czas wykonania w porównaniu do innych?

one                5242 ms
two                6318 ms
three (moonshadow) 3806 ms
four               7192 ms
five  (pdox)       3650 ms

Przynajmniej na moim komputerze, odpowiedź pdox jest tylko nieco szybsza niż odpowiedź @moonshadow moonshadow, dzięki czemu pdox jest najszybszy ogólnie (na moim HP / Intel laptop).

 4
Author: Rex Barzee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 22:46:57

W Ruby:

[a, b, c].count { |x| x } >= 2

Które można uruchomić w JRuby na JavaVM. ;-)

 3
Author: user373826,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-23 03:00:30

On prawdopodobnie nie szuka niczego zawiłego, jak operatory porównawcze bitowe (zwykle nie zawiłe, ale z booleanami, bardzo dziwne jest używanie operatorów bitowych) lub czegoś, co jest bardzo okrężne, jak konwersja do int i sumowanie ich.

Najbardziej bezpośrednim i naturalnym sposobem rozwiązania tego problemu jest wyrażenie takie jak:

a ? (b || c): (b && c)

Umieść go w funkcji, jeśli wolisz, ale to nie jest zbyt skomplikowane. Rozwiązanie jest logicznie zwięzłe i efektywne.

 3
Author: stinky472,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-25 09:28:36

W C:

return !!a + !!b + !!c >= 2;
 3
Author: Matt Joiner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-19 23:13:28