<commit_before>module TheGambler
  module Poker
    POKER_HANDS = %w{
      high_card one_pair two_pair three_of_a_kind straight flush full_house four_of_a_kind straight_flush royal_flush
    }
    
    # Valuation methods ===========================================================================
    
    def poker_value
      if royal_flush? then
        10e10
      elsif straight_flush? then
        if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
          10e9 + 1
        else
          10e9 + contents.max_by(&:numerical_value).numerical_value
        end
      elsif four_of_a_kind? then
        c = contents.group_by(&:numerical_value)
        10e8 + c.keys.max_by{|k| c[k].count}
      elsif full_house? then
        c = contents.group_by(&:numerical_value)
        10e7 + c.keys.detect{|k| c[k].count == 3} * 13 + c.keys.detect{|k| c[k].count == 2}
      elsif flush? then
        10e6 + contents.max_by(&:numerical_value).numerical_value
      elsif straight? then
        if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
          10e5 + 1
        else
          10e5 + contents.max_by(&:numerical_value).numerical_value
        end
      elsif three_of_a_kind? then
        c = contents.group_by(&:numerical_value)
        10e4 + c.keys.detect{|k| c[k].count == 3}
      elsif two_pair? then
        c = contents.group_by(&:numerical_value)
        
        pair_one, pair_two = c.keys.select{|k| c[k].count == 2}.minmax
        
        10e3 + 13 * pair_two + pair_one
      elsif one_pair? then
        c = contents.group_by(&:numerical_value)
        10e2 + c.keys.detect{|k| c[k].count == 2}
      elsif high_card? then
        contents.max_by(&:numerical_value).numerical_value
      end
    end
    
    # Different kinds of hands ====================================================================
    
    def high_card?
      true  # Every hand has a high card.
    end
    
    def one_pair?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]}i
    end
    
    def two_pair?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD].*(.{1,2})[SCHD]\2[SCHD]}i
    end
    
    def three_of_a_kind?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD]}i
    end
    
    def straight?
      values = contents.map(&:numerical_value).sort
      values == (values.min..values.max).to_a or values == [2, 3, 4, 5, 14]
    end
    
    def flush?
      contents.map(&:suit).uniq.count == 1
    end
    
    def full_house?
      as_string = contents.sort_by(&:numerical_value).map(&:to_s).join
      as_string =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD](.{1,2})[SCHD]\2[SCHD]} or as_string =~ %r{(.{1,2})[SCHD]\1[SCHD](.{1,2})[SCHD]\2[SCHD]\2[SCHD]}
    end
    
    def four_of_a_kind?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD]\1[SCHD]}i
    end
    
    def straight_flush?
      straight? and flush?
    end
    
    def royal_flush?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{\A10([SCHD])J\1Q\1K\1A\1\Z}i
    end
    
  end
end
<commit_msg>Four of a kind and three of a kind 100% fully working.<commit_after>module TheGambler
  module Poker
    POKER_HANDS = %w{
      high_card one_pair two_pair three_of_a_kind straight flush full_house four_of_a_kind straight_flush royal_flush
    }
    
    # Valuation methods ===========================================================================
    
    def poker_value
      if royal_flush? then
        
        10e10
        
      elsif straight_flush? then
        
        if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
          10e9 + 1
        else
          10e9 + contents.max_by(&:numerical_value).numerical_value
        end
        
      elsif four_of_a_kind? then
        
        c = contents.group_by(&:numerical_value)
        10e8 + 13 * c.keys.max_by{|k| c[k].count} + c.keys.min_by{|k| c[k].count}
        
      elsif full_house? then
        
        c = contents.group_by(&:numerical_value)
        10e7 + c.keys.detect{|k| c[k].count == 3} * 13 + c.keys.detect{|k| c[k].count == 2}
        
      elsif flush? then
        
        10e6 + contents.max_by(&:numerical_value).numerical_value
        
      elsif straight? then
        
        if contents.map(&:numerical_value).sort == [2, 3, 4, 5, 14] then
          10e5 + 1
        else
          10e5 + contents.max_by(&:numerical_value).numerical_value
        end
        
      elsif three_of_a_kind? then
        
        c = contents.group_by(&:numerical_value)
        a, b = c.keys.select{|k| c[k].count == 1}.minmax
        10e4 + 13 * 13 * c.keys.detect{|k| c[k].count == 3} + 13 * b + a
        
      elsif two_pair? then
        
        c = contents.group_by(&:numerical_value)
        
        pair_one, pair_two = c.keys.select{|k| c[k].count == 2}.minmax
        
        10e3 + 13 * pair_two + pair_one
        
      elsif one_pair? then
        
        c = contents.group_by(&:numerical_value)
        10e2 + c.keys.detect{|k| c[k].count == 2}
        
      elsif high_card? then
        
        contents.max_by(&:numerical_value).numerical_value
        
      end
    end
    
    # Different kinds of hands ====================================================================
    
    def high_card?
      true  # Every hand has a high card.
    end
    
    def one_pair?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]}i
    end
    
    def two_pair?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD].*(.{1,2})[SCHD]\2[SCHD]}i
    end
    
    def three_of_a_kind?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD]}i
    end
    
    def straight?
      values = contents.map(&:numerical_value).sort
      values == (values.min..values.max).to_a or values == [2, 3, 4, 5, 14]
    end
    
    def flush?
      contents.map(&:suit).uniq.count == 1
    end
    
    def full_house?
      as_string = contents.sort_by(&:numerical_value).map(&:to_s).join
      as_string =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD](.{1,2})[SCHD]\2[SCHD]} or as_string =~ %r{(.{1,2})[SCHD]\1[SCHD](.{1,2})[SCHD]\2[SCHD]\2[SCHD]}
    end
    
    def four_of_a_kind?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{(.{1,2})[SCHD]\1[SCHD]\1[SCHD]\1[SCHD]}i
    end
    
    def straight_flush?
      straight? and flush?
    end
    
    def royal_flush?
      contents.sort_by(&:numerical_value).map(&:to_s).join =~ %r{\A10([SCHD])J\1Q\1K\1A\1\Z}i
    end
    
  end
end

{'fraction_non_alphanumeric': 0.18410041841004185, 'fraction_numerical': 0.032277346084877465, 'mean_word_length': 2.363316582914573, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2453311', 'n_tokens_mistral': 2635, 'n_tokens_neox': 2463, 'n_words': 420}