Luke Palmer wrote:
> 
> Wow, what an old thread...
> 
> Jonadab the Unsightly One writes:
> > "Abhijit A. Mahabal" <[EMAIL PROTECTED]> writes:
> >
> > > On the other hand, if you wanted to say "true for all except exactly
> > > one value, I can't think of a way.
> >
> > Easy.  The following two statements are equivalent:
> >
> > F(x) is true for all but exactly one x
> > (not F(x)) is true for exactly one x
> >
> > The only additional possibility that can't be phrased in terms of the
> > four given is the complex generalised case:
> >
> > F(x) is true for at least n but not more than m values of x
> 
> Oh, I wouldn't say that....
> 
>     use HypotheticalModules::List::Combinations 'combinations';
> 
>     sub between($low, $high, [EMAIL PROTECTED]) {
>         any(
>             $low..$high ==> map -> $num {
>                 any( map { all(@$_) } combinations($num, @values) )
>             }
>         )
>     }
> 
> Efficient?  No.  Blows out memory for (20, 30, 1..50)?  Yes.
> Works?  Yes.
> 
> We also have:
> 
>     class Betwunction is Junction {
>         submethod BUILD($.low, $.high, @.values) { }
>
>         method evaluate() {
>             my Int $n = grep { ? $_ } @.values;
>             $.low <= $n <= $.high;
>         }
>     }
>     sub between($low, $high, @values) {
>         new Betwunction: $low, $high, @values;
>     }
> 
> Or something.  But I guess this one breaks the constraint of "in terms
> of the four given".

Also, it tests more values for truth than it has to.

If there are fewer elements in the array than $.low, then obviously, we
should fail immediately.  Actually I should say, "elements remaining",
instead of just "elements", and should say "$.low - the number of true
elements so far" instead of "$.low".  In otherwords, this bit of short-
circuiting could be done on every iteration, so as to test fewer
elements of the array for truth, if we can.

If there are fewer elements in the array than $.high, then (assuming we
already know that there are at least $.low elements) we can succeed
immediately.  Likewise, this short-circuiting can be done on every
iteration.

   method evaluate() {
      my Iterator $i = Iterator.new($.values);
      my Int $need = $.low;
      while( $need > 0 ) {
         return false if $i < $need;
         --$need if ? $i.shift;
      }
      my Int $limit = $.high - $.low;
      while( $limit >= 0 ) {
         return true if $i < $limit;
         --$limit if ? $i.shift;
      }
      return false;
   }

This *should* do no more boolean tests on the elements of $.values than
absolutely necessary.

> > So for example you could have a list of fifty values for x and test
> > whether the condition is true for at least ten but not more than
> > fourty of them.  (Or, x could be the condition; you could have a list
> > of fifty conditions and test whether between twenty and thirty of them
> > were true.)  My guess is, however, that the frequency with which
> > anyone would use such a capability would not be overwhelming.
> >
> > It would be great for obfuscation, though, particularly if some of the
> > conditions had side effects with an impact on the value of the other
> > conditions to be tested...  That would be sufficiently interesting
> > that it's almost a shame I can't think of a real reason to request
> > such a feature, since I rather doubt anyone's going to much fancy
> > implementing it just for obfuscatory value ;-)
> 
> Who needs reasons?

It's at least as useful as the proposed "fortytwo" op for parrot. :)

-- 
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "[EMAIL PROTECTED]
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Reply via email to