Scheme prime number assignment - scheme

I have this Scheme assignment where I need to display whether the integers in the range of 2-100 are prime or not. I know that Scheme does not allow one to change the value of a variable, but given how I did this I was wondering if this is fixable.
(let loop ((i 2))
(begin (print "")
(let loop ((j i))
(begin ()
(if (and (= (mod i j) 0) (not (= i j)))
(print i " is NOT PRIME"))
(if (= j 2)
(print i " is PRIME")
(loop (- j 1)))))
(if (= i 100)
(print "done first")
(loop (+ i 1)))))

You need to forget about counting/for loops for the moment, look for recursive patterns and helpful abstractions.
For instance this snippet may be helpfull
(define (test n)
(if (prime? n)
(begin (display i) (display " is prime.") (newline))
(begin (display i) (display " is NOT prime.") (newline))))
Also (let loop ((var binding) ...) body) is not what you think it is. It's not a variation of the C for i=x... Loop is just a name here, you could just as easily call it hiccup or roses. The form is used where defining an internal recursive function and calling it with specific expressions would do just as well, but where the sub-function wouldn't benifit from highly descriptive function and free variable names.

Related

In Scheme, how can I display something multiply times?

`(display-n "*" 4)`
****
This code should give 4 stars. How can I display this?
Also, this code should fit in this:
Finally figured out the entire good code. Thanks for all the hints and feedback!
(define (display-n k n)
(if (> n 0)
(do ((x 0 (+ x 1)))
((= x n))
(display k))))
(define (parasol n)
(define (triangle i)
(if (< i n)
(begin
(display-n " "(- n i 1))
(display-n "*" (+ (* 2 i) 1))
(newline)
(triangle (+ i 1)))))
(define (stick i)
(if (< i 3)
(begin
(display-n " " (- n 1))
(display "*") (newline)
(stick (+ i 1)))))
(triangle 0)
(stick 0))
(parasol 5)
Phrased differently, your question is:
How can I repeat an operation `n` times?
The solution is to use a loop. In Scheme you can choose between a "named let" or a "do loop".
See detailed explanation here:
What does the "do" control construct do in Scheme?
(define (display-n n k)
(if (> k 0)
(do ((x 0 (+ x 1)))
((= x k))
(display n))))
Found it. I'll put this here if an unfortunate soul is looking for the same thing.
For this specific case, since you're only outputting a single character long string, you can just make a string of n copies of that character and print it instead of using an explicit loop:
(define (display-n k n)
(display (make-string n (string-ref k 0))))
(display-n "*" 4)
or if passing a character instead of a string:
(define (display-n k n)
(display (make-string n k)))
(display-n #\* 4)
While knowing how to repeat an arbitrary task a given number of times is generally useful and probably a big point of the exercise, being able to find simpler approachs for special cases is also a good skill to have.

Print value -and- call function?

I am new to scheme, and have the following question:
If I want a function to also print -the value- of an expression and then call a function, how would one come up to doing that?
For example, I need the function foo(n) to print the value of n mod 2 and call foo(n/2), I would've done:
(define foo (lambda (n) (modulo n 2) (foo (/ n 2))))
But that, of course, would not print the value of n mod 2.
Here is something simple:
(define foo
(lambda (n)
(display (modulo n 2))
(when (positive? n)
(foo (/ n 2)))))
Note the check of (positive? n) to ensure that you avoid (/ 0 2) forever and ever.
I'm terrible at Lisp, but here's an idea: Maybe you could define a function that prints a value and returns it
(define (debug x) (begin (display x) (newline) x))
Then just call the function like
(some-fun (debug (some expression)))
As #Juho wrote, you need to add a display. But, your procedure is recursive without a base case, so it will never terminate.
Try this:
(define foo
(lambda (n)
(cond
((integer? n) (display (modulo n 2))
(newline)
(foo (/ n 2)))
(else n))))
then
> (foo 120)
0
0
0
1
7 1/2
Usually when dealing with more than one thing it's common to build lists to present a solution when the procedure is finished.
(define (get-digits number base)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (cons (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10) ; ==> (1 2 3 4)
Now, since you use DrRacket you have a debugger so you can actually step though this code but you rather should try to make simple bits like this that is testable and that does not do side effects.
I was puzzled when you were taling about pink and blue output until I opened DrRacket and indeed there it was. Everything that is pink is from the program and everything blue is normally not outputed but since it's the result of top level forms in the IDE the REPL shows it anyway. The differences between them are really that you should not rely on blue output in production code.
As other has suggested you can have debug output with display within the code. I want to show you another way. Imagine I didn't know what to do with the elements so I give you the opportunity to do it yourself:
(define (get-digits number base glue)
(let loop ((nums '()) (cur number))
(if (zero? cur)
nums
(loop (glue (remainder cur base) nums)
(quotient cur base)))))
(get-digits 1234 10 cons) ; ==> (1 2 3 4)
(define (debug-glue a d)
(display a)
(newline)
(cons a d))
(get-digits 1234 10 debug-glue) ; ==> (1 2 3 4) and displays "4\n3\n2\n1\n"

scheme function to call a procedure n times

Does scheme have a function to call a function n times. I don't want map/for-each as the function doesn't have any arguments. Something along the lines of this :-
(define (call-n-times proc n)
(if (= 0 n)
'()
(cons (proc) (call-n-times proc (- n 1)))))
(call-n-times read 10)
SRFI 1 has a list-tabulate function that can build a list from calling a given function, with arguments 0 through (- n 1). However, it does not guarantee the order of execution (in fact, many implementations start from (- n 1) and go down), so it's not ideal for calling read with.
In Racket, you can do this:
(for/list ((i 10))
(read))
to call read 10 times and collect the result of each; and it would be done left-to-right. But since you tagged your question for Guile, we need to do something different.
Luckily, Guile has SRFI 42, which enables you to do:
(list-ec (: i 10)
(read))
Implementing tail-recursion modulo cons optimization by hand, to build the resulting list with O(1) extra space:
(define (iterate0-n proc n) ; iterate a 0-arguments procedure n times
(let ((res (list 1))) ; return a list of results in order
(let loop ((i n) (p res))
(if (< i 1)
(cdr res)
(begin
(set-cdr! p (list (proc)))
(loop (- i 1) (cdr p)))))))
This technique first (?) described in Friedman and Wise's TR19.

How Do For Loops Work In Scheme?

I'm having some difficulty understanding how for loops work in scheme. In particular this code runs but I don't know why
(define (bubblesort alist)
;; this is straightforward
(define (swap-pass alist)
(if (eq? (length alist) 1)
alist
(let ((fst (car alist)) (scnd (cadr alist)) (rest (cddr alist)))
(if (> fst scnd)
(cons scnd (swap-pass (cons fst rest)))
(cons fst (swap-pass (cons scnd rest)))))))
; this is mysterious--what does the 'for' in the next line do?
(let for ((times (length alist))
(val alist))
(if (> times 1)
(for (- times 1) (swap-pass val))
(swap-pass val))))
I can't figure out what the (let for (( is supposed to do here, and the for expression in the second to last line is also a bit off putting--I've had the interpreter complain that for only takes a single argument, but here it appears to take two.
Any thoughts on what's going on here?
That's not a for loop, that's a named let. What it does is create a function called for, then call that; the "looping" behavior is caused by recursion in the function. Calling the function loop is more idiomatic, btw. E.g.
(let loop ((times 10))
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))
gets expanded to something like
(letrec ((loop (lambda (times)
(if (= times 0)
(display "stopped")
(begin (display "still looping...")
(loop (- times 1)))))))
(loop 10))
This isn't actually using a for language feature but just using a variation of let that allows you to easily write recursive functions. See this documentation on let (it's the second form on there).
What's going on is that this let form binds the name it's passed (in this case for) to a procedure with the given argument list (times and val) and calls it with the initial values. Uses of the bound name in the body are recursive calls.
Bottom line: the for isn't significant here. It's just a name. You could rename it to foo and it would still work. Racket does have actual for loops that you can read about here.

How to create a function that multiplies all numbers between 1 and "x" with dotimes?

I'm making a function that multiplies all numbers between an 1 input and a "x" input with dotimes loop. If you please, check my function and say what's wrong since I don't know loops very well in Scheme.
(define (product x)
(let ((result 1))
(dotimes (temp x)
(set! result (* temp (+ result 1))))
result))
Use recursion. It is the way to do things in Scheme/Racket. And try to never use set! and other functions that change variables unless there really is no other choice.
Here's a textbook example of recursion in Scheme:
(define factorial
(lambda (x)
(if (<= x 1)
1
(* x (factorial (- x 1))))))

Resources