[plt-scheme] Project Euler #4 solution refactor?

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Sun Jun 17 02:31:22 EDT 2007

Grant Rettke wrote:

> It works, and it makes sense, but it is sort of tricky/ugly to read in
> that it logically has an inner and outer loop.
> 
> (define psum
>    (λ ()
>      (let ([top 999] [bot 1])
>        (let loop ([x top] [y top] [max 0])
>          (let* ([prod (* x y)]
>                 [str (number->string prod)]
>                 [ispal (string=? str (srfi13:string-reverse str))]
>                 [newmax (if (and ispal (> prod max)) prod max)])
>            (cond [(> newmax (* x x)) newmax]
>                  [(= x y bot) newmax]
>                  [(> y bot) (loop x (sub1 y) newmax)]
>                  [else (loop (sub1 x) top newmax)]))))))

One way is to nest two named loops, and copy the max value from
the outer loop to the inner loop:

(define (psum)
   (let ([top 999] [bot 1])
     (let loopx ([x top] [max 0])
       (if (= x bot) max
           (loopx (- x 1)
             (let loopy ([y x] [max max])
               (if (= y bot) max
                   (let* ([prod (* x y)]
                          [str (number->string prod)]
                          [ispal (string=? str
                                           (srfi13:string-reverse str))]
                          [newmax (if (and ispal (> prod max))
                                       prod max)])
                     (loopy (- y 1) newmax)))))))))

But, erm, I think your version is prettier.

You might want to look at either (lib "for.ss") or srfi-42.
With srfi-42 it becomes:

(require (lib "42.ss" "srfi"))

(define (palindromic? s)
   (equal? (string->list s)
           (reverse (string->list s))))

(max-ec (: x 999 99 -1)   ; loop from 999 to 100 with step -1
         (: y x 99 -1)     ; loop from x ti 100 with step -1
         (if (palindromic? (number->string (* x y))))
         (* x y))

-- 
Jens Axel Søgaard



Posted on the users mailing list.