Find the Hardy–Ramanujan number using R5RS scheme. Please suggest improvements in idiom and calculations. -


i remember once going see [srinivasa ramanujan] when ill @ putney. had ridden in taxi cab number 1729 , remarked number seemed me rather dull one, , hoped not unfavorable omen. "no," replied, "it interesting number; smallest number expressible sum of 2 cubes in 2 different ways." [g. h. hardy told in "1729 (number)"]

in "math wrath" joseph tartakovsky says feat, "so what? give me 2 minutes , calculator watch, , i'll same without exerting little gray cells." don't know how mr. tartakovsky accomplish proof on calculator watch, following scheme function enumerates numbers starting @ 1 , stops when finds number expressable in 2 seperate ways summing cubes of 2 positive numbers. , indeeds returns 1729.

there 2 areas appreciate suggestions improvement. 1 area is, being new scheme, style , idiom. other area around calculations. sisc not return exact numbers roots, when be. example (expt 27 1/3) yields 2.9999999999999996. exact retults when cubing exact number, (expt 3 3) yields 27. solution exact floor of cube root , test against cube of floor , cube of floor plus one, counting match if either match. solution seems messy , hard reason about. there more straightforward way?

; find hardy-ramanujan number, smallest positive ; integer sum of cubes of 2 positivie integers in ; 2 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 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 3) 1) (/ n 2))                     count                     (let* ((cube-i (cube i))                            (tmp (floor (cube-root (- n cube-i)))))                       (iter (+ 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)))))) 

your code looks fine, see few minor things comment on:

  • there's no need define cube , cube-root @ innermost scope,

  • using define internal functions makes little clearer,

  • this related second part of question: you're using inexact->exact on floating point number can lead large rationals (in sense allocate pair of 2 big integers) -- better avoid this,

  • doing still doesn't solve test -- that's because you're not if have right number of if missed 1. given should close integer, can use round , 1 check, saving 1 test.

fixing above, , doing in 1 function returns number when it's found, , using more "obvious" identifier names, this:

(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 (+ 1) count)))))) 

i'm running on racket, , looks it's 10 times faster (50ms vs 5ms).


Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -