I'm having problems with this problem because i don't know how to make a list with recursivity using generators. The idea is to create a function that receives a generator that generates n numbers and returns a list with those numbers.
This is my code
;GENERATOR THAT GENERATES "INFINITE NUMBERS OF FIBONACCI"
(define (fib)
(let ((a 0) (b 1))
(lambda ()
(let ((ret a))
(set! a b)
(set! b (+ ret b))
ret))))
;RETURNS A GENERATOR THAT GENERATES NUMBERS OF FIBONACCI UP TO N
(define (taking n g)
(let ((i 1))
(lambda ()
(if (> i n)
#f
(begin
(set! i (+ i 1))
(g))))))
Your definitions are fine! You just need to call them correctly to see it.
> (define t (taking 10 (fib)))
> (t)
0
> (t)
1
> (t)
1
> (t)
2
> (t)
3
> (t)
5
>
UPDATE
(define (generator->list n g)
(if (= n 0)
'()
(cons (g) (generator->list (- n 1) g))))
(generator->list 10 (fib))
So something like this:
(define (to-list gen)
(let loop ((l '()))
(let ((r (gen)))
(if r
(loop (cons r l))
(reverse! l)
))))
Untested. What this does is build up a list in reverse consing the truthy items. When it gets a falsy item, it stops and returns the reverse of the accumulation list.
Related
I'm having problems implementing one generator called fib in a function.
I want the function to return me a generator that generates the first n Fibonacci numbers.
;THIS IS MY GENERATOR
(define fib
(let ((a 0) (b 1))
(lambda ()
(let ((return a))
(set! a b)
(set! b (+ b return)
)return))))
;THIS IS MY FUNCTION
(define (take n g)
(define fib
(let ((a 0) (b 1) (cont 1))
(lambda ()
(if (>= cont n) #f
(let ((return a))
(set! cont (+ cont 1))
(set! a b)
(set! b (+ b return)
)(return)))))))
I expect a generator to return the Fibonacci numbers up to N (delivered to the function). But the actual output is :
begin (possibly implicit): no expression after a sequence of internal definitions in:
(begin
(define fib
(let ((a 0) (b 1) (cont 1))
(lambda ()
(if (>= cont n) #f
(let ((return a))
(set! cont (+ cont 1))
(set! a b)
(set! b (+ b return))
(return)))))))
Just as the error says, you have no expressions in your function's definition except for some internal definition (which, evidently, is put into an implicit begin). Having defined it, what is a function to do?
More importantly, there's problems with your solution's overall design.
When writing a function's definition, write down its sample calls right away, so you see how it is supposed / intended / to be called. In particular,
(define (take n g)
suggests you intend to call it like (take 10 fib), so that inside take's definition g will get the value of fib.
But fib is one global generator. It's not restartable in any way between different calls to it. That's why you started copying its source, but then realized perhaps, why have the g parameter, then? Something doesn't fit quite right, there.
You need instead a way to create a new, fresh Fibonacci generator when you need to:
(define (mk-fib)
(let ((a 0) (b 1))
(lambda ()
(let ((ret a))
(set! a b)
(set! b (+ ret b))
ret)))) ;; ..... as before .....
Now each (mk-fib) call will create and return a new, fresh Fibonacci numbers generator, so it now can be used as an argument to a take call:
(define (taking n g) ;; (define q (taking 4 (mk-fib)))
Now there's no need to be defining a new, local copy of the same global fib generator, as you were trying to do before. We just have whatever's specific to the take itself:
(let ((i 1))
(lambda () ; a generator interface is a function call
(if (> i n) ; not so good: what if #f
#f ; is a legitimately produced value?
(begin
(set! i (+ i 1))
(g)))))) ; a generator interface is a function call
Now we can define
> (define q (taking 4 (mk-fib)))
> (q)
0
> (q)
1
> (q)
1
> (q)
2
> (q)
#f
> (q)
#f
>
Hi I am trying to implement a program in scheme shifting a list k times to the left.
For example:
(shift-k-left ’(1 2 3) 2)
’(3 1 2)
I have managed to implement a code that do shift left once here:
(define shift-left
(lambda (ls)
(if (null? ls)
'()
(append (cdr ls)
(cons (car ls)
'())))))
I want to use shift left as a function on shift-k-left.
Here is a solution using circular-list from srfi/1.
(require srfi/1)
(define (shift xs k)
(define n (length xs))
(take (drop (apply circular-list xs) k) n))
Using your shift-left to shift k times:
If k is 0: do nothing
If k is not 0: shift k-1 times, and then shift-left the result.
That is,
(define (shift-left-k ls k)
(if (= k 0)
ls
(shift-left (shift-left-k ls (- k 1)))))
You may want to adjust to do something sensible for negative k.
The idea is to count down n while consing the cars of r to p and the cdrs to r then the base case becomes append r to the reverse of p. If we run into a null? r we reverse p and continue this wraps the rotation:
(define (shift-k-left l n)
; assume that n >= 0
(let loop ((n n) (p '()) (r l))
(if (= n 0)
(append r (reverse p))
(if (null? r)
(loop n '() (reverse p))
(loop (- n 1) (cons (car r) p) (cdr r))))))
Here is something similar:
(define (addn value n)
(let loop ((value value) (n n))
(if (zero? n)
value
(loop (add1 value) (- n 1)))))
(addn 5 3)
; ==> 8
Now you could make an abstraction:
(define (repeat proc)
(lambda (v n)
...))
(define addn (repeat add1))
(addn 5 3)
; ==> 8
(define shift-k-left (repeat shift-left))
(shift-k-left ’(1 2 3) 2)
; ==> (3 1 2)
Needless to say repeat looks a lot like add1 does.
NB: The naming is off. Your implementation is more "rotate" than "shift".
shift-left is actually more like cdr than your implemenation.
is it possible to implement Scheme function (one function - its important) that gets a list and k, and retreive the permutations in size of k, for example: (1 2 3), k=2 will output { (1,1) , (1,2) , (1,3) , (2,1) , (2,2) , ..... } (9 options).?
Its possible to do anything without defining anything as long as you have lambda:
(define (fib n)
;; bad internal definition
(define (helper n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))
(helper n 0 1))
Using Z combinator:
(define Z
(lambda (f)
((lambda (g)
(f (lambda args (apply (g g) args))))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(define (fib n)
((Z (lambda (helper)
(lambda (n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))))
n 0 1))
Now we are never calling Z so we can substitute the value of Z for Z in the function and it will do the same:
(define (fib n)
(((lambda (f)
((lambda (g)
(f (lambda args (apply (g g) args))))
(lambda (g)
(f (lambda args (apply (g g) args))))))
(lambda (helper)
(lambda (n a b)
(if (zero? n)
a
(helper (- n 1) b (+ a b))))))
n 0 1))
There you go, Saved by Alonzo Church.
It is not only possible, it is easy. Just use a loop:
(define permute
(lambda (k lst)
(let loop ((result (map list lst))
(i 1))
(if (= i k)
result
(loop
;; code to add each element of the original list
;; to each element of the result list
(1+ i))))))
I want to show the result of my function as a list not as a number.
My result is:
(define lst (list ))
(define (num->base n b)
(if (zero? n)
(append lst (list 0))
(append lst (list (+ (* 10 (num->base (quotient n b) b)) (modulo n b))))))
The next error appears:
expected: number?
given: '(0)
argument position: 2nd
other arguments...:
10
I think you have to rethink this problem. Appending results to a global variable is definitely not the way to go, let's try a different approach via tail recursion:
(define (num->base n b)
(let loop ((n n) (acc '()))
(if (< n b)
(cons n acc)
(loop (quotient n b)
(cons (modulo n b) acc)))))
It works as expected:
(num->base 12345 10)
=> '(1 2 3 4 5)
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.