In Scheme, how can I display something multiply times? - scheme

`(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.

Related

I need to this function to sum the number of unlimiited paramters

I am learning ELISP and this function should gather any number of parameters plus N and return the sum. This what I've got so far and I cannot figure out where my error is thanks. Also if a char is in the list it should just skip over and not add that to the value. I am using ELISP
(defun sum-numbers (n &rest L)
(let (a 0)
(if (not L) n
(dolist (x L result)
(if (integerp x)
(setq a (+ x a)))))
(setq a (+ a n))))
You are using let incorrectly.
There might be other errors too, but your code is unreadable due to broken indentation. Hit TAB on every line to get the indentation right.
Corrections:
(defun sum-numbers (n &rest L)
- (let (a 0)
+ (let ((a 0))
(if (not L)
n
- (dolist (x L result)
+ (dolist (x L (+ a n))
(if (integerp x)
- (setq a (+ x a)))))
- (setq a (+ a n))))
+ (setq a (+ x a)))))))
(Outside of learning, you'd just use + which already sums an arbitrary number of arguments.)

Scheme prime number assignment

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.

Scheme if expression returns '#<void>' if the body contains an expression

So I am currently reading SICP and I am stuck at exercise 1.22, since I do not understand why my program isn't working the way I intend it to work. Here is the Code
#lang sicp
; the given function to time the search for a prime
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
(if (prime? n)
(report-prime (- (runtime) start-time))))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
; finds the smallest natural number that can divide n without any remainder
(define (smallest-divisor n)
(define (square x)
(* x x))
(define (divides? a b)
(= (remainder a b) 0))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? n test-divisor) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(find-divisor n 2))
; returns true if the given number n is prime
(define (prime? n)
(= n (smallest-divisor n)))
; start searching at start and found keeps track of the amount of
; primes found, if it equals 3 return found
(define (search-for-primes start found)
(if (= found 3)
found ; after finding 3 primes above start return
((timed-prime-test start) ; if not continue search with start + 1
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))
(search-for-primes 1000 0)
The problem is that when I run this program it works fine until it finds a prime number. The interpreter that I use is racket and the program terminates with:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
3
1019 *** 0
If I understand the interpreter correctly than it should evaluate this expression according to the applicative-order evaluation principle right? So why is it passing the if expression as a procedure to my search-for-primes procedure? What am I missing here?
The problem is in search-for-primes, if you have more than one expression in one of the legs of an if, then you need to put them inside a begin block - surrounding it with () won't work. This should fix the problem:
(define (search-for-primes start found)
(if (= found 3)
found
(begin ; add this!
(timed-prime-test start)
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))

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 prime numbers

this is possibly much of an elementary question, but I'm having trouble with a procedure I have to write in Scheme. The procedure should return all the prime numbers less or equal to N (N is from input).
(define (isPrimeHelper x k)
(if (= x k) #t
(if (= (remainder x k) 0) #f
(isPrimeHelper x (+ k 1)))))
(define ( isPrime x )
(cond
(( = x 1 ) #t)
(( = x 2 ) #t)
( else (isPrimeHelper x 2 ) )))
(define (printPrimesUpTo n)
(define result '())
(define (helper x)
(if (= x (+ 1 n)) result
(if (isPrime x) (cons x result) ))
( helper (+ x 1)))
( helper 1 ))
My check for prime works, however the function printPrimesUpTo seem to loop forever. Basically the idea is to check whether a number is prime and put it in a result list.
Thanks :)
You have several things wrong, and your code is very non-idiomatic. First, the number 1 is not prime; in fact, is it neither prime nor composite. Second, the result variable isn't doing what you think it is. Third, your use of if is incorrect everywhere it appears; if is an expression, not a statement as in some other programming languages. And, as a matter of style, closing parentheses are stacked at the end of the line, and don't occupy a line of their own. You need to talk with your professor or teaching assistant to clear up some basic misconceptions about Scheme.
The best algorithm to find the primes less than n is the Sieve of Eratosthenes, invented about twenty-two centuries ago by a Greek mathematician who invented the leap day and a system of latitude and longitude, accurately measured the circumference of the Earth and the distance from Earth to Sun, and was chief librarian of Ptolemy's library at Alexandria. Here is a simple version of his algorithm:
(define (primes n)
(let ((bits (make-vector (+ n 1) #t)))
(let loop ((p 2) (ps '()))
(cond ((< n p) (reverse ps))
((vector-ref bits p)
(do ((i (+ p p) (+ i p))) ((< n i))
(vector-set! bits i #f))
(loop (+ p 1) (cons p ps)))
(else (loop (+ p 1) ps))))))
Called as (primes 50), that returns the list (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47). It is much faster than testing numbers for primality by trial division, as you are attempting to do. If you must, here is a proper primality checker:
(define (prime? n)
(let loop ((d 2))
(cond ((< n (* d d)) #t)
((zero? (modulo n d)) #f)
(else (loop (+ d 1))))))
Improvements are possible for both algorithms. If you are interested, I modestly recommend this essay on my blog.
First, it is good style to express nested structure by indentation, so it is visually apparent; and also to put each of if's clauses, the consequent and the alternative, on its own line:
(define (isPrimeHelper x k)
(if (= x k)
#t ; consequent
(if (= (remainder x k) 0) ; alternative
;; ^^ indentation
#f ; consequent
(isPrimeHelper x (+ k 1))))) ; alternative
(define (printPrimesUpTo n)
(define result '())
(define (helper x)
(if (= x (+ 1 n))
result ; consequent
(if (isPrime x) ; alternative
(cons x result) )) ; no alternative!
;; ^^ indentation
( helper (+ x 1)))
( helper 1 ))
Now it is plainly seen that the last thing that your helper function does is to call itself with an incremented x value, always. There's no stopping conditions, i.e. this is an infinite loop.
Another thing is, calling (cons x result) does not alter result's value in any way. For that, you need to set it, like so: (set! result (cons x result)). You also need to put this expression in a begin group, as it is evaluated not for its value, but for its side-effect:
(define (helper x)
(if (= x (+ 1 n))
result
(begin
(if (isPrime x)
(set! result (cons x result)) ) ; no alternative!
(helper (+ x 1)) )))
Usually, the explicit use of set! is considered bad style. One standard way to express loops is as tail-recursive code using named let, usually with the canonical name "loop" (but it can be any name whatever):
(define (primesUpTo n)
(let loop ((x n)
(result '()))
(cond
((<= x 1) result) ; return the result
((isPrime x)
(loop (- x 1) (cons x result))) ; alter the result being built
(else (loop (- x 1) result))))) ; go on with the same result
which, in presence of tail-call optimization, is actually equivalent to the previous version.
The (if) expression in your (helper) function is not the tail expression of the function, and so is not returned, but control will always continue to (helper (+ x 1)) and recurse.
The more efficient prime?(from Sedgewick's "Algorithms"):
(define (prime? n)
(define (F n i) "helper"
(cond ((< n (* i i)) #t)
((zero? (remainder n i)) #f)
(else
(F n (+ i 1)))))
"primality test"
(cond ((< n 2) #f)
(else
(F n 2))))
You can do this much more nicely. I reformated your code:
(define (prime? x)
(define (prime-helper x k)
(cond ((= x k) #t)
((= (remainder x k) 0) #f)
(else
(prime-helper x (+ k 1)))))
(cond ((= x 1) #f)
((= x 2) #t)
(else
(prime-helper x 2))))
(define (primes-up-to n)
(define (helper x)
(cond ((= x 0) '())
((prime? x)
(cons x (helper (- x 1))))
(else
(helper (- x 1)))))
(reverse
(helper n)))
scheme#(guile-user)> (primes-up-to 20)
$1 = (2 3 5 7 11 13 17 19)
Please don’t write Scheme like C or Java – and have a look at these style rules for languages of the lisp-family for the sake of readability: Do not use camel-case, do not put parentheses on own lines, mark predicates with ?, take care of correct indentation, do not put additional whitespace within parentheses.

Resources