Scheme functions and lists, multiply,add - scheme

i am trying to write 2 functions in scheme, the first would multiply every value in a list by a user specified value, 2nd function would add a number to all the values in the list from previous result.
i tried something like that but racket throws an error.
(define test (list 1 1 2 3 5))
(define funca(*(test)(2)))

In Scheme we use the map higher-order procedure for applying a function over a list of elements - bear in mind that you can't multiply a list, what we can do is multiply each of its elements . For example, to multiply each of the elements by two do this:
(define test (list 1 1 2 3 5))
(map (lambda (element) (* 2 element))
test)
=> '(2 2 4 6 10)
Notice how we pass a lambda as parameter to map: that's a function that will get applied to each of the elements in the input list, returning a new list with the results. Similarly if we need to, say, add one to the elements in a list:
(map (lambda (element) (+ 1 element))
test)
=> '(2 2 3 4 6)
The above examples are hard-coded to multiply by two and to add one. For solving your problem, you just have to put each of the above snippets inside a function and pass along the correct parameters in the right places (left as an exercise for the reader).

Related

Return a predecessor for a given value and given list

I'm familiar with recursion procedures, but somehow I cannot solve this problem: I want to return a predecessor value for a given list.
(define (pred value lst)
...)
(pred 3 (list 8 3 7 3)) should return 8
(pred 2 (list 1 2 2 2 2)) should return 1
Note that I only want to return the "first" occurrence of a predecessor, therefore in this first example the number 7 does not have to be returned.
I'm currently stuck because I "loose information" about the predecessor value, once I call a recursion by (pred value (rest lst)) ... I don't know to "store" this information in e.g. a list.
Thanks for any help! I'm already trying for hours...
So here is how to fix this. You make a helper that takes additional arguments. One of those can be the previous element. eg.
(define (iterate-pred value last lst)
...)
(pred 3 '(1 2 3 4)) ; ==>
(iterate-pred 3 1 '(2 3 4)) ; ==>
(iterate-pred 3 2 '(3 4)) ; ==>
; ==> 2
So to update the variables you just call the same procedure again with the new values. It is just as easy as iterating the list to begin with, which uses the same strategy.
You can implement these as internal procedure either with define/letrec or you can use named let. Then you can omit value in the helper since you have access to it through the scope.
Good luck!

Any way to map functions with more than one argument in Scheme/Racket?

I'm currently doing an introductory course in Racket/Scheme, and am currently studying map, apply, and fold. For the most part, I've been assuming that map can only work on lambdas that accept a single argument. However, for certain problems I would find it incredibly useful to get around this somewhat - say, having a function that can be mapped to a list whilst also carrying an accumulator that updates independently for each recursive function call. While I can't get much more specific than that for fear of violating Honor Code, is there any way to get around being unable to give each recursive call an accumulator if you plan to use map?
map takes as many lists as you want:
(map + '(1 2 3) '(3 2 1) '(3 3 3)) ; ==> (7 7 7)
fold has an accumulator:
(foldl (lambda (a b c acc) (+ a b c acc)) 1 '(1 2 3) '(3 2 1) '(3 3 3)) ; ==> 22

Scheme language add one to every list element

Here is the problem:
Define a function addOne, which takes a list of numbers and returns a list where each number in the input list is increased by one. For example, (addOne ′(1 2 3 4)) should return (2 3 4 5), and (addOne ′(2 4 6 8)) should return (3 5 7 9).
I'm new for scheme language, need the help. Thank you!
Using map:
(define (add-one nums)
(map (lambda (x) (+ x 1)) nums))
I tried to think of a simple solution to this problem. I created a helper procedure, plus1, which takes in a number and returns the sum of that number and 1:
(define (plus1 x)
(+ x 1))
Then, I defined addOne using map:
(define (addOne lst)
(map plus1 lst))
Basically, map takes in two arguments: a procedure and a list. It applies that procedure to every item of that list, then returns the modified list according to that procedure. In this case, the map part of addOne just takes every item of the inputted list, adds 1 to it, and returns the new list.
Please respond with questions or feedback!

Scheme skip or continue during lambda map

I am building a function that takes a set of integers, and returns a subset of the odd integers. I am running into the problem that I need to skip over the even integers in my map, but right now my function returns #<void> instead.
(define (oddSubset set)
(map
(lambda (x)
(cond
((odd? x) x)))
s))
In use:
> (oddSubset '(1 2 3))
'(1 #<void> 3)
Is there logic I can use like "else, continue onto next element"?
Note: I am trying to rewrite the built in filter function
map does not have the possibility to skip, but you can use filter instead:
(filter odd? '(1 2 3 4 5 6)) ; ==> (1 3 5)
Or you can use fold-right
(fold-right (lambda (e acc)
(if (odd? e)
(cons e acc)
acc))
'()
'(1 2 3 4 5 6)) ; ==> (1 3 5)
I assume #!r6rs. Both fold-right and filter are in the library (rnrs lists (6)). There is also SRFI-1 which gives both of these procedures for a R5RS language.
In the none standard language #!racket uses the name foldr in place of fold-right.
map looks like a weird choice for this. By definition it maps a function onto each element in a list and returns the list of the results, so trying to "skip" elements seems unnatural.
filter is what you're looking for.
(filter odd? '(1 2 3))
'(1 3)
map applies a function on all elements. Each invocation of the function is supposed to be independant from the others. Even if you introduce a state with a closure, you can't avoid map to build a list of same size as your input.
You want to (re-)implement the filter function. If you want to do it by yourself, you should try to use foldl and foldr instead.
(cond
((odd? x) x))
map check each element in the list: if it is odd, then return that element. But you did not tell your program what to do when the element is not odd, so map return void.
To solve your problem: use filter instead, since map will return something for each element in the list.
If you want to know how to implement filter, try reading the second chapter of SICP

Comparing items in a list? scheme

If you have a list ( (1 4 5) 5 (6 2 5) ), and another list (5 1 3 7 5 (9 2 4) ), I need to write a procedure that compares items from the first list and sees if they're in the second. For example, (1 4 5) appears 0 times in (5 1 3 7 5 (9 2 3) ). 5 appears in this list 2 times, and (9 2 4) appears 0 times. So the list will return (0 2 0)
I need help writing a scheme procedure frequency that takes in two lists, the first being the one that has each component compared, and the second being the one that counts the number of occurrences of the first list. The procedure should return a list of the occurrences.
So far I've been told to make two procedures, one that counts the occurrences (counter) for each item and the other that keeps track of it in a list (frequency). I've done this so far:
(define (counter ele lst)
`(cond ((null? lst) `
'())
`((equal? ele lst)`
`(+ 1 (counter ele (cdr lst))))`
`(else`
`(counter ele (cdr lst)))))`
(define (frequency els lst)
`(if (null? els)`
`'()`
`(cons <???>`
`(frequency <???> lst))))`
I'm not sure what to do with the frequency procedure, and how to call the counter procedure from it
Thanks!
For something like this you are going to have to use something like pair? becuase you working with trees which are lists of lists.
For example the car of (list (list 1 2) 3 4) is going to be the list 1 2. So that means if you try to compare values you will get an error. You need to isolate the leaves (the individual numbers) from the pairs to be able to compare.

Resources