本文介绍了如何从循环中返回延迟序列,并在Clojure中使用条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于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中使用条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 19:48