我想让下面的代码对所有方面进行检查,特别是我想知道像这样使用let
是否是常见的用法,因为目前在let
语句中完成的计算比在其他代码中完成的要多。
找出前一百个自然数的平方和与和的平方之间的差额。
问题/问题
(ns project-euler.problems.problem6
(:require [project-euler.shared :as shared]))
(defn sum-square-difference [n]
{:pre [(number? n)]}
(let [sum-squares (reduce + (map shared/square (range 1 (inc n))))
square-sum (shared/square (reduce + (range 1 (inc n))))]
(- square-sum sum-squares)))
(println (sum-square-difference 100))
shared.clj
(ns project-euler.shared
(:require [clojure.math.numeric-tower :as math]))
(defn square [n]
{:pre [(number? n)]}
(math/expt n 2))
发布于 2016-10-05 11:17:03
与许多欧拉问题一样,可以全部或部分推导一个公式,以加快运行时的速度。在这种情况下,下面的公式提供了O(1)运行时。对于这个例子来说,这是微不足道的,但假设它是前10亿个数字的平方之和。由于您正在定义您自己的函数,正如我在我的示例中所做的那样,我认为提供最有效的解决方案是有意义的,以便在以后的问题中使用这些解决方案时,它们不会成为影响性能的因素。
关于let
的使用,是的,通常情况下,您将在let
绑定中绑定所需的内容。实际上,您完全可以在没有let
的情况下过活,但正如我在下面所做的那样,我认为您的代码比所有内联的代码都要清晰。
(defn sum-of-squares
"1^2 + 2^2 + 3^2 ... N^2 ==> N*(N+1)*(2N+1)/6 "
[n]
(/ (* n (+ n 1) (+ 1 (* n 2))) 6))
(defn sum-of-naturals
"1 + 2 + 3 ... N ==> N*(N+1)/2 "
[n]
(/ (* n (inc n)) 2))
(defn answer []
(let [sum (sum-of-naturals 100)
square-of-sum (* sum sum)
sum-of-square (sum-of-squares 100)]
(- square-of-sum sum-of-square)))
https://codereview.stackexchange.com/questions/142724
复制