foo(x Y) is a procedure that has to solve this problem in the
Picture.
Here is my Scheme Code:
(define foo
(lambda (x y)
(if (<= y 0) (x) 0)
(if (<= x 0) (y) 0)
(if (>= x y) (+ x foo ((- x 1) (- y 2))) 0)
(if (< x y) (+ y foo ((- x 2) (- y 3))) 0)))
when it test it for (foo 5 6) => it prints the same exact numbers, instead of 12 !! I don't know why it is not going through the recursive call..
There is no recursive calls here. For it to be a call you need to have parentheses around it like (foo (- x 2) (- y 3))
Only the last if is regarded as becoming the result of the procedure. All the previous ones return a value and since it's not the last it discards the result and continues to the next. In order for several conditions to mean something they must be nested. Thus instead of the 0 you put the entire next if.
(define (foo x y)
(if (<= x 0)
x
(if (<= y 0)
y
...)))
There is also cond that makes a flatter structure that works as if-elseif-else in other languages.
(define (foo x y)
(cond
((<= x 0) x)
((<= y 0) y)
...
(else ...)))
Related
I'm starting to coding in Scheme and I wan't to know if a number is "abundante". A number x is "abundante" if the sum of its dividers is greater than the double of x.
So this is my code:
#lang scheme
(define (abundante x)
(cond
((= x 0) #f)
((= x 1) #f)
((> (apply +(divisores x)) (doble x)) #t)
(else #f)
)
)
;aux functions
(define (doble x) (* x 2))
(define (divisores x)
(cond
((= x 1) '(1))
(else (cons 1 (divisores-aux x 2)))
)
)
(define (divisores-aux x y)
(cond
((= x y) '(x))
((integer? (/ x y))(cons y (divisores-aux x (+ y 1))))
(else (divisores-aux x (+ y 1)))
)
)
As you can see, I have 3 auxiliary functions:
1) Doble x: Return the double of x
2) Divisores x: Return the dividers of x
2.1) Divisores-aux x y: Check if x/y is a integer number, then goes for y+1
But I got the problem when Divisores-aux reach x = y. I want to return x because x its a divider of itself but DrRacket prints the follow error:
+: contract violation
expected: number?
given: y
argument position: 6th
other arguments...:
And indicates me that the error was produced on apply +(divisores x)
If I return null or '() everything goes fine, but obviously I don't get the correct result.
Thanks in advance
There's a bug in the base case of divisores-aux, in here:
'(x)
The above expression will return a list with the symbol x as its single member (to understand why, read about quoting in the docs). What you meant to say was this, that creates a list with the value of the x variable:
(list x)
Also, it's better to use remainder to test if a number is divided by another. This should fix the issues:
(define (divisores-aux x y)
(cond
((= x y) (list x))
((zero? (remainder x y)) (cons y (divisores-aux x (+ y 1))))
(else (divisores-aux x (+ y 1)))))
Now abundante works as expected:
(abundante 42)
=> #t
(abundante 45)
=> #f
I'm having a little trouble creating a recursive function in Scheme. I need to create a function called foo(x) that recursively does the addition of all the powers. For example foo(5) would be 5^4 + 4^3 + 3^2 + 2^1 + 1^0 = 701.
The stopping condition is if x = 0 then return zero. Else then return x^x-1 + foo(x-1)
Here's what I have so far for my function:
(define (foo x)
(cond ((zero? x) 0)
(else (+(expt(x (- x 1)))foo(- x 1)))))
You just have to be more careful with the parentheses, in particular notice that the correct way to call a procedure is like this: (foo x), instead of this: foo(x). This should work:
(define (foo x)
(cond ((zero? x) 0)
(else (+ (expt x (- x 1))
(foo (- x 1))))))
(foo 5)
=> 701
Allow me to ident the code. I just pasted it in DrRacket and hit CTRL+I then put the arguments to + on one line each:
(define (foo x)
(cond ((zero? x) 0)
(else (+ (expt (x (- x 1)))
foo
(- x 1)))))
So the base case is ok, but your default case looks very off. x is treated as a procedure since it has parentheses around it and - also uses x as if it's a number. It can't be both.
foo is not applied since it doesn't have parentheses around it so it evaluates to a procedure value, while + would expect all its arguments to be numeric.
The rules of Scheme are that parentheses matters. x and (x) are two totally different things. The first x can be any value, but (x) is an application so x have to evaluate to a procedure. Some exceptions are for special forms you need to know by heart like cond, and define but rather than that it's very important to know you change the meaning of a program by adding parentheses.
The correct definition of your procedure might be:
(define (foo x)
(if (zero? x)
0
(+ (expt x (- x 1))
(foo (- x 1)))))
(foo 5) ; ==> 701
Here I've changed cond to if since none of conds features were used. Seeing cond I expect either side effects or more than one predicate.
Say I have a function recurse that takes three parameters x,y,z. y and z remain fixed, but x is iterative. I know how to generate a list of x values. How can I write code so that recurse is applied to the list of xs, but y and z remain the same?
I know map works like this but I don't know how to implement it considering it only works on lists of the same size. I do not know what the length of x will be. What I'm trying to do conceptually is call recurse on a list (x1, x2,...,xn) as such:
recurse x1 y z
recurse x2 y z
recurse xn y z
Just pass the parameters y and z unchanged:
(define (recurse x y z)
(unless (null? x)
;; … use x, y, z
;; then:
(recurse (cdr x) y z)))
Alternately you can define a helper function; made easy with 'named let`:
(define (recurse x y z)
(let recursing ((x x))
;; … use x, y, z
;; then:
(recursing (cdr x))))
An example:
(define (all-in-range? values min max)
(or (null? values)
(and (< min (car values) max)
(all-in-range? (cdr values) min max))))
You can use map:
(define (between x y z) (<= x y z))
(define (between-list xlist y z)
(map (lambda (e) (between e y z)) xlist))
> (between-list '(1 20 3 100 99 2) 5 15)
'(#t #f #t #f #f #t)
As an alternative to the lambda function used with map, in Racket you can use curryr. Also, if you just do it for side-effects, you can use for-each instead of map:
(define (between x y z) (display (<= x y z)))
(define (between-list xlist y z)
(for-each (curryr between y z) xlist))
> (between-list '(1 20 3 100 99 2) 5 15)
#t#f#t#f#f#t
You have a list '(x1 x2 … xn) and you want to apply a function recurse to each element xn as well as y and z. You haven't said what the return value will be. I will assume there is no return value.
(for-each (lambda (x) (recurse x y z)) <your list of x1, … xn>)
The lambda captures the values for y and z, takes the provided x argument and applies your recurse procedure to all three.
You either pass the same variable to the next recursion or you leave it out completely so that it is a free variable.
Eg. send it:
(define (make-list items value)
(if (zero? items)
'()
(cons value (make-list (- items 1) value))))
Have it as a free variable:
(define (make-list items value)
(let loop ((items items)(acc '()))
(if (zero? items)
acc
(loop (- items 1) (cons value acc)))))
For higher order procedures you also keep it as a free (closed over) variable:
(define (make-list items value)
(map (lambda (x) value) (range items))) ;; value exists in the anonymous functions scope
I'm trying to learn some functional programming and am doing project euler problems in scheme (racket) to get me started. I'm currently on problem 15 and I think I have a correct function for computing the number of paths in the lattice. Problem is that for large number of gridSize the function takes very long time to run.
(define uniqueTraverse
(lambda (x y gridSize)
(cond
((and (eq? x gridSize) (eq? y gridSize)) 1)
((eq? x gridSize) (uniqueTraverse x (+ y 1) gridSize))
((eq? y gridSize) (uniqueTraverse (+ x 1) y gridSize))
(else (+ (uniqueTraverse (+ x 1) y gridSize)
(uniqueTraverse x (+ y 1) gridSize))))))
I'm trying to figure out how to make this function tail call recursive but I don't know how to do it. I need some help getting started on how to think about optimizing functions like this using tail call optimization.
The problem is that you recompute the same results over and over again.
To solve this, you don't need tail calls - you need to remember old
results and return them without recomputing them. This technique is called memoization.
This is one solution:
#lang racket
(define old-results (make-hash))
(define uniqueTraverse
(lambda (x y gridSize)
(define old-result (hash-ref old-results (list x y) 'unknown))
(cond
; if the result is unknown, compute and remember it
[(eq? old-result 'unknown)
(define new-result
(cond
((and (eq? x gridSize) (eq? y gridSize)) 1)
((eq? x gridSize) (uniqueTraverse x (+ y 1) gridSize))
((eq? y gridSize) (uniqueTraverse (+ x 1) y gridSize))
(else (+ (uniqueTraverse (+ x 1) y gridSize)
(uniqueTraverse x (+ y 1) gridSize)))))
(hash-set! old-results (list x y) new-result)
new-result]
; otherwise just return the old result
[else old-result])))
(uniqueTraverse 0 0 2)
Memoization is one way, another is to use a different data representation.
I used the grid represented as a matrix, or vector of vectors.
Then set the value of the top row to 1 (as there is only on path on the top edge.
After that the next row ther first of the row is one, the second is the value of the entry in the column one above, plus the entry of or value before it in the row,
Recurse for each of the points in the row, and then for each row.
The answer then is the last point in the last row when you are done recursing.
For a 3x3 grid
1 1 1
1 2 3
1 3 6
6
Where the keys are very close together, (continuous, or nearly so) a vector representation is going to be more performant than a hash.
(define (make-lattice-point-square n)
(let ((lps (make-vector (+ n 1))))
(let loop ((i 0))
(if (> i n)
lps
(begin
(vector-set! lps i (make-vector (+ n 1)))
(loop (++ i)))))))
(define (lattice-ref lat x y)
;; where x is row, y is column thought it's not really important
(vector-ref (vector-ref lat y) x))
(define (lattice-set! lat x y value)
(vector-set! (vector-ref lat y) x value))
;; paths through a point are equal the the paths through the above point,
;; plus the paths through the left, those along the top and left edges
;; only have one possible path through them
(define (ways-exit-lattice n)
(let ((lps (make-lattice-point-square n)))
(letrec
((helper
(lambda (x y)
(if (or (= x 0) (= y 0))
(lattice-set! lps x y 1)
(lattice-set! lps x y
(+ (lattice-ref lps (- x 1) y)
(lattice-ref lps x (- y 1)))))))
(lattice-walker
(lambda (x y)
(cond ((and (= x n) (= y n))
(begin (helper x y) (lattice-ref lps x y)))
((= y n)
(begin
(helper x y)
(lattice-walker (++ x) 0)))
(else
(begin
(helper x y)
(lattice-walker x (++ y))))))))
(lattice-walker 0 0))))
notice all the calls to latice-walker are tail calls.
using RSR5 compliant scheme
I keep getting this error when trying to run the code:
(let ((exp lambda (x y) (if (= y 1) x (* (exp x (- y 1)) x)))))
Error:
let: bad syntax in: (let ((exp lambda (x y) (if (= y 1) x (* (exp x (- y 1)) x)))))
My function is supposed to define recursive exponentiation, but I'm having problems with let.
You're missing an opening parenthesis before the lambda, and the let form is missing a body. Also, you can't use let for defining recursive functions; you need to use letrec (for Scheme) or labels (for Common Lisp). Perhaps you meant this (Scheme):
(letrec ((exp (lambda (x y)
(if (= y 1) x
(* (exp x (- y 1)) x)))))
exp)