[QUIZ SOLUTION] Euchre Hands (#55)

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

  1. 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
    lines = readlines

    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
    #1
    1. Advertising

  2. --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]}

    trump,hand =3D STDIN.readline, STDIN.readlines

    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
    #2
    1. Advertising

  3. 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
    bad input.

    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):

    a=3D$<.read.split("\n");s=3D%w{d c h
    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
    #3
  4. 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
    #4
  5. 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

    I would have answered:

    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
    #5
  6. 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
    lines = readlines

    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
    #6
  7. 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',
    'Ad','Kd','Qd','Td','9d',
    'Ac','Kc','Qc','Jc','Tc','9c'
    ]

    SPADES_AS_TRUMP_DECK = [
    'Js','Jc','As','Ks','Qs','Ts','9s',
    'Ad','Kd','Qd','Jd','Td','9d',
    'Ac','Kc','Qc','Tc','9c',
    'Ah','Kh','Qh','Jh','Th','9h'
    ]

    DIAMONDS_AS_TRUMP_DECK = [
    'Jd','Jh','Ad','Kd','Qd','Td','9d',
    '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',
    'Ad','Kd','Qd','Jd','Td','9d'
    ]

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

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

    def test_spades_as_trump
    @eh.trump = "Spades"
    assert_equal( SPADES_AS_TRUMP_DECK, @eh.hand )
    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, :eek:ff_suit,
    :alternate_suit_2 )

    @@suits = {
    "Diamonds"=>Suit.new("d","c","h","s"),
    "Clubs"=>Suit.new("c","h","s","d"),
    "Spades"=>Suit.new("s","d","c","h"),
    "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

    def add_card( card )
    @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
    puts %w{Diamonds Clubs Spades Hearts}[rand(4)]

    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
    eh.add_card( card.strip )
    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
    #7
  8. 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
    #8
  9. 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,
    :spades =3D> :black
    }
    SUIT_ORDER =3D [:diamonds, :clubs, :hearts, :spades]
    RANK_ORDER =3D [:nine, :ten, :jack, :queen, :king, :ace]

    attr_reader :rank, :suit

    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
    #9
  10. Here is another solution to the problem. I got the idea for this while =20
    reading Dale Martenson's solution.

    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
    #10
  11. Robin Stocker

    Zed Lopez Guest

    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'}
    attr_reader :trump_suit
    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
    #11
  12. Robin Stocker

    Zed Lopez Guest

    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
    #12
  13. 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
    reply to Christian's solution)...

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

    Thanks,
    Dominik
    Dominik Bathon, Nov 21, 2005
    #13
  14. 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:

    a=3D$<.read.split("\n");s=3D%w{d c h
    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
    #14
  15. Ryan, how about changing /(J#{u})|(J#{v})/ to /J[#{u}#{v}]/? That'll
    save you a couple more characters. :p

    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:
    >
    > a=3D$<.read.split("\n");s=3D%w{d c h
    > 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
    #15
  16. Here's my terribly hacky version of Ryans;

    a=3D$<.read.split("\n");s=3D%w{d c h
    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. :p
    >
    > 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:
    > >
    > > a=3D$<.read.split("\n");s=3D%w{d c h
    > > 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
  17. 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. :p
    >


    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:
    > >
    > > a=3D$<.read.split("\n");s=3D%w{d c h
    > > 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
  18. Robin Stocker

    Pit Capitain Guest

    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. :p

    >
    > 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
    #18
  19. Robin Stocker

    Adam Shelly Guest

    ------=_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
    input =3Dreadlines
    e =3D EuchreHand.new(input)
    e.display
    end

    ----
    -Adam

    ------=_Part_32527_30812562.1132555782725--
    Adam Shelly, Nov 21, 2005
    #19
  20. 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. :p

    > >
    > > 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.

    a=3D$<.read.split("\n");s=3D%w{d c h
    s};c=3D'AKQJT9';t=3Da.shift;u=3D(t[0]+32).chr;i=3Ds.index(u);v=3Ds[i-2];w=
    =3D[1];puts
    t,a.sort_by{|k|(k=3D~/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.
    David Balmain, Nov 21, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Tran
    Replies:
    9
    Views:
    184
    David Tran
    Jan 21, 2005
  2. Ruby Quiz

    [QUIZ] Euchre Hands (#55)

    Ruby Quiz, Nov 18, 2005, in forum: Ruby
    Replies:
    5
    Views:
    152
    Timothy Goddard
    Nov 21, 2005
  3. Daniel Sheppard

    [QUIZ SOLUTION] Euchre Hands (#55)

    Daniel Sheppard, Nov 21, 2005, in forum: Ruby
    Replies:
    0
    Views:
    101
    Daniel Sheppard
    Nov 21, 2005
  4. Warren Brown

    [SOLUTION] Euchre Hands (#55)

    Warren Brown, Nov 21, 2005, in forum: Ruby
    Replies:
    2
    Views:
    95
    James Edward Gray II
    Nov 23, 2005
  5. Ruby Quiz

    [SUMMARY] Euchre Hands (#55)

    Ruby Quiz, Nov 24, 2005, in forum: Ruby
    Replies:
    2
    Views:
    136
    James Gray
    Nov 24, 2005
Loading...

Share This Page