对于Clojure和编程来说还是很新的事物,所以可以原谅这个愚蠢的问题.
Still very new to Clojure and programming in general so forgive the stupid question.
问题是:
找到n和k,直到n的数字总和(等于)等于n + 1到k的数字总和.
Find n and k such that the sum of numbers up to n (exclusive) is equal to the sum of numbers from n+1 to k (inclusive).
我的解决方案(效果很好)是定义以下功能:
My solution (which works fine) is to define the following functions:
(defn addd [x] (/ (* x (+ x 1)) 2)) (defn sum-to-n [n] (addd(- n 1))) (defn sum-to-k [n=1 k=4] (- (addd k) (addd n))) (defn is-right[n k] (= (addd (- n 1)) (sum-to-k n k)))然后运行以下循环:
(loop [n 1 k 2] (cond (is-right n k) [n k] (> (sum-to-k n k) (sum-to-n n) )(recur (inc n) k) :else (recur n (inc k))))这仅返回一个答案,但是如果我手动设置n和k,则可以得到不同的值.但是,我想定义一个函数,该函数返回所有值的惰性序列,以便:
This only returns one answer but if I manually set n and k I can get different values. However, I would like to define a function which returns a lazy sequence of all values so that:
(= [6 8] (take 1 make-seq))我如何尽可能有效地做到这一点?我已经尝试过各种方法,但是运气不太好.
How do I do this as efficiently as possible? I have tried various things but haven't had much luck.
谢谢
:修改:
我想我想出了一种更好的方法,但是它返回的"let应该是一个向量".Clojure文档并没有太大帮助...
I think I came up with a better way of doing it, but its returning 'let should be a vector'. Clojure docs aren't much help...
在这里输入新代码:
(defn calc-n [n k] (inc (+ (* 2 k) (* 3 n)))) (defn calc-k [n k] (inc (+ (* 3 k)(* 4 n)))) (defn f (let [n 4 k 6] (recur (calc-n n k) (calc-k n k)))) (take 4 (f)) 推荐答案如果您不想自己动手",这是另一种解决方案.我还通过重命名/重新格式化对算法进行了一些整理.
If you don't feel like "rolling your own", here is an alternate solution. I also cleaned up the algorithm a bit through renaming/reformating.
主要区别是您将循环重复视为 t/lazy-gen 形式内的无限循环.找到要保留的值时,可以使用 t/yield 表达式创建输出的惰性序列.就像Python中一样,此结构是 生成器函数 的Clojure版本.
The main difference is that you treat your loop-recur as an infinite loop inside of the t/lazy-gen form. When you find a value you want to keep, you use the t/yield expression to create a lazy-sequence of outputs. This structure is the Clojure version of a generator function, just like in Python.
(ns tst.demo.core (:use tupelo.test ) (:require [tupelo.core :as t] )) (defn integrate-to [x] (/ (* x (+ x 1)) 2)) (defn sum-to-n [n] (integrate-to (- n 1))) (defn sum-n-to-k [n k] (- (integrate-to k) (integrate-to n))) (defn sums-match[n k] (= (sum-to-n n) (sum-n-to-k n k))) (defn recur-gen [] (t/lazy-gen (loop [n 1 k 2] (when (sums-match n k) (t/yield [n k])) (if (< (sum-to-n n) (sum-n-to-k n k)) (recur (inc n) k) (recur n (inc k))))))有结果:
------------------------------- Clojure 1.10.1 Java 13 ------------------------------- (take 5 (recur-gen)) => ([6 8] [35 49] [204 288] [1189 1681] [6930 9800])您可以找到所有详细信息在图珀洛图书馆.
You can find all of the details in the Tupelo Library.
更多推荐
如何从循环中返回延迟序列,并在Clojure中使用条件?
发布评论