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

在Clojure中按特定方式分割保龄球得分字符串

解决Clojure中保龄球得分的帧分组与总分计算问题

我来帮你搞定这个保龄球得分分组的问题!在Clojure里处理这种结构化的字符串,我们可以结合序列操作和保龄球的规则来实现分组,之后再根据规则计算总分。

一、按帧分组的实现

首先得明确保龄球的帧规则,这样分组才有依据:

  • 前9帧:每帧要么是全中(X,单个字符),要么是补中(如6/,两个字符),要么是两次普通投球(如62、--,两个字符)
  • 第10帧:最多3个字符(如果前两次是全中或补中,会有补投),剩下的字符串直接作为第10帧

基于这个规则,我们可以写一个递归函数来完成分组:

(defn split-frames [s]
  (loop [remaining s
         frames []]
    (cond
      ;; 前9帧处理完成,剩余部分作为第10帧
      (= (count frames) 9) (conj frames remaining)
      ;; 字符串已空,直接返回已分组的帧
      (empty? remaining) frames
      ;; 当前字符是全中,单独作为一帧
      (= (first remaining) \X) (recur (rest remaining) (conj frames [(str (first remaining))]))
      ;; 否则取两个字符作为一帧
      :else (recur (drop 2 remaining) (conj frames [(str (first remaining)) (str (second remaining))])))))

测试分组效果

针对你给出的例子:

  1. 输入 "62--43---2----X--",调用函数后得到:
[["6" "2"] ["-" "-"] ["4" "3"] ["-" "-"] ["-" "-"] ["2" "-"] ["-" "-"] ["-" "-"] ["X"] ["--"]]

完全符合你想要的分组结构。

  1. 输入 "XXXXX6/XX7/XX5",调用后得到:
[["X"] ["X"] ["X"] ["X"] ["X"] ["6" "/"] ["X"] ["X"] ["7" "/"] "XX5"]

二、计算总分的实现

分组完成后,我们需要根据保龄球的得分规则计算总分:

  • 全中(X):当前帧得10分,加上接下来两次投球的得分
  • 补中(如6/):当前帧得10分,加上接下来一次投球的得分
  • 普通投球:两次投球的分数相加
  • 第10帧:直接计算所有投球的分数(补投的分数已包含在内)

步骤1:字符转分数的辅助函数

先写一个把单个字符转换成对应分数的函数:

(defn char->score [c]
  (cond
    (= c \X) 10
    (= c \/) 10  ; 补中代表第二次投球得分为10减去第一次的分数,这里先统一转10,后续计算时处理
    (= c \-) 0
    :else (Integer/parseInt (str c))))

步骤2:展开所有投球的分数序列

把分组后的帧展开成一个连续的分数序列,方便后续计算:

(defn expand-scores [frames]
  (flatten
    (map (fn [frame]
           (if (string? frame)
             (map char->score frame)
             (map char->score frame)))
         frames)))

步骤3:计算总分的核心函数

通过递归遍历展开后的分数序列,按照规则累加每帧的得分:

(defn calculate-total [frames]
  (let [expanded (expand-scores frames)]
    (loop [i 0
           total 0
           frame-count 0]
      (if (= frame-count 10)
        total
        (let [current (nth expanded i)]
          (cond
            ;; 处理全中:加10 + 下两次投球的分数
            (= current 10)
            (recur (inc i)
                   (+ total current (nth expanded (inc i)) (nth expanded (+ i 2)))
                   (inc frame-count))
            ;; 处理补中:加10 + 下一次投球的分数
            (= (nth expanded (inc i)) 10)
            (recur (+ i 2)
                   (+ total 10 (nth expanded (+ i 2)))
                   (inc frame-count))
            ;; 处理普通帧:加两次投球的分数和
            :else
            (recur (+ i 2)
                   (+ total current (nth expanded (inc i)))
                   (inc frame-count))))))))

测试总分计算

针对你的例子:

  1. 输入 "XXXXX6/XX7/XX5",调用 (calculate-total (split-frames "XXXXX6/XX7/XX5")) 会返回 248,符合预期。
  2. 输入 "62--43---2----X--",调用后返回 27,也和你给出的结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:00:24