_Comment made by: mfikes_
下面是一个可能更小或至少更容易运行的复现代码。如果您取消对常规Clojure向量调用的注释并注释{{core.rrb-vector}}调用,您会发现事情开始正常工作。
如果您调用{{test-1}},您将得到正确的答案{{32}}(来自
https://adventofcode.com/2018/day/9)。
如果您改为调用{{test-2}},将引发错误。以下是从谜题中获取的测试输入。
(play 9 25) ; 32
(play 10 1618) ; 8317
(play 13 7999) ; 146373
(play 17 1104) ; 2764
(play 21 6111) ; 54718
(play 30 5807) ; 37305
以下是复现代码:
ns advent-2018.day-09
(:refer-clojure :exclude [subvec vector])
(:require
[clojure.core.rrb-vector :as fv]))
(defn vector [& more]
(apply fv/vector more)
#_(apply clojure.core/vector more))
(defn catvec [v1 v2]
(fv/catvec v1 v2)
#_(into v1 v2))
(defn subvec
([v x]
(fv/subvec v x)
#_(clojure.core/subvec v x))
([v x y]
(fv/subvec v x y)
#_(clojure.core/subvec v x y)))
(defn swap [marbles split-ndx]
(catvec
(subvec marbles split-ndx)
(subvec marbles 0 split-ndx)))
(defn rotl [marbles n]
(swap marbles (mod n (count marbles))))
(defn rotr [marbles n]
(swap marbles (mod (- (count marbles) n) (count marbles))))
(defn place-marble [marbles marble]
(let [marbles (rotl marbles 2)]
[(catvec (vector marble) marbles) 0]])
(defn remove-marble [marbles marble]
(let [marbles (rotr marbles 7)
first-marble (nth marbles 0)]
[(subvec marbles 1) (+ marble first-marble)]))
(defn play-round [marbles round]
(if (zero? (mod round 23))
(remove-marble marbles round)
(place-marble marbles round)))
(defn add-score [scores player round-score]
(if (zero? round-score)
scores
(assoc scores player (+ (get scores player 0) round-score))))
(defn play [players rounds]
(loop [marbles (vector 0)
round 1
player 1
scores {}]
(let [[marbles round-score] (play-round marbles round)
scores (add-score scores player round-score)]
(if (> round rounds)
(apply max (vals scores))
(recur
marbles
(inc round)
(if (= player players) 1 (inc player))
scores)))))
(defn test-1 []
(play 9 25))
(defn test-2 []
(play 10 1618))