Re: Reductions, junctions, hashslices, and cribbage scoring

2005-05-26 Thread John Williams
On Wed, 25 May 2005, Rob Kinyon wrote:

 (This post references the discussion at
 http://www.perlmonks.org/?node_id=458728, particularly dragonchild's
 response at the bottom.)

 For those who don't know, cribbage is a game where each player has
 access to 4 cards, plus a community card. Various card combinations
 score points. The one in question is when cards add up to 15. If you
 have a group of cards that add up to 15, you receive 2 points. This is
 for every group, so if you have a ten and 2 fives, you get 4 points.
 Two tens and two fives is 8 points. Face cards are worth 10 and aces
 are 1, for these purposes.

 I proposed the following:

 # Fifteens
 $score += 2 * all( 15 == [EMAIL PROTECTED] any( 0 .. 4 ) } );

 * Is this syntax legal?

I think so.

 * Does it do what I want it to do?

Definitely not.  It looks like you are thinking of junctions in terms of
arrays, instead of scalar quantum superpositions.

   any( 0 .. 4 )

This returns a scalar junction of the five values (0,1,2,3,4).
What you want is clearly all possible subsets of 0..4.  You probably
should write a coroutine to generate a lazy list of them.

   @hand{ $junction }

returns a scalar junction of the five cards in the hand.  Junctions
auto-thread through operators, including postcircumfixes.

   [+] $junction

returns $junction, since [+] $scalar == $scalar.  The individual values
auto-thread through.

   15 == $junction

This returns a junction of booleans.  Knowing the possible values of
@hand, all of them are false.

   all( $junction )

I'm not real good with nested junctions...

   2 * $junction

This returns another junction, with all elements doubled.  (still zeros)
You obviously want 2 * junction.elems, but I'm not sure if junctions
support that method.

   $score += $junction

Again this will make $score a junction of values.  It will not add each of
the junction values to $score.  You probably want something like
C $score += $junction.values  but that is another indication
that you should be using arrays instead of junctions.  And I'm not sure
about the object interface to junctions anyway.

 * Is there another way?

Assuming you write the subset coroutine above, how about

  $score +=
  ( subsets(0..4) == map { 2 * (15 == [+] @[EMAIL PROTECTED]) } == [+] )


~ John Williams




Re: Reductions, junctions, hashslices, and cribbage scoring

2005-05-26 Thread Rob Kinyon
 Assuming you write the subset coroutine above, how about
 
   $score +=
   ( subsets(0..4) == map { 2 * (15 == [+] @[EMAIL PROTECTED]) } == [+] )

Working on it last night and this morning, I ended up with the
following, very similar rewrite.

sub gen_idx_powerset (Int $size is copy) returns Array {
   my @c = ([]);
   for 0 .. $size-1 - $i {
   push @c, (map { [EMAIL PROTECTED], $i] }, @c);
   }
   return @c;
}

# Fifteens
$score += 2 * grep {
   15 == [+]( @[EMAIL PROTECTED].val )
}, gen_idx_powerset( [EMAIL PROTECTED] );

(Also available at http://www.perlmonks.org/?node_id=460666)

(I had an error in my original posting. @hand is an AoH. My original
should have hypered to .val like my second one does.)

Question: Is it possible using hypers and the like to replace the
gen_idx_powerset() sub with an inline expression? I'm not worried
about maintainability - I wanna see what the new ops can do!

Thanks,
Rob