मैं एक पर काम कर रहा हूँ परियोजना यूलर समस्या जिसमें फ़ैक्टरिंग नंबर शामिल हैं और ऐसा करने के लिए निम्न कार्य लिखा है।
(defn get-factors [value]
(let [max-factor (->> (Math/sqrt value)
(Math/floor)
(Math/round))
ifactors #{}]
(loop [n 2 factors ifactors]
(do
(println (format ">> N: %d, Factors: %s" n factors))
(cond
(when (> n max-factor) ; exit of we have passed the max-factor
(do
(println (format "--Exiting(%d): %s" n factors))
factors)) ; return factors
(when (= 0 (mod value n)); have we found a factor?
(do
(println (format"--Factor(%d)" n))
(recur (inc n) (conj factors n (/ value n))))) ; recurse: add _n_ and reciprocal _n_ to list
:default (do ; otherwise
(println (format"--default(%d): %s" n (= 0 (mod value n))))
(recur (inc n) factors)) ; recurse: increment _n_, dont modify factors
)))))
हालांकि, समारोह वापस आ रहा है nil
और मेरे println कथन का मूल्यांकन एक अजीब क्रम में किया जाता है। आरईपीएल के लिए आउटपुट यहां है (get-factors 12)
, जो वापस आना चाहिए #{2,3,4,6}
:
>> N: 2, Factors: #{}
--default(2): true
>> N: 3, Factors: #{}
--default(3): true
>> N: 4, Factors: #{}
--Exiting(4): #{}
--Factor(4)
>> N: 5, Factors: #{3 4}
--Exiting(5): #{3 4}
जैसा कि आप देख सकते हैं, हालांकि डिफ़ॉल्ट स्थिति को हिट किया जा रहा है (= 0 (mod value n))
पिछले मामले का सच साबित होता है। इसी तरह, बाहर निकलने की स्थिति दो बार हिट होती है। अंतिम मामला मूल्यांकन एन = 3 के लिए होना चाहिए, लेकिन आप एन = 5 तक आउटपुट देख सकते हैं।
मैं स्पष्ट रूप से कुछ मूल रूप से गलत कर रहा हूं लेकिन मैं क्या नहीं देख रहा हूं। (संबंधित, क्या सूची बनाने के बारे में जाने का कोई बेहतर तरीका है?)
उत्तर:
उत्तर № 1 के लिए 1सबसे पहले, किसी के परीक्षण भाग में "कब" (या "अगर") एक अंतर्निहित है cond
तो आप का उपयोग नहीं करना चाहिए when
खुद को उस परीक्षा के अंदर।
दूसरा, आप एक ही फॉर्म का उपयोग कर रहे हैं, ए when
फॉर्म, की पूरी शाखा के रूप में cond
, इसलिए cond
जब परीक्षण सही होता है तो वह दूसरा रूप नहीं देखता है।
उचित के इस उदाहरण को देखें cond
:
http://clojuredocs.org/clojure_core/1.2.0/clojure.core/cond
जवाब के लिए 0 № 2
यदि, जैसा कि अन्य ने सुझाव दिया है, तो आप सभी क्रूड को हटा दें - द when
रेत do
रेत println
एस - आपका कार्यक्रम काम करता है!
कुछ सुझाव:
- उपयोग
quot
के बजाय/
एक पूर्णांक मात्रा प्राप्त करने के लिए। - आप अपने थ्रेडिंग मैक्रो को भी शुरू कर सकते हैं:
(->> value (Math/sqrt) ... )
. - उपयोग
:else
, नहीं:default
या कैच-सब क्लॉज को पेश करने के लिए और कुछ भीcond
.