Найдите число Харди-Рамануджана, используя схему R5RS. Пожалуйста, предложите улучшения в идиомах и расчетах.
Я помню, как однажды увидим [Шриниваса Рамануджан], когда он был болен в Патни. Я ехал в такси номер 1729 и отметил, что номер показался мне довольно скучным., и я надеялся, что это не было неблагоприятное предзнаменование. - Нет, - ответил он, - это очень интересное число. наименьшее число выражаются сумма двух кубов в двух разных пути."[Г. Х. Харди, как сказано в "1729 (номер)"]
In "Математика Гнева" Жозеф Тартаковский говорит об этом подвиге: "ну и что? Дай мне две минуты и часы с калькулятором, и я сделаю то же самое. без каких-либо маленьких серых клеток."Я не знаю, как Г - н Тартаковский выполнил бы это доказательство на часах калькулятора, но ниже приведена моя функция схемы, которая перечисляет начальные числа на 1 и останавливается, когда находит число, expressable в два разными путями путем суммирования кубов двух положительных чисел. И это возвращает indeeds 1729.
есть две области, где я был бы признателен за предложения для
улучшение. Одна из областей-быть новым для схемы, стиля и идиомы. Другая область - вокруг расчетов. Sisc
не возвращает точных чисел для корней, даже когда они могли бы быть. Для
пример (expt 27 1/3)
дает 2.999999999999999996. Но я вам точно
retults когда кубатуры точное число, (expt 3 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))))))
2 ответов
ваш код выглядит в основном нормально, я вижу несколько очень незначительных вещей, чтобы прокомментировать:
нет необходимости определять
cube
иcube-root
в самой сокровенной области,используя
define
для внутренних функций делает его выглядеть немного яснее,это связано со второй частью вашего вопроса: Вы используете
inexact->exact
на число с плавающей запятой, которое может привести к большим рациональным (в том смысле, что вы выделяете пара двух больших целых чисел) -- лучше этого избежать,это все еще не решает дополнительный тест, который вы делаете, но это только потому, что вы не уверены, есть ли у вас правильное число, если вы пропустили на 1. Учитывая, что это должно быть закрыть в целое число, вы можете просто использовать
round
а затем выполните одну проверку, сохранив один тест.
фиксировать вышеуказанное, и делать его в одной функции которая возвращает номер когда он найден, и, используя еще несколько "очевидных" имен идентификаторов, я получаю следующее:
(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))))))
я запускаю это на ракетке, и похоже, что это примерно в 10 раз быстрее (50 мс против 5 мс).
различные схемы ведут себя по-разному, когда дело доходит до точного возведения в степень: некоторые возвращают точный результат, когда возможно, некоторые неточный результат во всех случаях. Вы можете посмотреть ExactExpt один из моих набор контрасты реализации страницы, чтобы увидеть, какие схемы делать.