gpt4 book ai didi

clojure - 在 Clojure 中计算 GS1 校验位的更惯用的方法

转载 作者:行者123 更新时间:2023-12-01 09:59:48 25 4
gpt4 key购买 nike

我正在尝试计算 GS1 check digit 并得出以下代码。计算校验位的算法是:

  1. 反转条码
  2. 删除最后一位(计算出的校验位)
  3. 将第一、第三、第五等数字相加数字乘以 3,偶数乘以 1。
  4. 从最接近的等于或大于 10 的倍数中减去总和

这听起来很简单,但我想出的解决方案似乎有点不雅。它确实有效,但我想知道是否有更优雅的写法。

(defn abs "(abs n) is the absolute value of n" [n]
(cond
(not (number? n)) (throw (IllegalArgumentException.
"abs requires a number"))
(neg? n) (- n)
:else n))

(defn sum-seq "adds (first number times 3) with (second number)"
[coll]
(+
(* (first coll) 3)
(second coll)))

(defn sum-digit
[s]
(reduce +
(map sum-seq
(partition 2 2 '(0)
(map #(Integer/parseInt %)
(drop 2 (clojure.string/split (clojure.string/reverse s) #"")))))))

(defn mod-higher10 "Subtracts the sum from nearest equal or higher multiple of ten"
[i]
(if (zero? (rem i 10))
0
(- 10(rem i 10))))

(defn check-digit "calculates a GS1 check digit"
[s]
(mod-higher10
(sum-digit s)))

(= (check-digit "7311518182472") 2)
(= (check-digit "7311518152284") 4)
(= (check-digit "7311518225261") 1)
(= (check-digit "7311518241452") 2)
(= (check-digit "7311518034399") 9)
(= (check-digit "7311518005955") 5)
(= (check-digit "7311518263393") 3)
(= (check-digit "7311518240943") 3)
(= (check-digit "00000012345687") 7)
(= (check-digit "012345670") 0)

最佳答案

(defn check-digit 
[s]
(let [digits (map #(Integer/parseInt (str %)) s)
[chk & body] (reverse digits)
sum (apply + (map * body (cycle [3 1])))
moddiff (mod (- 10 sum) 10)]
moddiff))

这个实现使用了两个我知道的 clojure 习语:

  • let 管理本地分解(和重用)
  • map 与第二个集合,是与问题“相邻”的无限惰性序列。

还对列表进行解构,以便将检查谓词编写为(= moddiff chk)

关于clojure - 在 Clojure 中计算 GS1 校验位的更惯用的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17921814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com