[plt-scheme] Cost of string creation? / Euler 8 code review

From: Grant Rettke (grettke at acm.org)
Date: Mon Jul 2 21:56:29 EDT 2007

Hi folks,

I wrote a solution for project Euler #8:

http://projecteuler.net/index.php?section=problems&id=8

My solution involves what I would imagine to be a decent amount of
string creation: 5000 strings. Usually string creation makes programs
slow but this doesn't run slowly at all, it runs very fast, faster
than a lot of the other solutions posted.

The creation is like this:
1. get a substring of a string
2. convert it to a list of chars
3. convert each char to a string
3. convert each string to a number

Why isn't this an expensive operation?

Here is my solution if that helps or if you would be kind enough to
code review this:

================================================================
#|
$LastChangedDate: 2007-07-02 20:22:48 -0500 (Mon, 02 Jul 2007) $
$LastChangedRevision: 271 $
$HeadURL: svn://osiris/project_euler/trunk/euler8.ss $
|#
(module euler8 mzscheme

  (provide (all-defined))

  (require (prefix ri13: (lib "13.ss" "srfi")))

  (define the-number
"7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450")

  ;! Get the greatest product of consecutive digits in a number
  ;  string -> int -> int
  ; .example (grtprod "1234" 2) -> 12
  ; .pre-condition length of str >= the consecutive digit number
  ; .parameter str string: The value being checked
  ; .parameter dgts int: The number of consecutive digits to analyze
  ; .post-condition none
  ; .returns int:
  (define greatprod1
    (λ (str digits)
      (let* ([len (string-length str)]
             [stop (add1 (- len digits))])
        (let loop ([start 0] [end digits] [found 0])
          (if (= start stop) found
              (let* ([candidate (apply * (map string->number (map
string (ri13:string-fold cons '() (ri13:substring/shared str start
end)))))]
                    [next-start (add1 start)]
                    [next-end (+ next-start digits)])
                (loop
                 next-start
                 next-end
                 (if (> candidate found) candidate found)))))))))

Posted on the users mailing list.