state
函数在time = t时返回灯的状态。
(defn thomsons-lamp []
(iterate (fn [[onoff dur]]
[(not onoff) (/ dur 2)])
[true 1]))
(defn state [t]
(let [t-vals (map second (thomsons-lamp))]
(loop [i 1]
(if (<= t (apply + (take i t-vals)))
((comp first last) (take i (thomsons-lamp)))
(recur (inc i))))))
如何定义清除state
函数(最好没有循环/重复)?
答案 0 :(得分:3)
这里唯一的罪孽是
state
减少/减少将是您state
功能的良好候选者。
(defn thomsons-lamp []
(map vector (iterate not true) (iterate #(* 1/2 %) 1)))
(defn state [t]
(reduce (fn [[s1 t1] [s2 t2]]
(if (>= t1 t) (reduced s1) [s2 (+ t1 t2)]))
(thomsons-lamp)))
答案 1 :(得分:3)
Clojure中的单行解决方案
在Clojure中,虽然不是在ClojureScript中,但我们可以将state
函数表示为一系列纯函数应用程序:
(defn state [t]
(-> t rationalize / biginteger .bitLength odd?))
或者,不使用线程宏
(defn state [t]
(odd? (.bitLength (biginteger (/ (rationalize t))))))
让我们测试一下:
(map (juxt identity state) [1 0.7 0.5 0.4 0.3 0.2])
; ([1 true] [0.7 true] [0.5 false] [0.4 false] [0.3 false] [0.2 true])
一步一步地采取行动:
(defn state [t]
(-> t
rationalize ; convert to a ratio to avoid losing precision using floating point
/ ; take the reciprocal
biginteger ; round down (if need be) to a java.math.BigInteger
.bitLength ; take its length in bits (a method, not a Clojure function)
odd? ; ask whether odd
))
它是如何运作的?
而不是测试给定数字t
在一系列切换点
1 1/2 1/4 1/8 ...
我们测试1/t
(Clojure中的(/ t)
)在倒置切换点系列中的位置
1 2 4 8 ...
,二进制,
1 10 100 1000 ...
是
中最小的数字1 2 3 4 ...
二进制数字。
应用BigInteger/bitLength
告诉我们有多少二进制数字1/t
- 四舍五入无效。这是1 2 4 8 ...
到达的系列1/t
的术语数。所以答案是这个数字是否是奇数。