The Maple computer algeba system has a command seq(f, i = m..n, step), which returns the sequence fm,...fn, where fi is the expression f with all occurrences of the symbol i replaced by the numeric value of i in the sequence of integers from m to n. Implement a scheme function (seq f (start step end)), and produces a list of values (f(start),f(start+step),...,f(start+n*step)), where n is the largest integer such that start+n*step <= end and start+(n+1)*step > end.
I thought this would work: (seq (lambda (x) (* x x)) '(0 2 7)) => (0 4 16 36)
The basic solution to this is to implement iota and map, and combine the two:
iota generates a list of numbers given the start, stop, and step
map invokes a given function on all the elements of the given list, and returns a new list containing the returned values
You have to write those functions, but once you have, your seq function is a simple matter of piecing the two together.
Related
I am reading Tree Recursion of SICP, where fib was computed by a linear recursion.
We can also formulate an iterative process for computing the
Fibonacci numbers. The idea is to use a pair of integers a and b,
initialized to Fib(1) = 1 and Fib(0) = 0, and to repeatedly apply the
simultaneous transformations
It is not hard to show that, after applying this transformation n
times, a and b will be equal, respectively, to Fib(n + 1) and Fib(n).
Thus, we can compute Fibonacci numbers iteratively using the procedure
(rewrite by Emacs Lisp substitute for Scheme)
#+begin_src emacs-lisp :session sicp
(defun fib-iter (a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
(defun fib (n)
(fib-iter 1 0 n))
(fib 4)
#+end_src
"Set a + b = a and b = a", it's hard to wrap my mind around it.
The general idea to find a fib is simple:
Suppose a completed Fibonacci number table, search X in the table by jumping step by step from 0 to X.
The solution is barely intuitive.
It's reasonably to set a + b = b, a = b:
(defun fib-iter (a b count)
(if (= count 0)
a
(fib-iter b (+ a b) (- count 1))
)
)
(defun fib(n)
(fib-iter 0 1 n))
So, the authors' setting seems no more than just anti-intuitively placing b in the head with no special purpose.
However, I surely acknowledge that SICP deserves digging deeper and deeper.
What key points am I missing? Why set a + b = a rather than a + b = b?
As far as I can see your problem is that you don't like it that order of the arguments to fib-iter is not what you think it should be. The answer is that the order of arguments to functions is very often simply arbitrary and/or conventional: it's a choice made by the person writing the function. It does not matter to anyone but the person reading or writing the code: it's a stylistic choice. It doesn't particularly seem more intuitive to me to have fib defined as
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter next current n)
(if (zero? n)
current
(fib-iter (+ next current) next (- n 1))))
Rather than
(define (fib n)
(fib-iter 0 1 n))
(define (fib-iter current next n)
(if (zero? n)
current
(fib-iter (+ next current) current (- n 1))))
There are instances where this isn't true. For instance Standard Lisp (warning, PDF link) defined mapcar so that the list being mapped over was the first argument with the function being mapped the second. This means you can't extend it in the way it has been extended for more recent dialects, so that it takes any positive number of lists with the function being applied to the
corresponding elements of all the lists.
Similarly I think it would be extremely unintuitive to define the arguments of - or / the other way around.
but in many, many cases it's just a matter of making a choice and sticking to it.
The recurrence is given in an imperative form. For instance, in Common Lisp, we could use parallel assignment in the body of a loop:
(psetf a (+ a b)
b a)
To reduce confusion, we should think about this functionally and give the old and new variables different names:
a = a' + b'
b = a'
This is no longer an assignment but a pair of equalities; we are justified in using the ordinary "=" operator of mathematics instead of the assignment arrow.
The linear recursion does this implicitly, because it avoids assignment. The value of the expression (+ a b) is passed as the parameter a. But that's a fresh instance of a in new scope which uses the same name, not an assignment; the binding just induces the two to be equivalent.
We can see it also like this with the help of a "Fibonacci slide rule":
1 1 2 3 5 8 13
----------------------------- <-- sliding interface
b' a'
b a
As we calculate the sequence, there is a two-number window whose entries we are calling a and b, which slides along the sequence. You can read the equalities at any position directly off the slide rule: look, b = a' = 5 and a = b' + a' = 8.
You may be confused by a referring to the higher position in the sequence. You might be thinking of this labeling:
1 1 2 3 5 8 13
------------------------
a' b'
a b
Indeed, under this naming arrangement, now we have b = a' + b', as you expect, and a = b'.
It's just a matter of which variable is designated as the leading one farther along the sequence, and which is the trailing one.
The "a is leading" convention comes from the idea that a is before b in the alphabet, and so it receives the newer "updates" from the sequence first, which then pass off to b.
This may seem counterintuitive, but such a pattern appears elsewhere in mathematics, such as convolution of functions.
I am supposed to write a function called (nth-filtered f n), where f is a function of one variable and n is a natural number, which evaluates to the nth natural number such that f applied to that number is #t.
If we called
(nth-filtered even? 1) we would get 2
(nth-filtered prime? 10) we would get 29
How do I make it so that it works for any sequential function? What should I think about when approaching this type of problem?
A variable is a variable and + is also a variable. The main difference between a function and some other data type is that you can wrap a function name in parentheses with arguments and it will become a new value.
eg.
(define (double fun)
(lambda (value)
(fun (fun value))))
(define (add1 v)
(+ 1 v))
(define add2 (double add1))
(add2 1) ; ==> 3
Now the contract doesn't say so you deduct by looking that you do (fun ...) that fun needs to be a function. Imagine this:
(define test (double 5)) ; probably works OK
(test 1)
The last one fails since you get application: 5 is not a procedure or something similar. The error message is not standardized.
How to attack your task is by making a helper that has the same arguments as your function but in addition the current number that I guess starts at 1. As I demonstrated you use the function variable as a function and recurse by always increasing the number and reducing n when the f call was #t. The actual function will just use the helper by passing all the parameters in addition to your state variable.
Your problem requires a fold, which is the standard way to iterate other a list while keeping a record of things done so far.
Here a very rackety method using for/fold:
(define (nth-filtered predicate index)
(for/fold ([count 0]
[current #f] #:result current)
([n (in-naturals 1)]) ; we start at 1 but we could start at 0
#:break (= count index)
(values (if (predicate n) (add1 count) count)
n)))
for/fold takes a list of initial state. Here we define count as the number of times the given predicate returned #t and current as the currently tested value.
Then it takes a list of iterators, in this case we only iterate infinitely over (in-naturals).
To make it stop, we provide a #:break condition, which is "when the number of truthy predicates (count) is equal to the requested amount (index)".
for/fold requests that it's body finishes with a list of values for each "state" variable, in order to update them for the next iteration. Here we provide two values: one is the new count, the other is just the current n.
You can try it out, it works as you requested:
> (nth-filtered even? 1)
2
> (require math/number-theory)
> (nth-filtered prime? 10)
29
> (nth-filtered prime? 5)
11
So, i'm trying to write the following function in scheme, and to be able to run it on DrRacket. The problem is as follows,
make5 - takes two integers, and returns a 5-digit integer constructed of the rightmost 3 digits of the first input, and the leftmost 2 digits of the second input. For example, (make5 561432 254) would return 43225.
Negative signs on either input number should be ignored - that is, (make5 561432 -254) would also return 43225.
If the first number has less than three digits or the last three digits start with zeros, and/or the second number has less two digits, your
function should return -2. Note: you may want to define some auxiliary functions.
So far this is the function I've been able to write.
(define (make5 x y)
(cond ((< (length x) 3) -2)
((< (length y) 2) -2)
(((modulo (abs(x)) 1000) 0) -2)
(((modulo (abs(y)) 1000) 0) -2)
(else (append (list-tail x 3) (cons (first(y)second(y)))))))
I'm getting the error...
application: not a procedure;
expected a procedure that can be applied to arguments
Any advice would be appreciated. I'm new to scheme and still trying to grasp everything.
Don't wrap your arguments in parentheses - (abs(x)) means "call the procedure x and pass the result to abs.
(cons (first(y)second(y)) means "cons these four things: the value of first; the result of calling the procedure y; the value of second; and the result of calling the procedure y".
(You've called procedures correctly in some places. Stick to the same pattern.)
You're also missing a comparison in a couple of conditions; (= (modulo (abs x) 1000) 0).
The inputs are not lists, they're integers, so you can't apply length, first, or any such things to them.
The result should be an integer, not a list, so you can't construct it using append and cons, you should only use arithmetic.
These facts about integers should get you started:
A number has fewer than five digits if it is smaller than 10000.
The last four digits of a non-negative number n is (modulo n 10000).
If x is 12 and y is 34, x * 100 + y is 1234.
To get the three leftmost digit in an integer, you can divide by 10 repeatedly until you have a number less than 1000.
Also note that the second number only has one condition on its digits while the first has two, and that the note about defining auxiliary functions was not left there as a challenge for you to do without them.
For instance, if you had the auxiliary functions
(left-digits n x), which produces the leftmost n digits of x, and
(right-digits n x), which produces the rightmost n digits of x
you could write (it's also probably not a coincidence that the description uses the words "if" and "or"):
(define (make5 x y)
(if (or ( ... ))
-2
(+ (* 100 (right-digits 3 x)) (left-digits 2 y))))
Since you want to ignore the sign of the numbers, it's convenient to take care of abs once at the start, using let:
(define (make5 signed-x signed-y)
(let ((x (abs signed-x))
(y (abs signed-y)))
(if (or ( ... ))
-2
(+ (* 100 (right-digits 3 x)) (left-digits 2 y)))))
"All" that's left now is filling in the conditions and writing the two digit-extracting functions.
Given this code:
(define (wrapper n)
(define (sum-ints)
(set! n (+ n 1))
(display n)(newline)
(if (= n 3)
n
(+ n (sum-ints))))
(sum-ints))
Calling this procedure with n = 0
(wrapper 0) =>
1
2
3
6
I had expected the process to increment n to a value of 3, and then as it returns, add 3 to 3 to 3 for an output of 3 3 3 9.
Does the inner procedure store a shadow copy of n?
Oog, mutation is nasty. The issue here is that "plus" is evaluated left-to-right. Specifically, let's consider the case when n=2. The expression (+ n (sum-ints)) is evaluated left-to-right. First, the identifier + evaluates to the plus function. Then, n evaluates to 2. Then, the recursive call is made, and the result is 3. Then, we add them together and the result is 5.
You'll see the same result in Java, or any other language that defines left-to-right evaluation of subexpressions.
Solution to this particular problem, IMHO: don't use mutation. It's needed in only
about 10% of the cases that people want to use it.
I have to create the following:
A Scheme procedure named 'proc2' which takes 4 numbers as arguments
and returns the value of the largest argument minus the smallest.
So I want to write
(define proc2
lambda(a b c d)
...
)
Is there any way I can evaluate (> a b), (> a c), (> a d) at the same time? I want to get the largest (and the smallest)number without having to write nested ifs.
Can you use the max and min procedures? if the answer is yes, it's pretty simple:
(- (max a b c d) (min a b c d))
If not, remember that <, >, <=, >= accept a variable number of arguments, so this is valid code and will tell you if a is smaller than b and b is smaller than c and c is smaller than d (although you'll have to test more combinations of b, c, d to make sure that a is the smallest value).
(< a b c d)
Also remember to consider the cases when two or more numbers are equal (that's why it's a good idea to use <= instead of <).
Anyway, you'll have to use conditionals. Maybe nested ifs, or perhaps a cond to make things simpler - you can work out the details yourself, I'm guessing this is homework.
If you want to find the smallest and largest members of the list and you are not allowed to use the standard min and max library functions, then I can think of three approaches
Write your own min and max functions (hint: recursion). Apply both to the list to find your two values. Perform the subtraction.
Write a combined function (again, recursive) which will pass through the list once, returning another two-member list which contains the max and min. If the first element in the returned list is the max, then (apply - (find-min-and-max 3 2 8 7)), where find-min-and-max is your function, would return the result of the subtraction.
Use map.
Option 1 is less efficient than option 2 but much simpler to write. Option 3 is more complex than either but actually does what you asked (that is, compare a to b, c and d "at the same time").
For example, if I defined the following function:
(define (compare test x l)
(map (lambda (y) (test x y)) l))
then
(compare < 3 '(1 2 4))
would return (#f #f #t)
How is this useful to you? Well, if (compare < x l) returns all true, then x is smaller than all elements of l. If it returns all false, then x is bigger than all elements of l. So you could use map to build the code you want, but I think it would be ugly and not the most efficient way to do it. It does do what you specifically asked for, though (multiple simultaneous comparisons of list elements).