Euchre Hands (#55)

On 11/21/05, Pit C. [email protected] wrote:

Regards,
Pit

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

a=$<.read.split(“\n”);s=%w{d c h
s};c=‘AKQJT9’;t=a.shift;u=(t[0]+32).chr;i=s.index(u);v=s[i-2];w=[1];puts
t,a.sort_by{|k|(k=~/J[#{u+v}]/?0:99)+(s.index(k[1,1])-i)%4*10+c.index(k[0,1])}

184 characters. And this time I think it works.

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

class EuchreHand
SUIT = [?c,?d,?s,?h]
VAL = [?A,?Q,?K,?J,?T,?9]
def initialize input
@trump = input.shift
@hand = {}
4.times {|s| @hand[SUIT[s]]=[]}
input.each{|card| @hand[card[1]] << card[0] }
end
def display
puts @trump
t=SUIT.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 = SUIT[s]
@hand[suit].sort{|a,b| VAL.index(a)<=>VAL.index(b)}.each{|v|
puts [v,suit].pack(‘c*’)
}
end
end

if FILE == $0
input =readlines
e = EuchreHand.new(input)
e.display
end


-Adam

OOPS! I was just looking at ways I could golf my solution and I realized
I
had a big bug:
replace
VAL = [?A,?Q,?K,?J,?T,?9]
with
VAL = [?A,?K,?Q,?J,?T,?9]

Doh!

Got to get back to work. 166 chars;
a=$<.readlines;s=‘dchs’;c=‘AKQJT9’;t=a.shift;u=(t[0]+32).chr;i=s.index(u);v=s[i-2].chr;puts
t,a.sort_by{|k|(k=~/J[#{u+v}]/?0:50)+(s.index(k[1])-i)%4*10+c.index(k[0])}

On 11/21/05, David B. [email protected] wrote:

Got to get back to work. 166 chars;
a=$<.readlines;s=‘dchs’;c=‘AKQJT9’;t=a.shift;u=(t[0]+32).chr;i=s.index(u);v=s[i-2].chr;puts
t,a.sort_by{|k|(k=~/J[#{u+v}]/?0:50)+(s.index(k[1])-i)%4*10+c.index(k[0])}

Brilliant. I’m extremely impressed. I learned quite a bit from it too,
which is one of the reasons I like code golfing so much. Plus it is
fun and rather addictive, as you have learned.

For those wondering, here is what I learned from David’s changes to my
code:

  1. The extra newlines don’t need to be cleaned out from the input
    since “puts” seems to ignore them.
  2. For compactness it is better to use strings rather than %w{} arrays.
  3. Ruby’s array and string indexing already takes care of
    “wrap-around” when indexing since negative indexes work. So given a
    string s of length 4, s[(i+2)%4] and s[i-2] are equivalent for values
    of i from 0 to 5.
  4. You can get the index of either a string or a fixnum representing a
    character using String#index.
  5. Using % on a negative number yields a positive number, which is
    cleverly used above in calculating the weight. My math is rusty I
    guess, or in fact, I’m not sure I ever learned what performing modulus
    on a negative number is supposed to return. But I Googled it and
    learned now.

But there is a problem in my code (both the above and the longer
version) which I just noticed (and that Zed brought up earlier): if a
suit is missing in certain cases the suits are not interlaced
properly. I’m wondering if I will bother going back to the drawing
board or not :slight_smile:

Ryan

Here is a corrected version, that hopefully gets the color alternation
right.

Dominik

order = {
“Spades” => “JsJcAsKsQsTs9sAdKdQdJdTd9dAcKcQcTc9cAhKhQhJhTh9h”,
“Hearts” => “JhJdAhKhQhTh9hAsKsQsJsTs9sAdKdQdTd9dAcKcQcJcTc9c”,
“Clubs” => “JcJsAcKcQcTc9cAhKhQhJhTh9hAsKsQsTs9sAdKdQdJdTd9d”,
“Diamonds” => “JdJhAdKdQdTd9dAcKcQcJcTc9cAhKhQhTh9hAsKsQsJsTs9s”
}

trump = gets.strip
cards = readlines.map { |l| l.strip }
o = order[trump].dup

do we have a card of the 2nd suit

unless cards.any? { |card| card[1] == o[15] }
# if not replace second suit by the last
o[14, 12] = o[36, 12]
end
puts trump, cards.sort_by { |card| o.index(card) }

Here is mine. Some parts shamefully stolen from above (input using
…split and using negative array indexes to get the complement suit)

class Hand
attr :cards
SUITS = %w{s h c d} # should be ordered by alternating colors
RANKS = %w{9 T J Q K A} # must be ordered low to high

def initialize(cards, trump)
	@trump_c = trump[0,1].downcase
	@complement = SUITS[SUITS.index(@trump_c) - 2]
	first_off_suit = SUITS.find{|suit|

![@trump_c,@complement].include?(suit) &&
cards.find{|card|card[1,1]==suit}}
@suit_values = {@trump_c => 100, first_off_suit => 50, @complement =>
25}
@cards = cards.sort_by{|card| get_val(card) * -1}.unshift(trump)
end

private

def get_val(card)
	val = RANKS.index(card[0,1]) + (@suit_values[card[1,1]] ||= 0)
	return ["J#{@trump_c}", "J#{@complement}"].include?(card) ? val+500 :

val
end
end

cards = STDIN.read.split
puts Hand.new(cards, cards.shift).cards

On 11/22/05, Bob S. [email protected] wrote:

second and fourth suits if the hand was void in the second suit. Given
that adjustment, any combination of suits in the hand should yield
properly alternating colors.

I did it kind of bottom-up to your approach’s top-down – starting
with array of the suits present in the hand, in arbitrary order, I
moved the trump suit to the front. Then, if there were three or more
suits, if the second suit was the same color as the trump suit, I
swapped the second and third suits.

Zed L. wrote:

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.

Ordering the hand can’t come without considering what suits are present.

I addressed this by generating a suit order in alternating colors
starting with the trump suit. Then some hand checking of the various
possibilities showed me that the only adjustment needed was to swap the
second and fourth suits if the hand was void in the second suit. Given
that adjustment, any combination of suits in the hand should yield
properly alternating colors.