# [QUIZ SOLUTION] Euchre Hands (#55)

Discussion in 'Ruby' started by Robin Stocker, Nov 20, 2005.

1. ### Robin StockerGuest

Hi

This one seemed pretty easy, so I gave it a try.

My first idea was to solve the whole sorting in the <=> method of the
Card class. But it was too confusing this way, because I had to include
all possible comparisons. Also the Card itself had to know what the
trump suit was.

Then I tried a different approach. I wrote a Card#weighting method which
returned a number, for trump jack a 41, for trump color jack a 40, and
so on. Then i sorted the card array with sort_by and the weighting. But
I wasn't satisfied yet, because again, the card had to know what suit
was trump. And the numbering was ugly, too.

So my final idea was to just implement the <=> method for sorting
without regard to trump. Then in my Hand class, which knows about the
trump, I wrote a sort! method for the sorting with regard to trump suit.

Now I'm interested to see other solutions

Robin Stocker

module Euchre

class Hand
attr_accessor :cards

def initialize( trump )
@cards = []
@trump = Card.new( trump )
end

def <<( card )
@cards << card
end

def sort!
@cards =
# First the trump jack..
@cards.select{ |c| trump_suit?(c) and c.jack? } |
# then the jack of the trump color..
@cards.select{ |c| trump_color?(c) and c.jack? } |
# then all the trump cards..
@cards.select{ |c| trump_suit?(c) }.sort.reverse |
# then a different color, so the colors alternate..
@cards.select{ |c| !trump_color?(c) and
c.suit =~ /d|c/ }.sort.reverse |
# then the cards with the same color as the trump..
@cards.select{ |c| trump_color?(c) }.sort.reverse |
# and finally the rest.
@cards.sort.reverse
end

def trump_suit?( card ) card.suit == @trump.suit end
def trump_color?( card ) card.color == @trump.color end

def to_s
@cards.join("\n")
end
end

class Card
attr_accessor :suit, :face

Suits = ['d', 'h', 'c', 's']
Faces = ['9', 'T', 'J', 'K', 'A']
Colors = {'d' => :red, 'h' => :red, 'c' => :black, 's' => :black}

def initialize( suit, face=nil )
@suit = suit.downcase
@face = face.upcase if face
end

def jack?() @face == 'J' end
def color() Colors[@suit] end

# Sort first by suit and then by face.
def <=>( other )
rel = Suits.index(@suit) - Suits.index(other.suit)
rel = Faces.index(@face) - Faces.index(other.face) if rel == 0
rel
end

def to_s
@face + @suit
end
end

end

if __FILE__ == \$0

trump = lines.shift.slice(/\w+/)
hand = Euchre::Hand.new(trump[0,1])

lines.join.scan(/(\w)(\w)/) do |face, suit|
hand << Euchre::Card.new(suit, face)
end

hand.sort!
puts trump
puts hand
end

Robin Stocker, Nov 20, 2005

2. ### Edward FaulknerGuest

--TB36FDmn/VVEgNH/
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Here's my minimalist solution: 20 lines. I believe it always gets
both rank and color-alternation correct. If you only want to get
alternation correct *most* of the time, you can cut out another five
lines.

SUITS =3D %w{d c h s}.map {|s| s[0]}
CARDS =3D %w{A K Q J T 9}.map {|c| c[0]}

puts trump
trump =3D SUITS.index(trump.downcase[0])

# If the suit after the trump suit is missing, we swap it with the
# other suit of the same color. This ensures that we always have a
# correct color alternation when possible.
unless hand.find {|card| card[1] =3D=3D SUITS[(trump+1)%4]}
tmp =3D SUITS[(trump+1)%4]
SUITS[(trump+1)%4] =3D SUITS[(trump+3)%4]
SUITS[(trump+3)%4] =3D tmp
end

hand.map { |card|=20
suit =3D (SUITS.index(card[1]) - trump)%4
num =3D CARDS.index(card[0])
if num=3D=3D3 && suit=3D=3D2
suit,num =3D 0,-1 # Left bower
elsif num=3D=3D3 && suit=3D=3D0
num =3D -2 # Right bower
end
[suit,num,card.chomp]
}.sort.each{|c| puts "#{c[2]}\n" }

--TB36FDmn/VVEgNH/
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQFDgJmYnhUz11p9MSARAt1cAKC8/V15WvvXCnxPxtmkvOPHLS9KRwCbBu4G
9+kkX5s6DVtZP4uGzXHKX5g=
=EaVm
-----END PGP SIGNATURE-----

--TB36FDmn/VVEgNH/--

Edward Faulkner, Nov 20, 2005

3. ### Ryan LeavengoodGuest

I made two solutions, both of which use the same basic algorithm of
applying weights (where smaller is better) to the cards and then
sorting by weight. The comments in the first "normal" version should
explain things.

The second version is my highly golfed version which I think is about
as small as my algorithm can get. It is 242 bytes. I would be very
interested to see if anyone can go smaller, either by tweaking mine
more, or more likely, by golfing another algorithm. Obviously the
golfed code has zero error handling, so it will probably choke on any

Normal code:

class String
def to_suit
self[0..0].downcase
end
end

class EuchreSort
# These represent preferred sorting order
SUITS =3D %w{Diamonds Clubs Hearts Spades} # Alphabetical, then by color
CARDS =3D %w{A K Q J T 9} # Highest to lowest

def initialize(trump)
@trump =3D trump
trump_index =3D SUITS.index(trump)
raise "Invalid trump suit: #{trump}" unless trump_index
@right_bower =3D "J#{trump.to_suit}"
# The ordering used in SUITS ensures this works
@left_bower =3D "J#{SUITS[(trump_index+2)%4].to_suit}"
# Apply weights to suits starting from the trump, wrapping
# around as needed
@suit_weights =3D {}
weight =3D 10
trump_index.upto(trump_index+3) do |i|
@suit_weights[SUITS[i%4].to_suit] =3D weight
weight +=3D 10
end
end

def sort(hand)
weights =3D {}
hand.each do |card|
raise "Invalid card: #{card}" if card !~ /\A[#{CARDS.join}]{1}[dchs]{=
1}\z/
weights[card] =3D
case card
when @right_bower: 0
when @left_bower: 1
else
@suit_weights[card[1..1]] + CARDS.index(card[0..0])
end
end
hand.sort_by {|c| weights[c]}
end
end

if \$0 =3D=3D __FILE__
hand =3D STDIN.collect {|i|i.chomp}
trump =3D hand.shift
es =3D EuchreSort.new(trump)
puts trump
puts es.sort(hand)
end

Golfed code (I'm not sure how Gmail will wrap this, but it should be
all on one line):

s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[(i+2)%4]=
;w=3D[1];i.upto(i+3){|j|w<<s[j%4]};m=3D{};a.each{|k|m[k]=3Dk=3D~/(J#{u})|(J=
#{v})/?\$1?0:1:w.index(k[1..1])*10+c.index(k[0..0])};puts
t,a.sort_by{|k|m[k]}

Ryan

Ryan Leavengood, Nov 20, 2005
4. ### James Edward Gray IIGuest

On Nov 20, 2005, at 8:53 AM, Robin Stocker wrote:

> Hi
>
> This one seemed pretty easy, so I gave it a try.

Just FYI, this solution seems to have trouble with certain inputs:

Neo:~/Documents/Ruby/Ruby Quiz\$ ruby solutions/euchre_hand.rb >
test_hand.txt
Neo:~/Documents/Ruby/Ruby Quiz\$ ruby solutions/Robin\ Stocker/
euchre_hands.rb test_hand.txt
solutions/Robin Stocker/euchre_hands.rb:58:in `-': nil can't be
coerced into Fixnum (TypeError)
from solutions/Robin Stocker/euchre_hands.rb:58:in `<=>'
from solutions/Robin Stocker/euchre_hands.rb:27:in `sort'
from solutions/Robin Stocker/euchre_hands.rb:27:in `sort!'
from solutions/Robin Stocker/euchre_hands.rb:80
Neo:~/Documents/Ruby/Ruby Quiz\$ cat test_hand.txt
hearts
9s
9d
Kd
Ah
Qd

That's really not meant as a complaint. I appreciate you sharing
your solution. It works more often than not and always seems to
produce correct answers when it does. I just thought you might like
to know.

James Edward Gray II

James Edward Gray II, Nov 20, 2005
5. ### James Edward Gray IIGuest

On Nov 20, 2005, at 9:15 AM, Christian Neukirchen wrote:

> =begin
> Robin Stocker <> writes:
>
>> Now I'm interested to see other solutions
>> Robin Stocker

>
> This is mine, I didn't bother putting it into a class.

Hmm, is this correct:

Neo:~/Documents/Ruby/Ruby Quiz\$ ruby solutions/euchre_hand.rb >
test_hand.txtNeo:~/Documents/Ruby/Ruby Quiz\$ ruby solutions/Christian
\ Neukirchen/euchre_hands.rb test_hand.txt
Qh
9h
Qd
9d
Qc
Neo:~/Documents/Ruby/Ruby Quiz\$ cat test_hand.txt
hearts
Qd
9h
9d
Qc
Qh

hearts
Qh
9h
Qc
Qd
9d

Which doesn't put two red suits together. Getting back to the
question of the quiz, how do we know when we're right?

James Edward Gray II

James Edward Gray II, Nov 20, 2005
6. ### Robin StockerGuest

James Edward Gray II wrote:
> Just FYI, this solution seems to have trouble with certain inputs:

Ah, thank you... I just noticed that I forgot the queen in my Faces array

I also updated the script to get the alternating colors right.

Thanks for finding this (stupid) error.

Robin Stocker

module Euchre

class Hand
attr_accessor :cards

def initialize( trump )
@cards = []
@trump = Card.new( trump )
end

def <<( card )
@cards << card
end

def sort!
second_suit = @cards.find{ |c| !trump_color?(c) }.suit
@cards =
# First the trump jack..
@cards.select{ |c| trump_suit?(c) and c.jack? } |
# then the jack of the trump color..
@cards.select{ |c| trump_color?(c) and c.jack? } |
# then all the trump cards..
@cards.select{ |c| trump_suit?(c) }.sort.reverse |
# then a different color, so the colors alternate..
@cards.select{ |c| c.suit == second_suit }.sort.reverse |
# then the cards with the same color as the trump..
@cards.select{ |c| trump_color?(c) }.sort.reverse |
# and finally the rest.
@cards.sort.reverse
end

def trump_suit?( card ) card.suit == @trump.suit end
def trump_color?( card ) card.color == @trump.color end

def to_s
@cards.join("\n")
end
end

class Card
attr_accessor :suit, :face

Suits = ['d', 'h', 'c', 's']
Faces = ['9', 'T', 'Q', 'J', 'K', 'A']
Colors = {'d' => :red, 'h' => :red, 'c' => :black, 's' => :black}

def initialize( suit, face=nil )
@suit = suit.downcase
@face = face.upcase if face
end

def jack?() @face == 'J' end
def color() Colors[@suit] end

# Sort first by suit and then by face.
def <=>( other )
rel = Suits.index(@suit) - Suits.index(other.suit)
rel = Faces.index(@face) - Faces.index(other.face) if rel == 0
rel
end

def to_s
@face + @suit
end
end

end

if __FILE__ == \$0

trump = lines.shift.slice(/\w+/)
hand = Euchre::Hand.new(trump[0,1])

lines.join.scan(/(\w)(\w)/) do |face, suit|
hand << Euchre::Card.new(suit, face)
end

hand.sort!
puts trump
puts hand
end

Robin Stocker, Nov 20, 2005
7. ### Dale MartensonGuest

Re: Euchre Hands (#55)

I used to play euchre a lot in college so this was fun. It might be fun
writing an entire euchre game.

What I did was first think about the best test to prove my solution. If
you have a completely shuffled euchre deck for a specfic trump, the
entire deck would take on a known order. So I wrote four tests:

require 'test/unit'
require 'euchre'

HEARTS_AS_TRUMP_DECK = [
'Jh','Jd','Ah','Kh','Qh','Th','9h',
'As','Ks','Qs','Js','Ts','9s',
'Ac','Kc','Qc','Jc','Tc','9c'
]

'Js','Jc','As','Ks','Qs','Ts','9s',
'Ac','Kc','Qc','Tc','9c',
'Ah','Kh','Qh','Jh','Th','9h'
]

DIAMONDS_AS_TRUMP_DECK = [
'Ac','Kc','Qc','Jc','Tc','9c',
'Ah','Kh','Qh','Th','9h',
'As','Ks','Qs','Js','Ts','9s',
]

CLUBS_AS_TRUMP_DECK = [
'Jc','Js','Ac','Kc','Qc','Tc','9c',
'Ah','Kh','Qh','Jh','Th','9h',
'As','Ks','Qs','Ts','9s',
]

class TestEuchre < Test::Unit::TestCase
def setup
@ed = EuchreDeck.new
@eh = EuchreHand.new
@ed.shuffle
while( card = @ed.deal )
end
end

def test_hearts_as_trump
@eh.trump = "Hearts"
assert_equal( HEARTS_AS_TRUMP_DECK, @eh.hand )
end

end

def test_diamonds_as_trump
@eh.trump = "Diamonds"
assert_equal( DIAMONDS_AS_TRUMP_DECK, @eh.hand )
end

def test_clubs_as_trump
@eh.trump = "Clubs"
assert_equal( CLUBS_AS_TRUMP_DECK, @eh.hand )
end
end

I took the original input program and created a EuchreDeck class:

class EuchreDeck
def initialize
# build a Euchre deck
@cards = Array.new
%w{9 T J Q K A}.each do |face|
%w{d c s h}.each do |suit|
@cards << face + suit
end
end
end

def shuffle
@cards = @cards.sort_by { rand }
end

def deal
@cards.shift
end
end

I wrote a EuchreHand class that would take cards dealt to it and
originize them by a computed card value using sort.

class EuchreHand
Suit = Struct.new( :suit, :alternate_suit_1, ff_suit,
:alternate_suit_2 )

@@suits = {
"Diamonds"=>Suit.new("d","c","h","s"),
"Clubs"=>Suit.new("c","h","s","d"),
"Hearts"=>Suit.new("h","s","d","c")
}

@@face_values_trump = {
"J" => 6,
"A" => 4,
"K" => 3,
"Q" => 2,
"T" => 1,
"9" => 0
}

@@face_values_regular = {
"A" => 5,
"K" => 4,
"Q" => 3,
"J" => 2,
"T" => 1,
"9" => 0
}

MAX_CARDS_PER_SUIT = 7

def initialize
@trump = nil
@hand = []
end

def left_brower?( card )
card == "J#{@trump.off_suit}"
end

def trump?( card )
card[1].chr == @trump.suit
end

def trump=( suit_string )
@trump = @@suits[ suit_string ]
end

def trump
@@suits.index(@trump)
end

@hand.push( card )
end

def card_value( card )
face = card[0].chr
suit = card[1].chr

if left_brower?(card) then
suit_value = @trump.to_a.reverse.index( @trump.suit ) *
MAX_CARDS_PER_SUIT
face_value = @@face_values_trump[ face ] - 1
elsif trump?(card) then
suit_value = @trump.to_a.reverse.index( @trump.suit ) *
MAX_CARDS_PER_SUIT
face_value = @@face_values_trump[ face ]
else
suit_value = @trump.to_a.reverse.index( suit ) *
MAX_CARDS_PER_SUIT
face_value = @@face_values_regular[ face ]
end

suit_value + face_value
end

def hand
@hand.sort {|x,y| card_value(y)<=>card_value(x) }
end
end

Once my tests passed, I rewrote the original input program as:

require 'euchre'

# choose trump

ed = EuchreDeck.new
ed.shuffle
5.times{ puts ed.deal }

And the sort program as:

require 'euchre'

eh = EuchreHand.new

eh.trump = gets.strip

while card = gets
end

puts eh.trump
puts eh.hand

It would be a fun to attempt to create a EuchreBot to actually play.

--Dale

Dale Martenson, Nov 20, 2005
8. ### James Edward Gray IIGuest

Re: Euchre Hands (#55)

On Nov 20, 2005, at 3:07 PM, Dale Martenson wrote:

> I used to play euchre a lot in college so this was fun. It might be
> fun
> writing an entire euchre game.

[snip]

> It would be a fun to attempt to create a EuchreBot to actually play.

I agree. Maybe if you and I got a server together, building AI
players would make a good quiz for it? Drop me and email if this
interests you...

James Edward Gray II

P.S. Nice proof of your solution!

James Edward Gray II, Nov 21, 2005
9. ### Dominik BathonGuest

Here is my solution.

It also sorts the the cards by a score computed depending on the trump =20
suit, lower is better.

Dominik

The code:

class EuchreCard

SUIT_COLOR =3D {
:diamonds =3D> :red,
:hearts =3D> :red,
:clubs =3D> :black,
}
SUIT_ORDER =3D [:diamonds, :clubs, :hearts, :spades]
RANK_ORDER =3D [:nine, :ten, :jack, :queen, :king, :ace]

def initialize(str)
str =3D str.to_s.downcase
@rank =3D
if str[0] =3D=3D ?9
:nine
else
RANK_ORDER.find { |rank| rank.to_s[0] =3D=3D str[0] }
end
@suit =3D SUIT_ORDER.find { |suit| suit.to_s[0] =3D=3D str[1] }
raise "unknown card rank" unless rank
raise "unknown card suit" unless suit
end

def to_s
unless rank =3D=3D :nine
rank.to_s[0, 1].upcase
else
"9"
end + suit.to_s[0, 1]
end

def sort_score(trump)
if rank =3D=3D :jack && suit =3D=3D trump
0
elsif rank =3D=3D :jack && SUIT_COLOR[suit] =3D=3D SUIT_COLOR[tr=
ump]
1
else
ti =3D SUIT_ORDER.index(trump)
raise "unknown trump suit: #{trump}" unless ti
suit_score =3D (SUIT_ORDER.index(suit) - ti) % 4
10 + suit_score * 10 - RANK_ORDER.index(rank)
end
end
end

if \$0 =3D=3D __FILE__
trump =3D gets.strip.downcase.to_sym
unless EuchreCard::SUIT_COLOR.has_key? trump
warn "unknown trump suit: #{trump}"
exit 1
end
cards =3D readlines.map { |line| EuchreCard.new(line.strip) }
cards =3D cards.sort_by { |card| card.sort_score(trump) }
puts trump.to_s.capitalize, cards
end

Dominik Bathon, Nov 21, 2005
10. ### Dominik BathonGuest

Here is another solution to the problem. I got the idea for this while =20

It doesn't really "solve" the problem, instead it cheats ;-) , but on the=
=20
other side it is short and should be correct if the order hash is correct=

Dominik Bathon, Nov 21, 2005
11. ### Zed LopezGuest

Re: Euchre Hands (#55)

Terse, but almost reasonable version:

class Euchre
OTHER_COLOR =3D {'c' =3D> 's', 's' =3D> 'c', 'h' =3D> 'd', 'd' =3D> 'h'}
def initialize(suit_name)
@trump_suit =3D suit_name
@trump =3D @trump_suit[0,1].downcase
end
def <<(card)
(@hand ||=3D []) << card
end
def hand
suits =3D @hand.map {|card| card[1,1]}.uniq
i =3D suits.index(@trump) and suits.push(suits.slice!(i))
suits[-3],suits[-2] =3D suits[-2],suits[-3] if suits.length > 2 and
OTHER_COLOR[suits[-1]] =3D=3D suits[-2]
@hand.sort_by do |x|
rank, suit =3D x.split('')
if rank =3D=3D 'J' and @trump =3D=3D suit : 50
elsif rank =3D=3D 'J' and OTHER_COLOR[suit] =3D=3D @trump : 40
else '9TJQKA'.index(rank) + suits.index(suit)*10
end
end.reverse
end
end

euchre =3D Euchre.new(gets.strip)
5.times { euchre << gets.strip }
puts euchre.trump_suit, euchre.hand

Golfed, but weighing in a good 80 characters more than Ryan's (but,
hey, it's my first golf outing in Ruby.) Like his, it should be one
line.

a=3D[];6.times{a<<gets.strip};puts t=3Da.shift;o=3DHash[*%w{C S S C H D D
H}];t=3Dt[0,1];s=3Da.map{|c|c[1,1].upcase}.uniq;i=3Ds.index(t)and
s.push(s.slice!(i));s.length>2&&o[s[-1]]=3D=3Ds[-2]&&(s[-3],s[-2]=3Ds[-2],s=
[-3]);puts
a.sort_by{|c|r,z=3Dc.upcase.split('');r=3D=3D'J'&&t=3D=3Dz&&50||r=3D=3D'J'&=
&o[z]=3D=3Dt&&40||'9TJQKA'.index(r)+s.index(z)*9}.reverse

Zed Lopez, Nov 21, 2005
12. ### Zed LopezGuest

On 11/20/05, Dominik Bathon <> wrote:
> It doesn't really "solve" the problem, instead it cheats ;-) , but on the
> other side it is short and should be correct if the order hash is correct=

Zed Lopez, Nov 21, 2005
13. ### Dominik BathonGuest

On Mon, 21 Nov 2005 04:20:16 +0100, Zed Lopez <> wrote=
:

> On 11/20/05, Dominik Bathon <> wrote:
>> It doesn't really "solve" the problem, instead it cheats ;-) , but on =

=20
>> the
>> other side it is short and should be correct if the order hash is =20
>> correct.

>
> A couple of my early attempts depended on the idea that the trump suit
> absolutely determined the ranking of the cards, independent of knowing
> anything else. It doesn't work, though.

Indeed, I didn't realize that till now (even though James wrote a similar=
=20

So my first solution is "wrong", too. I will post new versions.

Thanks,
Dominik

Dominik Bathon, Nov 21, 2005
14. ### Ryan LeavengoodGuest

Thanks to inspiration from reading Zed Lopez's code, I've been able to
cut my golfed solution from 242 bytes to 214. Unfortunately for you
Zed, this now means your is now 108 bytes longer

The fixes were:

1. Using s[x,1] instead of s[x..x] to get a single character from a
string. This saved 2 bytes.
2. Calculating the weights INSIDE the sort_by, instead of using a
separate hash. This seems so obvious now I slapped my head when I saw
Zed's code doing this. This saved a whopping 26 bytes.

So, if anyone is interested:

s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[(i+2)%4]=
;w=3D[1];i.upto(i+3){|j|w<<s[j%4]};puts
t,a.sort_by{|k|k=3D~/(J#{u})|(J#{v})/?\$1?0:1:w.index(k[1,1])*10+c.index(k[0=
,1])}

I will be highly impressed if someone can go shorter than this. Also
if anyone wants it I can post a message "decoding" the above.

Ryan

Ryan Leavengood, Nov 21, 2005
15. ### David BalmainGuest

Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
save you a couple more characters.

On 11/21/05, Ryan Leavengood <> wrote:
> Thanks to inspiration from reading Zed Lopez's code, I've been able to
> cut my golfed solution from 242 bytes to 214. Unfortunately for you
> Zed, this now means your is now 108 bytes longer
>
> The fixes were:
>
> 1. Using s[x,1] instead of s[x..x] to get a single character from a
> string. This saved 2 bytes.
> 2. Calculating the weights INSIDE the sort_by, instead of using a
> separate hash. This seems so obvious now I slapped my head when I saw
> Zed's code doing this. This saved a whopping 26 bytes.
>
> So, if anyone is interested:
>
> s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[(i+2)%=

4];w=3D[1];i.upto(i+3){|j|w<<s[j%4]};puts
> t,a.sort_by{|k|k=3D~/(J#{u})|(J#{v})/?\$1?0:1:w.index(k[1,1])*10+c.index(k=

[0,1])}
>
> I will be highly impressed if someone can go shorter than this. Also
> if anyone wants it I can post a message "decoding" the above.
>
> Ryan
>
>

David Balmain, Nov 21, 2005
16. ### David BalmainGuest

Here's my terribly hacky version of Ryans;

s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[i-2];w=
=3D[1];4.times{|j|w<<s[j-i]};puts
t,a.sort_by{|k|k=3D~/J[#{u}#{v}]/?\$1?0:1:w.index(k[1,1])*10+c.index(k[0,1])=
}

On 11/21/05, David Balmain <> wrote:
> Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
> save you a couple more characters.
>
> On 11/21/05, Ryan Leavengood <> wrote:
> > Thanks to inspiration from reading Zed Lopez's code, I've been able to
> > cut my golfed solution from 242 bytes to 214. Unfortunately for you
> > Zed, this now means your is now 108 bytes longer
> >
> > The fixes were:
> >
> > 1. Using s[x,1] instead of s[x..x] to get a single character from a
> > string. This saved 2 bytes.
> > 2. Calculating the weights INSIDE the sort_by, instead of using a
> > separate hash. This seems so obvious now I slapped my head when I saw
> > Zed's code doing this. This saved a whopping 26 bytes.
> >
> > So, if anyone is interested:
> >
> > s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[(i+2=

)%4];w=3D[1];i.upto(i+3){|j|w<<s[j%4]};puts
> > t,a.sort_by{|k|k=3D~/(J#{u})|(J#{v})/?\$1?0:1:w.index(k[1,1])*10+c.index=

(k[0,1])}
> >
> > I will be highly impressed if someone can go shorter than this. Also
> > if anyone wants it I can post a message "decoding" the above.
> >
> > Ryan
> >
> >

>
>

David Balmain, Nov 21, 2005
17. ### David BalmainGuest

On 11/21/05, David Balmain <> wrote:
> Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
> save you a couple more characters.
>

Damn, now I can see why you did it that way. Sorry. Please disregard.

> On 11/21/05, Ryan Leavengood <> wrote:
> > Thanks to inspiration from reading Zed Lopez's code, I've been able to
> > cut my golfed solution from 242 bytes to 214. Unfortunately for you
> > Zed, this now means your is now 108 bytes longer
> >
> > The fixes were:
> >
> > 1. Using s[x,1] instead of s[x..x] to get a single character from a
> > string. This saved 2 bytes.
> > 2. Calculating the weights INSIDE the sort_by, instead of using a
> > separate hash. This seems so obvious now I slapped my head when I saw
> > Zed's code doing this. This saved a whopping 26 bytes.
> >
> > So, if anyone is interested:
> >
> > s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[(i+2=

)%4];w=3D[1];i.upto(i+3){|j|w<<s[j%4]};puts
> > t,a.sort_by{|k|k=3D~/(J#{u})|(J#{v})/?\$1?0:1:w.index(k[1,1])*10+c.index=

(k[0,1])}
> >
> > I will be highly impressed if someone can go shorter than this. Also
> > if anyone wants it I can post a message "decoding" the above.
> >
> > Ryan
> >
> >

>

David Balmain, Nov 21, 2005
18. ### Pit CapitainGuest

David Balmain schrieb:
> On 11/21/05, David Balmain <> wrote:
>>Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
>>save you a couple more characters.

>
> Damn, now I can see why you did it that way. Sorry. Please disregard.

No, your idea is right: he could still save one character using
/J(#{u})|(#{v})/

Regards,
Pit

Pit Capitain, Nov 21, 2005

------=_Part_32527_30812562.1132555782725
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Here's mine. I believe it always handles red-black ordering correctly even
with empty suits.

class EuchreHand
SUIT =3D [?c,?d,?s,?h]
VAL =3D [?A,?Q,?K,?J,?T,?9]
def initialize input
@trump =3D input.shift
@hand =3D {}
4.times {|s| @hand[SUIT]=3D[]}
input.each{|card| @hand[card[1]] << card[0] }
end
def display
puts @trump
t=3DSUIT.index(@trump.downcase[0])
get_jacks(SUIT[t])
get_jacks(SUIT[(t+2)%4])
if @hand[SUIT[(t+1)%4]].empty?
t.downto(0){|s| show_suit s}
(3).downto(t+1) {|s| show_suit s}
else
(t..3).each {|s| show_suit s}
(0...t).each {|s| show_suit s}
end
end
def get_jacks suit
if @hand[suit].include? ?J
puts [?J,suit].pack('c*')
@hand[suit].delete(?J)
end
end
def show_suit s
suit =3D SUIT
@hand[suit].sort{|a,b| VAL.index(a)<=3D>VAL.index(b)}.each{|v|
puts [v,suit].pack('c*')
}
end
end

if __FILE__ =3D=3D \$0
e =3D EuchreHand.new(input)
e.display
end

----

------=_Part_32527_30812562.1132555782725--

20. ### David BalmainGuest

On 11/21/05, Pit Capitain <> wrote:
> David Balmain schrieb:
> > On 11/21/05, David Balmain <> wrote:
> >>Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
> >>save you a couple more characters.

> >
> > Damn, now I can see why you did it that way. Sorry. Please disregard.

>
> No, your idea is right: he could still save one character using
> /J(#{u})|(#{v})/
>
> Regards,
> Pit

This is the last time I play golf. It's addictive and I should be working.