两个向量之间的“交叉”总和

时间:2016-03-20 15:01:35

标签: clojure

我有两个向量(或集合,从未表达过): [1 2 3 ...

让我们说

(def v (range 1 4))

我想计算这个向量的“交叉”-sum。 我的意思是对于v中的每个x,用v的每个值计算它的总和。

想象一下,矢量是[1 2 3],我想要一个像这样的矩阵:

    (1)(2)(3)
(1)  2  3  4
(2)  3  4  5
(3)  4  5  6

我不知道我是否清楚,但我没有看到任何Clojure功能。 我会考虑一个递归或置换,但它似乎不是很惯用。

有什么想法吗?

谢谢!

修改

计算“交叉”总和的代码示例(仅当数字不同时),减少mod n处的总和,然后计算有关它的统计数据

(defn crossed-sum [n]
  (let [v (range 1 (+ n 1))]
    (mapcat
      (fn [x]
        (for [k v
              :let [y (cond (= k x)
                              -1
                            :else
                              (+ k x))]]
          y))
      v)))

(defn mod-reduc [data n]
  (map
    (fn [x]
      (rem x n))
    data))


(defn compute-probability [n]
  (let [c-sum (-> (crossed-sum n)
                  (mod-reduc n)
                  (frequencies)
                  (dissoc -1))
        s (reduce + (vals c-sum))]
    (apply conj (map
                  (fn [[k v]]
                    {k (float (/ v s))})
                 c-sum))))

我使用for,但它是惯用的吗?

2 个答案:

答案 0 :(得分:2)

此函数生成一个列表列表(代替矩阵),就像您在示例中描述的那样。

(defn cross-add [v]
    (for [number v]
      (map #(+ number %)
           v)))

示例:

user> (cross-add [1 2 3])
((2 3 4) (3 4 5) (4 5 6))

user> (cross-add [5 13 8 9 12])
((10 18 13 14 17) (18 26 21 22 25) (13 21 16 17 20) (14 22 17 18 21) (17 25 20 21 24))

答案 1 :(得分:1)

BTW, void OnTriggerEnter(Collider obstacle) { if (obstacle.CompareTag("Stone")) { Stone stone = obstacle.gameObject.GetComponent (); if (stone.colliderType == ColloderTypeSlowDown) { // code } else { // code } } } 返回lazy seq,而不是向量。但是,这里并不重要。

使用range就足够了。

for

如果您只想计算不同的数字,可以这样写。

(let [numbers (range 1 4)]
  (for [n numbers
        m numbers]
    (+ n m)))
;; -> (2 3 4 3 4 5 4 5 6)