HackerRank比较Triplets Clojure

per*_*kss 0 clojure

我无法解释为什么原子引用不保留inc的值.

1)如何纠正这个?2)为什么在调试模式下它似乎给出了正确的值?

我知道这可能不是最佳解决方案,但想要理解为什么它不起作用.

你的任务是通过比较a0和b0,a1和b1,a2和b2来找到他们的比较点.

如果a大于b,那么Alice将获得积分.如果a小于b,则Bob获得积分.如果a等于b,那么两个人都没有得到一个点.

(defn compare-the-triplets
  [alice bob]
  (let [alice-score (atom 0)
        bob-score (atom 0)]
    (for [i (range 3)]
      (let [a (get alice i)
            b (get bob i)]
        (cond
          (> a b) (swap! alice-score inc)
          (< a b) (swap! bob-score inc))
        )) [@alice-score @bob-score]))

(compare-the-triplets [5 6 7] [3 6 10])
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它为Atom返回0和0.我觉得这可能不是最好的答案,但它真的很烦人为什么调试工作并获得正确值的原子,但然后他们没有正确返回.

使用let和for的范围一定不能正确.

Car*_*ate 5

这是冒险进入审查领域,但我认为应该强调原子不是这里的正确工具.没有副作用的泄漏,但它们的使用不必要地使一切都膨胀,并且违背了常见的功能实践.

由于这基本上只是一种减少,这就是我认为最好的.你有一个集合(或者在这种情况下,有两个),需要积累一个值(或者再次,在这种情况下,两个).无论何时出现这种情况,reduce都应该想到:

(defn compare-the-triplets2 [alice bob]
  (reduce (fn [scores [al bo]]
            ; If the condition on the left is true, update either the 0th or 1st score
            (cond-> scores
              (> al bo) (update 0 inc)
              (< al bo) (update 1 inc)))

          ; Both start with a score of 0
          [0 0]

          ; Zip alice and bob together, then reduce over the zipped collection
          (map vector alice bob)))
Run Code Online (Sandbox Code Playgroud)

事实上,平局可能使事情复杂化,但cond->处理得很好.不幸的是,cond->不像是那样短路cond,所以效率会稍差.除非这被证明是时间关键代码,否则时差应该是可以忽略不计的.

注意它的使用update,以及它与你的使用有多相似swap!.在这种情况下,我使用0和1来指示向量累加器中的哪个得分递增.