0

My question is very similar to "How do I return a group of sequential numbers that might exist in an array?".

I need to find a way to check if a given array of numbers (card values basically) is a poker straight, or simply return the longest sequence.

As Mr. Thomas suggested, each_cons works well, but in Texas Holdem, straight is not only 2, 3, 4, 5, 6 or 8, 9, 10, J, Q, but K, A, 2, 3, 4 also.

If we have figures signed as numbers I think it will make everything easier: J will be 11, Q will be 12 and so on.

Any idea how to achieve this?

Community
  • 1
  • 1
Leo
  • 2,061
  • 4
  • 30
  • 58
  • 1
    straights do not wrap in texas holdem (see: http://www.texasholdem-poker.com/straight) KA234 would not be a valid straight – Peter Andersen Feb 19 '13 at 23:36
  • wow, you're right, my whole life is a lie. but still, even the source you give, sign A,2,3,4,5 as valid!(what basically means this issue is still on the table) – Leo Feb 19 '13 at 23:39
  • Is this a homework assignment? If so, you should be figuring this out yourself, instead of asking for help. – the Tin Man Feb 20 '13 at 02:06
  • no, its not, im doing this purely for fun and to learn something – Leo Feb 20 '13 at 11:32

5 Answers5

1

Your input is an array of numbers. so I am assuming that J = 11, Q = 12, K= 13 and A= 1.

1) Sort the array 2) iterate through the array and the moment you run into the next number being more than one number greater than the previous number return false since it is not a straight hand.

if you are not assuming that J=11, Q=12, K=13, A=1, then you need an additional data structure (Perhaps a dictionary to make complexity low since a lookup is a O(1)) time. Dictionary a = new Dictionary(); a.key = "K"; a.value = "13".

now if you have an array of [10,11,J,Q,K] => iterate thourgh it and do a look up in your dictionary, and once your value is one more greater than the previous card then return false..

OBviously you'll have base cases, in case the input array is more than length 5. or is empty or is < 5. If you are doing overlapping straights, then the only thing that can come after a K is a A with value 1, so if thats the case then continue on in your loop. Hopefully this helps.

Good luck.

nav
  • 509
  • 4
  • 19
  • it changes nothing. if i assume A = 1, i have the same problem i had, but with combination of 10,J,Q,K,A – Leo Feb 19 '13 at 23:50
  • you know that A's can only be at the beginning or at the end. so if you have JQKA1 (this is not valid.. just return false).. you cant make a valid straight starting with (J, Q, K,). so if they are the first thing in your array you can just return false. it all depends how u want to implement your logic and your function. – nav Feb 20 '13 at 15:15
1

try this (assuming you've replaced the cards with numbers, A=1, 2=2)

def straight?(my_cards)    
  sorted = my_cards.uniq.sort

  if sorted.length < 5
    # cant form a straight with duplicates
    false

  else
    # also give an Ace a value of 14 so it can be placed after a King
    sorted << 14 if sorted[0] == 1

    # returns true if the last number is equal to 4 plus the first so
    # a hand with 2,3,4,5,6 will return true
    sorted.first + 4 == sorted.last
  end
jvnill
  • 29,479
  • 4
  • 83
  • 86
1

Maybe it's not optimal but I would use Array#rotate!:

@values = %w{A 2 3 4 5 6 7 8 9 10 J Q K A}

def longest_sequence cards
  cards, values = cards.sort_by{|c| @values.index c}, @values.dup
  # iterate down from 5 and rotate through cards/values until you find a match
  5.downto(1).each do |n|
    values.length.times do
      cards.length.times do
        return cards[0...n] if cards[0...n] == values[0...n]
        cards.rotate!
      end
      values.rotate!
    end
  end
end

longest_sequence ['A', '3', '4']
#=> ["3", "4"]
longest_sequence ['A', '3', '4', '2', '5']
#=> ["A", "2", "3", "4", "5"]
longest_sequence ['A', '10', 'Q', 'J', 'K']
#=> ["10", "J", "Q", "K", "A"]
pguardiario
  • 53,827
  • 19
  • 119
  • 159
1

Just enumerate all possible straights:

All_Poker_Straights = %w(A 2 3 4 5 6 7 8 9 10 J Q K A).each_cons(5)

and check if the (sorted) hand is one of them:

p All_Poker_Straights.include?(%w(4 5 6 7 8))
# => true
steenslag
  • 79,051
  • 16
  • 138
  • 171
0
class Array
  def sequences
    a = sort.uniq.inject([]){|a, e|
      a.last && e == a.last.last + 1 ? a.last.push(e) : a.push([e])
      a
    }
    a.push([*a.pop, *a.shift]) if a.first.first == 1 && a.last.last == 13
    a
  end
end

[1, 3, 4].sequences # => [[1], [3, 4]]
[1, 3, 4, 2, 5].sequences # => [[1, 2, 3, 4, 5]]
[1, 10, 12, 11, 13].sequences # => [[10, 11, 12, 13, 1]]

[1, 3, 4].sequences.max{|a| a.length} # => [3, 4]
[1, 3, 4, 2, 5].sequences.max{|a| a.length} # => [1, 2, 3, 4, 5]
[1, 10, 12, 11, 13].sequences.max{|a| a.length} # => [10, 11, 12, 13, 1]
sawa
  • 165,429
  • 45
  • 277
  • 381