Scheme 找到哈代–;使用R5RS方案的Ramanujan编号。请提出习惯用法和计算方面的改进建议。
我记得有一次去看电影 [Srinivasa Ramanujan]他生病的时候 在普特尼。我坐过出租车 1729号,并指出 在我看来,这个数字相当沉闷, 我希望这不是一场灾难 不祥之兆。“不,”他回答说, “这是一个非常有趣的数字;它 最小的数字是否可以表示为 两个不同立方体中两个立方体的和 方法。”[G.H.哈代,如中所述] 约瑟夫·塔塔科夫斯基在书中谈到这一壮举,“那又怎样? 给我两分钟和我的计算器手表,我也会这么做 我不知道该怎么做 塔塔科夫斯基先生会在一块计算器手表上完成这个证明,但是 下面是我的scheme函数,它枚举从 在1处,当它找到一个可表示为2的数字时停止 通过两个正数的立方体求和来分离方法。而且 索引返回1729 我希望在两个方面提出建议 改进。其中一个方面是,对方案、风格和习惯用法都不熟悉。另一个领域是计算。Sisc 不会返回根的确切数字,即使可能。对于 示例Scheme 找到哈代–;使用R5RS方案的Ramanujan编号。请提出习惯用法和计算方面的改进建议。,scheme,Scheme,我记得有一次去看电影 [Srinivasa Ramanujan]他生病的时候 在普特尼。我坐过出租车 1729号,并指出 在我看来,这个数字相当沉闷, 我希望这不是一场灾难 不祥之兆。“不,”他回答说, “这是一个非常有趣的数字;它 最小的数字是否可以表示为 两个不同立方体中两个立方体的和 方法。”[G.H.哈代,如中所述] 约瑟夫·塔塔科夫斯基在书中谈到这一壮举,“那又怎样? 给我两分钟和我的计算器手表,我也会这么做 我不知道该怎么做 塔塔科夫斯基先生会在一块计算器手表上完成这个证明,但是 下
(expt 27 1/3)
产生2.9999999996。但我确实知道
结果当对一个精确的数字进行立方运算时,(expt 3)
产生27
。我的
解决方案是得到一个立方根的确切楼层,然后进行测试
相对于地板的立方体和地板的立方体加上一,
如果其中一个匹配,则计算为匹配。这个解决方案看起来很混乱,也很难解释。有没有更直接的方法
; Find the Hardy-Ramanujan number, which is the smallest positive
; integer that is the sum of the cubes of two positivie integers in
; two seperate ways.
(define (hardy-ramanujan-number)
(let ((how-many-sum-of-2-positive-cubes
; while i^3 + 1 < n/1
; tmp := exact_floor(cube-root(n - i^3))
; if n = i^3 + tmp^3 or n = i^3 + (tmp + 1) ^3 then count := count + 1
; return count
(lambda (n)
(let ((cube (lambda (n) (expt n 3)))
(cube-root (lambda (n) (inexact->exact (expt n 1/3)))))
(let iter ((i 1) (count 0))
(if (> (+ (expt i 3) 1) (/ n 2))
count
(let* ((cube-i (cube i))
(tmp (floor (cube-root (- n cube-i)))))
(iter (+ i 1)
(+ count
(if (or (= n (+ cube-i (cube tmp)))
(= n (+ cube-i (cube (+ tmp 1)))))
1
0))))))))))
(let iter ((n 1))
(if (= (how-many-sum-of-2-positive-cubes n) 2)
n
(iter (+ 1 n))))))
;找到Hardy Ramanujan数,它是最小的正数
; 整数,是两个正整数的立方体之和
; 两种不同的方式。
(定义(hardy ramanujan编号)
(让((2个正立方体的数量和)
;而i^3+1精确(expt n 1/3‘‘‘)’))
(让国际热核实验堆((i 1)(计数0))
(如果(>(+(expt i3)1)(/n2))
计数
(让*((立方体一(立方体一))
(tmp(地板(立方根(-n立方体-i '))))
(国际热核实验堆(+i-1)
(+计数
(如果(或(=n(+cube-i(cube-tmp)))
(=n(+cube-i(cube(+tmp1()))))
1.
0))))))))))
(让iter((n 1))
(如果(=(2个正立方体的数量和n)2)
N
(国际热核实验堆(+1 n(()())))
您的代码看起来基本上很好,我看到一些非常小的问题需要评论:
- 无需在最里面的范围内定义
和多维数据集
多维数据集根
- 对内部函数使用
,使其看起来更清晰define
- 这与你问题的第二部分有关:你在浮点数上使用
,这会导致大的有理数(从分配两个大整数的意义上讲)——最好避免这种情况incexact->exact
- 这样做仍然不能解决你所做的额外测试——但那只是因为你不确定你是否有正确的数字,如果你错过了1。考虑到它应该接近整数,您可以只使用
,然后执行一次检查,从而节省一次测试舍入
(define (hardy-ramanujan-number n)
(define (cube n) (expt n 3))
(define (cube-root n) (inexact->exact (round (expt n 1/3))))
(let iter ([i 1] [count 0])
(if (> (+ (cube i) 1) (/ n 2))
(hardy-ramanujan-number (+ n 1))
(let* ([i^3 (cube i)]
[j^3 (cube (cube-root (- n i^3)))]
[count (if (= n (+ i^3 j^3)) (+ count 1) count)])
(if (= count 2) n (iter (+ i 1) count))))))
我在Racket上运行这个程序,看起来快了大约10倍(50ms vs 5ms)。不同的方案在精确求幂时表现不同:有些尽可能返回精确结果,有些在所有情况下都是不精确结果。您可以查看我的一组页面,看看哪些方案起到了什么作用。+1感谢您不要过度设计您的解决方案。我本来打算写一个解决方案,对一些事情进行微观优化,但您的答案非常简洁,显然足够快。太简单了!