http://qs1969.pair.com?node_id=222641

This came up in a real life problem I had, and I thought it might make an interesting challenge. The idea is simple, you have an array (sorted) containing n unique real numbers (call it @z). You also have two additional real values (call them $x, and $y). The challenge is to determine if $x and $y both either:

When determining "betweeness", treat any cases where $x or $y equals a value in @z as if $x or $y was actually less than that value.

Examples

  @z = ( 1, 3, 27, 38 );

  $x=4;  $y=5;   # Works
  $x=0;  $y=-1;  # Works
  $x=100;  $y=100;  # Works
  $x=10;  $y=27;  # Works
  $x=3;  $y=27; #Fails

So you start out with code like this:

use strict; my $x = shift(); my $y = shift(); my @z = @_; print "YES!\n" if (...);

And the challenge is to replace '...' with as few characters (whitespace counts) as possible while satisfactorially solving the problem.

I've gotten it down to 32 chars. Who's going to beat me first?

updated: You need to use strict.

Replies are listed 'Best First'.
Re: Golf Challenge - does $x and $y fit into the same slot on @z?
by Aristotle (Chancellor) on Dec 27, 2002 at 23:26 UTC
    30
    use strict; use Test::More q(no_plan); my @z = qw(1 3 27 38); my $x = shift(); my $y = shift(); my @test = ( [qw( 4 5) => 1], [qw( 0 -1) => 1], [qw(100 100) => 1], [qw( 10 27) => 1], [qw( 3 27) => 0], [qw( 0 100) => 0], ); sub bool { not not shift } for(@test) { my ($x, $y, $works) = @$_; is( # 1 2 3 #23456789012345678901234567890 ((grep$x<=$_,@z)==grep$y<=$_,@z), bool($works), "x=$x y=$y" ); } __END__ ok 1 - x=4 y=5 ok 2 - x=0 y=-1 ok 3 - x=100 y=100 ok 4 - x=10 y=27 ok 5 - x=3 y=27 ok 6 - x=0 y=100 1..6

    Makeshifts last the longest.

      Wow. You came up with the exact same thing as I did, except for two little syntax differences. This is what I had. If I had knon that I didn't need the curly's on the grep, and if you reversed the order in your evaluations, they would be the same.

      use strict; my $x = 4; my $y = 38; my @z = ( 1, 3, 38, 83 ); print "Yes\n" if ((grep{$_<$x}@z)==(grep{$_<$y}@z));
Re: Golf Challenge - does $x and $y fit into the same slot on @z?
by BrowserUk (Patriarch) on Dec 28, 2002 at 00:38 UTC

    25

    #! perl -slw use strict; my @z = ( 1, 3, 27, 38 ); while( my ($x,$y) = split/,/,<DATA> ) { # 1 2 # 1234567890123456789012345 print "YES!\n" if @z==grep$x<=$_==$y<=$_,@z; } __END__ 4, 5 0, -1 100, 100 10, 27 3, 27

    Examine what is said, not who speaks.

      23

      #! perl -slw use strict; my @z = ( 1, 3, 27, 38 ); while( my ($x,$y) = split/,/,<DATA> ) { # 1 2 # 1234567890123456789012345 print "YES!\n" if @z==grep$x>$_==$y>$_,@z; } __END__ 4, 5 0, -1 100, 100 10, 27 3, 27 3, 3
      Okay, this is not exactly fair on my part, credit goes to BrowserUK.

      -gjb-

        It's fair enough. Once you pick an approach, golf is all about wiggling tokens to get a few more characters left out.

        Makeshifts last the longest.

        20
        #! perl -slw use strict; my @z = ( 1, 3, 27, 38 ); while( my ($x,$y) = split/,/,<DATA> ) { # 1 2 # 12345678901234567890 print "YES!\n" if !grep$x>$_!=$y>$_,@z; } __END__ 4, 5 0, -1 100, 100 10, 27 3, 27 3, 3
Re: Golf Challenge - does $x and $y fit into the same slot on @z?
by sauoq (Abbot) on Dec 28, 2002 at 01:39 UTC

    I hate to spoil the party here but all of the solutions thus far fail on one or more boundary condition.

    I suggest adding two test cases:

    $x = 1; $y = 2; @z = (0, 1);
    and
    $x = 0; $y = -1; @z = (0, 1);

    It is possible that the specification was poorly written but, as it is stated, there is no mention of cases where $x and/or $y are equal to a number in the array. It stands to reason that the safe assumption is that such condition should be considered a failure condition. At the very least, it should be handled consistently. All of the current solutions handle it differently depending on which end of the array the equality occurs at.

    Take, for example, the first test I proposed above: $x = 1; $y = 2; @z = (0, 1);. In that case, it obviously not true that $x and $y are between the same numbers in @z. It is also not true that they are both less than all the numbers in @z. Finally, since $x is equal to the last element in @z, it is not true that they are both greater than all elements in @z.

    -sauoq
    "My two cents aren't worth a dime.";
    
      I hate to spoil the party here but all of the solutions thus far fail on one or more boundary condition.
      Liar! Admit it, you thoroughly enjoyed that one. Don't you try to hide that smug look on your face from me. ;-)

      Makeshifts last the longest.

      Erm. Isn't that covered by the bit that says:

      #When determining "betweeness", treat any cases where $x or $y equals a value in @z as if $x or $y was actually less than that value.
      ?

      By my (probably flawed) reading of that, your first case would be a fail because the $x would be judged less than the second element of @z

      And the second case would be a pass as both $x and $y would be judges as being lower than the first valeue of @z


      Examine what is said, not who speaks.

        Erm. Isn't that covered by the bit that says

        Hrm. It's a debatable point, I suppose.

        It explicitly states that that should be the strategy when determining "betweeness" whereas the example test cases I gave were those dealing with "greater than" or "less than" all the numbers in the array. I'm wavering more toward the poorly stated specification option now, though.

        -sauoq
        "My two cents aren't worth a dime.";
        

        Yes, you are correct.