Comparing items in a list? scheme - 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.

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!

Possible position of element in list using recursion?

Can anybody tell how to insert an element in the list in different positions and return a list of those possible combination as lists using only recursion?
For example, list is (2 3) and element to insert is 1.
Output:
list(
list (1 2 3)
list (2 1 3)
list (2 3 1)
)
The first step is to determine what the output should look like, and in this case it should be a list of lists.
The second step is usually to break the problem down into cases of the input list.
The case of the empty list is pretty simple - the result is a list that contains one singleton list
(define (insert i ls)
(if (null? ls)
(list (list i))
(...)))
For the case of the non-empty list, it's helpful to examine the structure of the expected result.
(insert 1 '(2 3))
-->
((1 2 3) (2 1 3) (2 3 1))
Note that only the first element of the result has 1 as its first element, and we can easily create this with (cons 1 '(2 3)).
The other elements all have the first element of the input list as their first element, and if you look at their tails, (1 3) and (3 1), you'll see that they are the results of the recursion (insert 1 '(3)).
What's missing is that you need to cons the 2 onto each one of them afterwards.
Now we have all the necessary parts - in summary
(define (insert i ls)
(if (null? ls)
(list (list i))
(cons (cons i ls) (<...something...> (insert i (cdr ls))))))
Where I've left a "<...something...>" part for you to figure out.

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!

Adding Elements In a List Scheme

In Scheme, I am trying to iterate through a list adding each element from a portion of the list.
For example, if I had ((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()) for a list, I am trying to add the first part ( 1 2 5 ) and then the second part ( 1 2 ) and so on in order to see if each element adds up to a specific number.
Hope this makes sense, tried my best to explain this.
If someone could help me figure this problem out, I would really appreciate it.
To add the numbers of a (small) list you can use apply:
> (apply + '(1 2 3))
6
which is the same as
> (+ 1 2 3)
6
In order to apply this to a list of sublists, use map:
(define (f lst)
(map (lambda (sublst) (apply + sublst))
lst))
> (f '((1 2 5) (1 2) (1 5) (1) (2 5) (2) (5) ()))
'(8 3 6 1 7 2 5 0)
For larger list you might want to replace apply by foldl or equivalent.

count elements from within a nested list in scheme

I am trying to count elements from within a nested list in scheme, and rank them in order of frequency. For example I have a listP which looks like this '((1 3 6)(1 4 7)(1 5 8)(2 5 7)) and I want scheme to tell me that the order of frequency of the elements is (1 5 7 2 3 4 6 8). Actually I just need the three most frequent, so (1 5 7).
I can't find a function that will find the most frequent element, then get the next most frequent, etc. I have tried max, min, map, length and count but couldn't get anything working at all.
I hope someone can point me in the direction of the function I need. I'm happy to play around with the code once I know what function/s I can use, but this has me beat right now. Thanks!
This looks like a job for #ChrisJester-Young's bagify. Here's one possible solution, tested in Racket and using Chris' third implementation of bagify:
(define (frequency lst)
(map car
(sort (hash->list (bagify (append* lst)))
(lambda (x y) (> (cdr x) (cdr y))))))
(frequency '((1 3 6) (1 4 7) (1 5 8) (2 5 7)))
=> '(1 5 7 2 3 4 6 8)

Resources