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

From: David Einstein (deinst at gmail.com)
Date: Mon Jun 18 15:48:59 EDT 2007

Here is how I would approach this

(require (lib "40.ss" "srfi"))
(require (lib "13.ss" "srfi"))

(define (stream-list-merge s1 s2 pred)
  (cond ((stream-null? s1) s2)
        ((stream-null? s2) s1)
        (else
         (let ((s1car (stream-car s1))
               (s2car (stream-car s2)))
           (cond ((pred s1car s2car)
                  (stream-cons s1car (stream-list-merge (stream-cdr s1) s2
pred)))
                 ((pred s2car s1car)
                  (stream-cons s2car (stream-list-merge s1 (stream-cdr s2)
pred)))
                 (else
                  (stream-cons s1car
                               (stream-list-merge (stream-cdr s1)
                                                  (stream-cdr s2)
pred))))))))

(define (join-series s1 s2 f order)
  (let ((e1 (stream-car s1))
        (e2 (stream-car s2)))
    (stream-cons (f e1 e2)
                 (stream-delay
                  (stream-list-merge
                   (stream-map (lambda (e) (f e e2)) (stream-cdr s1))
                   (join-series s1 (stream-cdr s2) f order)
                   order)))))

(define (stream-down-from n)
  (if (zero? n) stream-null
      (stream-cons n (stream-down-from (- n 1)))))

(define (palindrome? n)
  (let ((s (number->string n)))
    (string=? s (string-reverse s))))

(stream-car (stream-filter palindrome? (join-series (stream-down-from 999)
(stream-down-from 999) * >)))

Which looks overly complicated, but join-series and stream-list-merge are
tools that I had written for other projects.

All of which leads me to ask two questions.  Can someone help me to
understand why I need the stream-delay in join-series?  I would have thought
that stream-cons delayed its second argument.
Also, does anyone what happened to the quasi-proposed srfi-41?




On 6/17/07, Jens Axel Søgaard <jensaxel at soegaard.net> wrote:
>
> 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
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070618/d5f0f7e6/attachment.html>

Posted on the users mailing list.