in reply to One out of three ain't bad

Ok. The last one is best.
my $only_one = 1 == ($x ? 1 : 0) + ($y ? 1 : 0) + ($z ? 1 :0); + my $only_one = 2 == (! $x) + (! $y) + (! $z); my $only_one = ($x || $y || $z) && (! ($x && $y)) && (! ($y && $z)) && + (! ($z && $x)); my $only_one = (! ($x && $y && $z)) && ($x ^ $y ^ $z);

Replies are listed 'Best First'.
Re^2: One out of three ain't bad
by QM (Parson) on Oct 23, 2005 at 19:52 UTC
    Just a comment on forms for this kind of problem.

    The first two forms explicitly list each variable only once:

    my $only_one = 1 == ($x ? 1 : 0) + ($y ? 1 : 0) + ($z ? 1 :0); + my $only_one = 2 == (! $x) + (! $y) + (! $z);
    The second two forms require each variable to be listed twice:
    my $only_one = ($x || $y || $z) && (! ($x && $y)) && (! ($y && $z)) && + (! ($z && $x)); my $only_one = (! ($x && $y && $z)) && ($x ^ $y ^ $z);
    Just based on this criterion, I'd avoid the 2nd pair of solutions. (Looking at other replies, those with sub, map, grep, or List:Utils will take a list -- easier to maintain.)

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

      I'll disagree here an say a form like...
      if( !$x && !$y && $z or !$x && $y && !$z or $x && !$y && !$z ) { print "Exactly one..."; }
      ...is easier to maintain because it is more explicit as to what is required for a truth value. Anyone versed in boolean algebra will easily recognize the sum-of-product form here and instantly grasp the intent.
        if( !$x && !$y && $z or !$x && $y && !$z or $x && !$y && !$z ) { print "Exactly one..."; }
        I don't think I was clear. I should have added: "How do you expand that for 7, 42, or 105 variables?" It can be done mechanically, fairly easily, but I wouldn't want to end up with an arrangement of 105 x 105, nor would I want to maintain it.

        One might argue that getting from K to K+1 or K-1 variables is also easy (and it is). But I still wouldn't want to deal with it when I could use a list syntax instead.

        Cheers,

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Re^2: One out of three ain't bad
by Anonymous Monk on Oct 23, 2005 at 19:02 UTC
    You probably want logical exclusive or (xor) not bitwise exclusive or (^).

      Good catch. My test framework had a couple of bugs that let me miss that. I've corrected the framework errors, corrected my logical vs bitwise xor error and added the two contributions by anon monks to the tests. It changed the rankings - snowhare4 moved from about 9th to 2nd behind anonmonk1 after fixing. However, anonmonk1 got 3 test case failures, so snowhare4 is now the fastest of the correct solutions. It's nice that the solution that is to me the most elegant is also the fastest correct solution.


      anonmonk1 : 3.26 secs 100% (3 errors) snowhare4 : 4.50 secs 138% (0 errors) snowhare6 : 4.66 secs 143% (0 errors) snowhare2 : 4.99 secs 153% (0 errors) tye2 : 5.13 secs 157% (0 errors) snowhare5 : 5.17 secs 159% (0 errors) snowhare3 : 5.17 secs 159% (0 errors) snowhare1 : 5.30 secs 163% (0 errors) saintmike1 : 6.36 secs 195% (0 errors) tye1 : 7.21 secs 221% (0 errors) saintmike2 : 7.54 secs 231% (0 errors) knom1 : 13.41 secs 411% (0 errors) strat1 : 13.41 secs 411% (0 errors) ikegami1 : 13.50 secs 414% (0 errors) jamesnc1 : 14.86 secs 456% (0 errors) strat2 : 15.05 secs 462% (0 errors) tanktalus1 : 15.49 secs 475% (0 errors) ph713_1 : 20.21 secs 620% (0 errors) davido1 : 21.96 secs 674% (0 errors)