[racket] Forcing termination of a for loop
Hello
I am learning to program in racket - and have questions regarding forcing
the exit from a for loop. I wrote the following program to determine the
largest prime factor of a number. (The correct answer being 11 in the case
of input 165)
-------------------------------------------------------------------------
#lang racket
(define number 165)
(define maxp 0)
(define (divides? a b)
(= (remainder a b) 0))
(define (set-vars i)
(set! maxp i)
(set! number (/ number i))
)
(define (loop)
(for ([i (in-range 3 number 2)] #:break (= number 1))
(if (divides? number i)
(set-vars i)
0
)
)
)
(loop)
(printf "~a\n" maxp)
-------------------------------------------------------------------------
I decided to try to improve this and then wrote
-------------------------------------------------------------------------
#lang racket
; this computes the largest prime factor of the odd number maxnum
(define maxnum 165)
(define (divides? a b)
(= (remainder a b) 0))
(define (divides-yes i stepn)
(set! maxnum (/ maxnum i))
(ploop i maxnum stepn)
)
(define (ploop minn maxn stepn)
(for ([i (in-range minn (+ 1 maxn) stepn)] #:break (= maxnum 1))
(if (= maxnum i)
(printf "~a\n" i)
0
)
(if (divides? maxnum i)
(divides-yes i stepn)
(ploop (+ minn stepn) maxn stepn)
)
)
)
(ploop 3 maxnum 2)
-------------------------------------------------------------------------
My third attempt avoided me having to use set!, but I find that it does
not terminate as I expect.
-------------------------------------------------------------------------
#lang racket
(define maxnum 165)
(define (divides? a b)
(= (remainder a b) 0))
(define (case-stop start stop step)
(printf "CASE-STOP ~s, ~s, ~s\n" start stop step)
(ploop 0 start stop 0)
)
(define (case-divide start stop step)
(printf "CASE-DIVIDE ~s, ~s, ~s\n" start stop step)
(ploop 1 start stop step)
)
(define (case-else start stop step)
(printf "CASE-ELSE ~s, ~s, ~s\n" start stop step)
(ploop 1 start stop step)
)
(define (gosub start stop step)
(printf "GO ~s, ~s, ~s\n" start stop step)
(for ([i (in-range start (+ 1 stop) step)] #:break (= step 0))
(cond [(= stop i) (case-stop start stop 0)]
[(divides? stop i) (case-divide i (/ stop i) step)]
[ else (case-else (+ start step) stop step)]
)
)
)
(define (stopsub start stop step)
(printf "STOP ~s, ~s, ~s\n" start stop step)
)
(define (ploop go start stop step)
(if (= go 1)
(gosub start stop step)
(stopsub start stop 0)
)
)
(ploop 1 3 maxnum 2)
--------------------------------------------------------------------
I expect the function, ploop, to terminate when invoked with the
first parameter set to 0, but it doesn't. I did try stopping the loop
with a #:break on one parameter which I set explicitly to stop the
loop but that did not do what I wanted either. (I am aware that the
code will not handle even numbers correctly but I want to get it to
work with odd numbers first). I want the loop inside the function
gosub to terminate but I am not able to force it to do so?
(I noticed that the code ran under Racket v5.3.4. but under
Racket v5.2.1. none of the code ran - it showed
for: bad sequence binding clause at: #:break?)
I hope that my intention is clear, and any advice would be
gratefully received, as to how I can correct the third program.
Bob