Possible position of element in list using recursion? - scheme

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.

Related

DrRacket 2 list inputs and reversing only one

I'll preface this by saying this is for an assignment, but I am not sure how to approach this after going through other stackoverflow questions for an hour or two.
I'm attempting to create a reverse function that accepts 2 lists as input and returns the first list reverse appended with the second list.
Example: (reverse '(1 2) '(3 4)) --> (2 1 3 4)
My code is below, I have tried conditional statements such as when the first list is NOT null then do the main logic, then when it is only return l2 (which still returned (3 4 2 1) instead of (2 1 3 4).
The problem I'm having is that no matter what I do the second list is always at the beginning of the first reversed list.
(define (myreverse l1 l2)
(if (null? l) l2)
(append (myreverse(cdr l1) l2) (list(car l1))))
Consider the following:
(reverse '(1 2 3 4))
=> '(4 3 2 1)
(append (reverse '(1 2)) '(3 4))
=> '(2 1 3 4)
Think about how you can implement reverse, and how you can use it in your myreverse procedure.
With racket/scheme it is very helpful to think of these kinds of problems from the bottom up.
For example, what do you do when the first list is null?? Well, you're done! so just return the second list. What do you do when it has just one element? Well, we tack that element onto the second list and we're done. But a moment's thought tells us that all the cases are now covered.
(define (rev-first left right)
(if (null? left)
right
(rev-first (??? left) (???? right))))
Actually this kind of recursion is captured with foldl and foldr more generally. But I don't know if it's instructive for you at this point.

Scheme - Adding a list to a list of lists?

I am trying to answer a scheme question, for a part of this question I have to make a list of lists:
(define (join a b (result '()))
(cons (list a b) result))
So I am taking in two characters, and placing them in a list, then I need to place each sublist into a list of lists, this function is being called recursively with two characters each time, so it is supposed to work like this:
join 1 4
=> ((1 4))
join 2 5
=> ((1 4) (2 5))
join 3 6
=> ((1 4) (2 5) (3 6))
However, I am getting ((3 6) (2 5) (1 4)), so the elements need to be reversed, I tried reversing my cons function to (cons result (list a b)) but then I get (((() 1 4) 2 5) 3 6), how can I get the list the right way around, or is there an easier way to do what I'm doing?
If you need to add elements at the end of a list use append; cons is for adding elements at the head. Try this:
(define (join a b (result '()))
(append result (list (list a b))))
Notice that append combines two lists, that's why we have to surround the new element inside its own list. Also, it's not a good idea to add elements at the end, using append is more expensive than using cons - if possible, rethink your algorithm to add elements at the head, and reverse the result at the end.
This can easily be done like this:
(define (group-by-2 lst)
(let loop ((lst lst) (rlst '()))
(if (or (null? lst) (null? (cdr lst)))
(rcons->cons rlst)
(loop (cdr lst)
(rcons (list (car lst)
(cadr lst))
rlst)))))
(group-by-2 '(1 2 3 4 5 6 7 8))
; ==> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8))
Now rcons is like cons but it makes a reverse list. (rcons 1 (rcons 2 (rcons 3))) ; ==> {3 2 1} however it is not a list so you have to convert it to a list (rcons->list (rcons 1 (rcons 2 (rcons 3))) ; ==> (3 2 1)
The magic functions are really not that magical:
(define rcons cons)
(define rcons->cons reverse)
So in fact I didn't really have to make that abstraction, but hopefully I made my point. It doesn't matter how you organize the intermediate data structure in your programs so why not make the best for the job you are doing. For lists it's always best to iterate from beginning to end and make from end to beginning. Every insert O(1) per element and you do a O(n) reverse in the end. It beats doing append n times that would make it O(n²)

Use intermediate language in racket to find permutations of a list [duplicate]

I have found the following piece of code that it makes permutation in Scheme. I mean if I enter like arguments '(1 2 3) it will give me:
((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1))
The code is the following:
(define (remove x lst)
(cond
((null? lst) '())
((= x (car lst))(remove x (cdr lst)))
(else (cons (car lst) (remove x (cdr lst))))))
(define (permute lst)
(cond
((= (length lst) 1)(list lst))
(else (apply append(map(lambda (i) (map (lambda (j)(cons i j))
(permute (remove i lst))))lst)))))
The first function remove, it seems straightforward that only gets rid of the caracter denoted by x, even if its repeated or not, by comparing it with the beginning of the list and calling recursively with the rest of it.
The part that I quite do not get it, is the permute function. For what I know map appies a function to every element of an argument (in this case a list), and apply just applies one function one time completely to all the arguments. So what is exactly doing this line:
(apply append(map(lambda (i) (map (lambda (j)(cons i j))
(permute (remove i lst))))lst)))))
For me it seems that it just wants to create a pair with two elements: i and j, which they will become a list with the elements permuted (if we take the assumption that a list is just a bunch of concatenated pairs). But the part that calls again to permute and remove with i, what is that part doing? It is just removing the head of the list to generate subsets of the list having the head of the pair, element i, fixed until it runs out of elements?
Any help?
Thanks
Let's pick this apart, going from the inside out. Fix lst and apply the inner expression to one of its elements.
> (define lst '(1 2 3))
> (define i 1)
> (permute (remove i lst))
((2 3) (3 2))
Looks good: the inner expression removes an element and generates permutations of the remainder of the list, recursively. Now map the lambda over these permutations:
> (map (lambda (j) (cons i j)) (permute (remove i lst)))
((1 2 3) (1 3 2))
So the inner map produces all permutations that start with some i, which we've set to 1 here.
The outer map makes sure all permutations are generated by considering all elements of lst as the first element.
> (map (lambda (i) (map (lambda (j) (cons i j))
> (permute (remove i lst))))
> lst)
(((1 2 3) (1 3 2)) ((2 1 3) (2 3 1)) ((3 1 2) (3 2 1)))
But this generates lists with too much nesting. Applying append flattens a list of lists,
> (append '(1 2) '(3 4) '(5 6))
(1 2 3 4 5 6)
> (apply append '((1 2) (3 4) (5 6)))
(1 2 3 4 5 6)
so we get a flat list of permutations out.
I've always found it easier to understand the algorithm on a higher
level before diving into an implementation and trying to understand
what's happening there. So the question is: what are the permutations
of a list, and how would you find them?
The permutations of a single element list are evidently just the list
itself.
The permutations of (a b) are the set [(a b) (b a)].
The permutations of (a b c) are the set
[(a b c) (a c b) (b c a) (b a c) (c a b) (c b a)]
In general there are n! permutations of a list of length n - we have n
choices for the first element, and once we've picked that, (n-1) choices
for the second element, (n-2) for the third element, and so on. This
decrease in the degrees of freedom as we fix more and more of the first
elements of the list is very suggestive: maybe we can represent the
finding the permutations of a list of length n in terms of the
permutations of a list of length (n - 1), and so on until we reach the
permutations of a single-element list.
It turns out that the permutations of a list a precisely the set
[element prepended to the permutations of list \ element, for every
element in list].
Looking at the (a b c) case confirms that this is
true - we have a preceding (b c) and (c b), which are the
permutations of (b c), b preceding (a c) and (c a) and so on. This
operation of prepending the element to the sublist could be defined as
(define (prepend j)
(cons element j))
and the operation of doing it for all the
permutations of the sublist would then be (map prepend (permute
sublist)). Now, defining a new prepend function for each element is
maybe overkill - especially since they all have the same form. So a
better approach is just to use a lambda, which captures the value of
the element under consideration. The desired operation is
then (map (lambda (j) (cons element j)) (permute sublist)). Now, we
want to apply this operation to each element of the list, and the way to
do that is using another map, giving:
(map (lambda (element)
(lambda (j) (cons element j) (permute sublist)))
list)
Now, this looks good, but there is a problem: each stage of the recursion takes single
elements and turns them into a list. That's fine for lists of length 1,
but for longer lists it repeats for every recursive call, and we get
very deeply nested lists. What we really want to do is to put all
these lists on the same footing, which is exactly what the (apply append ...) takes care of. And that's almost all of that line. The only
thing missing is how the sublist is generated in the first place. But
that's easy as well - we'll just use remove, so that sublist = (remove element list). Putting everything together, and we have
(apply append (map (lambda (i)
(lambda (j) (cons i j))
(permute (remove i lst)))
lst))
The base case takes care of the length = 1 case, and all of the others can be found from there

How to convert a list into its elements

This must be very easy to accomplish but I am new to racket and dont know how:
I have a list (1 2 3 4) and would like to convert it into (1)(2)(3)(4)
Or is there a way to build it as (1)(2)(3)(4). I am using
cons '(element) call-function
to build it inside a function (recursively)
Try this:
(map list '(1 2 3 4))
From your text, I see that you do '(element). Problem with that is that everything which is quoted is never anything but what you see. Thus if element happens to be a variable it won't be expanded because of the quote.
The right way to get a list with one element would be to use list. eg. (list element) to get whatever the variable element to be the one element in your list. However, you won't need this in a roll-your-own recursive procedure:
(define (listify lst)
(if (null? lst) ; if lst is null we are done
'() ; evaluate to the empty list
(cons (list (car lst)) ; else we make a list with the first element
(listify (cdr lst))))) ; and listify the rest of the list too
Most of the procedure now is facilitating going through the argument, but since it's a common thing to do we can use higher order procedures with foldr so that you only concentrating on what is going to happen with the element in this chain in correspondence with the rest of the process:
(define (listify lst)
(foldr (lambda (e acc)
(cons (list e) ; chain this element wrapped in a list
acc)) ; with the result from the rest of the list
'() ; initiate with an empty list
lst)) ; go through lst
Of course, since we do something with each element in a list and nothing fancy by using map we only need to supply what to do with each element rather telling how to join the chains in the list together as well.
(define (listify lst)
(map list lst)) ; make a new list by applying a list of each element
It's actually a single argument version of zip:
(require srfi/1)
(zip '(1 2 3 4)) ; ==> ((1) (2) (3) (4))
(zip '(1 2 3) '(a b c)) ; ==> ((1 a) (2 b) (3 c))
There you go. As simple as it can get.

On Scheme cons and dots notation

Given
#;> (cons (cons 1 2) 3)
((1 . 2) . 3)
When we try
#;> (cons 3 (cons 1 2))
(3 1 . 2)
What governs where the . is used? What would the memory representation of these constructs be?
Scheme implementations usually print things that look like lists in list form:
-> (cons 1 (cons 2 '()))
'(1 2)
In your example, (cons 3 (cons 1 2)) would be a list if it weren't for the last 2. So your implementation makes a best effort to print it as a list until the 2. The other example does not contain any part that looks like a list, so it just prints as nested pairs.

Resources