You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python克里比奇牌得分计算问题:长度为3的双顺子重复值未存储

克里比奇顺子得分函数:长度3双顺子无法正确统计的问题修复

我编写的count_runs函数能正确统计多数克里比奇顺子得分,但长度为3的双顺子(因存在对子导致多个3张顺子的情况)例外——当这类顺子出现在其他顺子之后时,重复值无法被正确保留到duplicate_values列表,导致得分计算错误。其他顺子类型均正常运行。

原代码:

def count_runs(card_values):
    all_values = []
    duplicate_values = []
    for i, value in enumerate(card_values):
        if value in all_values:
            if value not in duplicate_values:
                duplicate_count = card_values.count(value)
                if duplicate_count == 2:
                    duplicate_values.append(value)
                elif duplicate_count == 3:
                    duplicate_values += [value, value]
        else:
            all_values.append(value)

    all_values.sort()
    run_points = 0
    run_length = 1

    for i in range(1, len(all_values)):
        if all_values[i] == all_values[i-1]:
            continue
        if all_values[i] == all_values[i-1] + 1:
            run_length += 1
        else:
            if run_length >= 3:
                if len(duplicate_values) == 1 and duplicate_values[0] in range(all_values[i-run_length], all_values[i-1]+1):
                    run_points += run_length * 2
                elif len(duplicate_values) == 2:
                    if duplicate_values[0] == duplicate_values[1] and duplicate_values[0] in range(all_values[i-run_length], all_values[i-1]+1):
                        run_points += run_length * 3
                    elif duplicate_values[0] != duplicate_values[1] and all(x in range(all_values[i-run_length], all_values[i-1]+1) for x in duplicate_values):
                        run_points += run_length * 4
                    else:
                        run_points += run_length
                else:
                    run_points += run_length
            run_length = 1
            duplicate_values = []
    if run_length >= 3:
        if len(duplicate_values) == 1 and duplicate_values[0] in range(all_values[-run_length], all_values[-1]+1):
            run_points += run_length * 2
        elif len(duplicate_values) == 2:
            if duplicate_values[0] == duplicate_values[1] and duplicate_values[0] in range(all_values[-run_length], all_values[-1]+1):
                run_points += run_length * 3
            elif duplicate_values[0] != duplicate_values[1] and all(x in range(all_values[-run_length], all_values[-1]+1) for x in duplicate_values):
                run_points += run_length * 4
            else:
                run_points += run_length
        else:
            run_points += run_length

    print("Duplicate Values: ", duplicate_values)
    return run_points

问题原因分析

  1. 全局重复值收集导致跨run污染:
    duplicate_values是全局收集所有牌的重复值,而非针对当前处理的顺子(run)。当存在多个顺子时,某个顺子的得分计算会包含其他顺子的重复值,导致判断错误。

  2. run结束后清空重复值列表:
    在处理完一个顺子后,代码执行duplicate_values = []清空列表,导致后续顺子无法使用原本收集到的重复值。比如当长度3的双顺子出现在第二个位置时,处理第一个顺子后列表被清空,后续无法识别该双顺子的重复值。

修复方案

改用频率字典预处理所有牌的出现次数,然后针对每个顺子单独统计其范围内的重复情况,避免全局状态干扰:

from collections import Counter

def count_runs(card_values):
    # 预处理所有值的出现频率
    value_counts = Counter(card_values)
    # 获取去重并排序后的值
    sorted_unique = sorted(value_counts.keys())
    run_points = 0
    n = len(sorted_unique)
    
    i = 0
    while i < n:
        # 找到当前连续顺子的结束位置
        end = i
        while end + 1 < n and sorted_unique[end + 1] == sorted_unique[end] + 1:
            end += 1
        run_length = end - i + 1
        
        if run_length >= 3:
            # 统计当前顺子范围内的重复值情况
            duplicates = []
            for val in sorted_unique[i:end+1]:
                cnt = value_counts[val]
                if cnt >= 2:
                    # 每多一个重复,就多一个乘数因子(比如3张同牌贡献2个额外因子)
                    duplicates.extend([val] * (cnt - 1))
            
            # 计算当前顺子的得分乘数:1 + 重复值的数量
            multiplier = 1 + len(duplicates)
            run_points += run_length * multiplier
        
        # 跳到下一个非连续的位置
        i = end + 1
    
    return run_points

修复说明

  1. 频率字典预处理:用Counter统计每个牌值的出现次数,避免多次调用count()导致的性能问题。
  2. 独立处理每个顺子:遍历排序后的唯一值,找到每个连续顺子的范围,单独统计该范围内的重复值数量。
  3. 动态计算乘数:每个重复值(超过1次的部分)会增加顺子的组合数,比如对子贡献1个额外乘数(总乘数2),三张同牌贡献2个额外乘数(总乘数3),两个不同对子贡献2个额外乘数(总乘数4),完全符合克里比奇的得分规则。

测试用例验证:

  • 输入[2,2,3,4](长度3的双顺子):返回3*2=6,正确。
  • 输入[6,7,8,2,2,3,4](两个顺子,第二个是双顺子):返回3 + 3*2=9,正确。
  • 输入[2,2,3,3,4](两个对子的3张顺子):返回3*4=12,正确。

内容的提问来源于stack exchange,提问作者ajhansn2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:29:53