Rearrange a list given a list of indices - scheme

(rearrange-this '(4 (4 2) 1) '(a b c d)) -> (d (d b) a)
So I need this to recurse into the sub-lists and rearrange those.
(define (rearrange-this list1 list2) ;Initial function
(rearrange-r list1 list2 (count list1) '() list1))
;list 1 holds numbers, list2 hold letters
(rearrange-this '(4 3 2 1) '( a b c d )) ;-> outputs (d c b a)
(rearrange-this '(2 3 4 1 3 2 1 4) '(a b c d)) ;-> outputs (b c d a c b a d)

You want to use higher order functions whenever possible. The most important ones for list operations are: map, fold, filter, and list-tabulate. Learning these will save so much time.
map is incredibly useful in this situation. I used it to write a deep-map function which delves into sublists and applies an operation to the objects within, although it will not work if you want to map lists to something else since deep-map will delve into those lists. You would have to wrap such lists in something to make the list? check fail.
After writing deep-map, I use it with list-ref to select the appropriate element from value-list and replace the number in arrangement.
(define (deep-map operator deep-list)
(map
(lambda (element)
(if (list? element)
(deep-map operator element)
(operator element)))
deep-list))
(define (rearrange-this arrangement value-list)
(deep-map
(lambda (element)
(list-ref value-list element))
arrangement))
Here is a quick test of the code. Note that unlike your code, the list positions start at 0. You could map the input arrangement list if you want to have input references starting at 1. I will leave that as an exercise to you.
> (rearrange-this '(3 2 (1 0)) '(a b c d))
;Value 16: (d c (b a))

Related

Retrieve nth cdr of a list in Scheme

I would like to return the nth cdr of a list. For example, I say
(nth-cdr 3 '(a b c d e)) and i would get (c d e) as output. I am not sure where I am going wrong with my code.
My approach is this. I will check if (= num 0) if it is, I will return the list. If not, I will recursively call nth-cdr and subtract 1 from num and cdr list
The code is this
(define arbitrary-cdr (lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list))
)))
However, I get this error when i try doing (arbitrary-cdr 3 ‘(a b c d e))
‘: undefined;
cannot reference an identifier before its definition
I am not sure what this means. When I say that, it means I hit the base case and would just like to return the list. I think my logic is correct though.
The first code that you posted was:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
(list)
(arbitrary-cdr (- num 1) (cdr list)))))
The error that you received was:
scratch.rkt> (arbitrary-cdr 3 '(a b d c e))
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: '(c e)
The problem was that you used list as an argument to the arbitrary-cdr procedure; since Racket is a lisp-1, procedures do not have their own namespace, so this redefined list. With (list), and with list redefined the code attempted to call ((c e)), but (c e) is not a procedure.
This is a great example for why you should not use list or other built-in procedure identifiers as parameters in your own procedure definitions in Scheme or Racket. You can get away with this in Common Lisp, because Common Lisp is a lisp-2, i.e., has a separate namespace for functions.
With your updated code:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list)))))
I don't get the error you report; maybe your code is not quite what you have posted. But, there is a mistake in the logic of your code. As it is, an empty list will always be returned:
scratch.rkt> (arbitrary-cdr 3 '(a b c d e f))
'()
The problem is that when the base case is reached you should return the input list, not an empty list. That is, given (arbitrary-cdr 0 '(a b c)), you want the result to be (a b c). This also means that your test case is wrong; (arbitrary-cdr 0 '(a b c d e)) --> '(a b c d e), and (arbitrary-cdr 3 '(a b c d e)) --> '(d e).
Here is your code rewritten, using xs instead of list to avoid the redefinition, and returning xs instead of an empty list when the base case is reached:
(define arbitrary-cdr
(lambda (num xs)
(if (= num 0)
xs
(arbitrary-cdr (- num 1) (cdr xs)))))
Sample interactions:
scratch.rkt> (arbitrary-cdr 0 '(a b c d e))
'(a b c d e)
scratch.rkt> (arbitrary-cdr 1 '(a b c d e))
'(b c d e)
scratch.rkt> (arbitrary-cdr 3 '(a b c d e))
'(d e)

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

Are these 2 expressions using quotation and list the same when evalulating expressions?

Are these 2 expressions using quotation and list the same when evaluating the expression such as a derivative?
The intrepreter outputs the same values for both:
(define a '(+ 3 4))
(define b (list '+ 3 4))
a
b
(car a)
(car b)
Output:
=> (+ 3 4)
=> (+ 3 4)
+
+
For these expressions:
(define a '(+ 3 4))
(define b (list '+ 3 4))
Do they have the same value? yes:
(equal? a b)
=> #t
Do they refer to the same object? no:
(eq? a b)
=> #f
I guess that you want to somehow process the lists (say, for calculating a derivative). It doesn't matter how you created the lists as long as you're only interested in treating them as lists of symbols, and you can safely switch back and forth between either representation. It'd be different if you were to treat the operators as actual procedures, these are different things:
(define a '(+ 3 4))
(define b (list + 3 4)) ; quote was removed
(equal? a b)
=> #f
Consider this example:
(define a '(+ 3 4))
(define b (list '+ 3 4))
(define c '(+ 3 4))
Here a will point to an immutable* list (+ 3 4). b will point to a list whose elements are the same as a but it's produced when that statement is evaluated (a can exist before the program runs since it's a constant and for a compiled program the order and how it gets produced is not important). In b you are guaranteed that all the cons cells are newly created and unique. Thus (equal? a b) ; ==>#t while (eq? a b) ; ==> #f.
The output of (eq? a c) is undefined. Some Scheme implementations will create a new immutable list while others will point to the same list created earlier because they are both immutable according to the spec.
*Immutable by the specifications in the Scheme standard but this is seldom enforced so many implementations lets you alter immutable data with undefined behavior as consequence.

Weird Common Lisp intersection behaviour

I'm trying to get the common elements of two lists.
I've tried both the available intersection function and one I implemented myself, both giving the same weird result when trying to test them on lists like (a a ... a) and (a b c d ... z).
Whenever the first list contains only the same element several times and the second list begins with that element the result is the first list.
For example: (intersection '(2 2 2 2) '(2 2 2 3)) returns (2 2 2 2)
The intersection I implemented:
(defun presentp (a l)
(cond ((null l) nil)
((and (atom (car l)) (equal a (car l))) t)
((not (atom (car l))) (presentp a (car l)))
(t (presentp a (cdr l)))))
(defun intersectionp (a b)
(cond ((not (and a b)) nil)
((presentp (car a) b) (append (list (car a)) (intersection (cdr a) b)))
(t (intersection (cdr a) b))))
How can I get a good result on lists of that type? For example I want (2 2 2) from (intersection '(2 2 2 2) '(2 2 2 3)).
You need to remove matches from the b list.. When you found an 2 in (2 2 2 3) you should continue with (2 2 3) as b.
Also.. (append (list x) result-list) is the same as (cons x result-list) just with the same or fewer CPU cylces.
(defun intersection (a b)
(cond ((not (and a b)) nil)
((presentp (car a) b)
(cons (car a)
(intersection (cdr a)
(remove (car a) b :count 1))))
(t (intersection (cdr a) b))))
There's already an accepted answer, but I want to point out that the answer the implementation provides, where
(cl:intersection '(2 2 2 2) '(2 2 2 3))
;=> (2 2 2 2)
is correct. It's important to recognize that the intersection, nintersection, etc., are intended for use with lists that are being treated as sets. Conceptually, a set has no duplicate elements (for that you'd need a multiset), so the lists (2), (2 2), (2 2 2), etc., all represent the same set, {2}.
14.1.2.2 Lists as Sets
Lists are sometimes viewed as sets by considering their elements
unordered and by assuming there is no duplication of elements.
adjoin nset-difference set-difference union
intersection nset-exclusive-or set-exclusive-or
nintersection nunion subsetp
Figure 14-5. Some defined names related to sets.
Now, that bit about "assuming there is no duplication of elements" actually means that you probably shouldn't be using the set functions with a list like (2 2 2 2), since there's obvious duplication of elements. Even so, if you posit that lists like (2 2 2) and (2 2 2 2) represent the same set, you can see that intersection is actually giving you the correct set back. I think that the specification actually mandates that the result will have three or four elements. From the HyperSpec entry on intersection:
The intersection operation is described as follows. For all possible
ordered pairs consisting of one element from list-1 and one element
from list-2, :test or :test-not are used to determine whether they
satisfy the test. The first argument to the :test or :test-not
function is an element of list-1; the second argument is an element of
list-2. If :test or :test-not is not supplied, eql is used. It is an
error if :test and :test-not are supplied in the same function call. …
For every pair that satifies the test, exactly one of the two elements
of the pair will be put in the result. No element from either list
appears in the result that does not satisfy the test for an element
from the other list. If one of the lists contains duplicate elements,
there may be duplication in the result.
So, in the case of (2 2 2 2) and (2 2 2 3), there are 16 pairs to consider:
(2 2) (2 2) (2 2) (2 3) ; first element is first 2 from list-1, second elements are from list-2
(2 2) (2 2) (2 2) (2 3) ; first element is second 2 from list-1, second elements are from list-2
(2 2) (2 2) (2 2) (2 3) ; first element is third 2 from list-1, second elements are from list-2
(2 2) (2 2) (2 2) (2 3) ; first element is fourth 2 from list-1, second elements are from list-2
Since "For every pair that satifies the test, exactly one of the two elements of the pair will be put in the result," it seems to me that you're going to end up with between 3 and 4 2's in the result, because you've got 12 pairs that satisfy the test, and you need to cover each row and column of those 12 pairs. This hinges, I suppose, on the interpretation of "exactly one of the two elements of the pair will be put in the result". In general though, if you have, e.g., lists-as-sets (a1 a2) and (b1 b2 b3) then you have the pairs:
(a1 b1) (a1 b2) (a1 b3)
(a2 b1) (a2 b2) (a2 b3)
I think that the spec should be read as saying that each ai and bi will be included at most once, and that you never include a given ai and bi based on the particular pair (ai bi). So, if from row one you were to select (a1 b2) and include b2 in the result, then the remaining pairs that could contribute elements to the result are
(a1 b1) (a1 b3)
(a2 b1) (a2 b3)
if you had taken a1 from (a1 b2), then the remaining pairs would be
(a2 b1) (a2 b2) (a2 b3)
That is, when you include an element from one of the pairs, you've either removed a row or a column from the table of pairs that determine the possible results. In the first case, you could still add two more elements to the result, but in the second, there could be three.
In fact, in LispWorks, if you reverse the order of the arguments, you'll get the 3 element version:
CL-USER 5 > (intersection '(2 2 2 3) '(2 2 2 2))
(2 2 2)
There is no guarantee that the order of elements in the result will
reflect the ordering of the arguments in any particular way. The
result list may share cells with, or be eq to, either list-1 or list-2
if appropriate.
You didn't mention whether you're just getting an equivalent list back, or if you're actually getting list-1 back. In Lispworks, it seems that you're actually getting the same list back, although that's not required:
CL-USER 2 > (let ((l1 '(2 2 2 2))
(l2 '(2 2 2 3)))
(eq l1 (intersection l1 l2)))
T
Here is mine that works well. I used remove to remove duplicating symbols.
(defun my-intersection (x y)
(cond ((or (null x) (null y)) nil)
((find (first x) y) (cons (first x)
(my-intersection (remove (first x) x) y)))
(t (my-intersection (rest x) y))))

Another way of writing a mimum value procedure in Scheme?

So if i have the following, which returns the smallest value out of a set of four numbers:
(define (minimum2 a b c d)
(cond ((and (< a b) (< a c) (< a d)) a)
((and (< b c) (< b d)) b)
((< c d) c)
(else d)))
But, I want to write it so that I compare a to b and find the smallest value between those two, then compare c and d, and find the smallest value between those, and then compare those two smallest values together to find the actual minimum. If what I wrote was tough to understand, think of it like a tournament bracket, where a "plays" b, and the winner plays the other winner between c and d. Thank you in advance for the help!
Here's one way to do it:
(define (min4 a b c d)
(define (min2 x y)
(if (< x y) x y))
(min2 (min2 a b) (min2 c d)))
Another way to do it, if you don't want to use an internal function:
(define (min4 a b c d)
(let ((min-ab (if (< a b) a b))
(min-cd (if (< c d) c d)))
(if (< min-ab min-cd) min-ab min-cd)))
Here are two ways to do this. I think that the first, using reduce, is much more idiomatic, but it's not doing the tournament style structure, though it uses the same number of comparisons. The second, which does a tournament style structure, is actually just a special case of a generalized merge-sort. The reason that the number of comparisons is the same is that in the tournament style comparison,
min(a,b,c,d) = min(min(a,b),min(c,d))
and in the reduce formulation,
min(a,b,c,d) = min(min(min(a,b),c),d)
Both require three calls the lowest level min procedure.
A reduce based approach
This solution uses a fold (more commonly called reduce in Lisp languages, in my experience). Scheme (R5RS) doesn't include reduce or fold, but it's easy to implement:
(define (reduce function initial-value list)
(if (null? list)
initial-value
(reduce function (function initial-value (car list))
(cdr list))))
A left-associative fold is tail recursive and efficient. Given a binary function f, an initial value i, and a list [x1,…,xn], it returns f(f(…f(f(i, x1), x2)…), xn-1), xn).
In this case, the binary function is min2. R5R5 actually already includes an n-ary (well, it actually requires at least one arguments, it's at-least-one-ary) min, which means min would already work as a binary function, but then again, if you wanted to use the built in min, you'd just do (min a b c d) in the first place. So, for the sake of completeness, here's a min2 that accepts exactly two arguments.
(define (min2 a b)
(if (< a b)
a
b))
Then our n-ary min* is simply a reduction of min2 over an initial value and a list. We can use the . notation in the argument list to make this a variadic function that requires at least one argument. This means that we can do (min* x) => x, in addition to the more typical many-argument calls.
(define (min* a . rest)
(reduce min2 a rest))
For example:
(min* 4 2 1 3)
;=> 1
A true tournament-style solution based on merge sort
A proper tournament style min is actually isomorphic to merge sort. Merge sort recursively splits a list in half (this can be done in place using the indices of the original list, as opposed to actually splitting the list into new lists), until lists of length one are produced. Then adjacent lists are merged to produce lists of length two. Then, adjacent lists of length two are merged to produce lists of length four, and so on, until there is just one sorted list. (The numbers here don't always work out perfectly if the length of the input list isn't a power of two, but the same principle applies.) If you write an implementation of merge sort that takes the merge function as a parameter, then you can have it return the one element list that contains the smaller value.
First, we need a function to split a list into left and right sides:
(define (split lst)
(let loop ((left '())
(right lst)
(len (/ (length lst) 2)))
(if (< len 1)
(list (reverse left) right)
(loop (cons (car right) left)
(cdr right)
(- len 1)))))
> (split '(1 2 3 4))
((1 2) (3 4))
> (split '(1))
(() (1))
> (split '(1 2 3))
((1) (2 3))
Merge sort is now pretty easy to implement:
(define (merge-sort list merge)
(if (or (null? list) (null? (cdr list)))
list
(let* ((sides (split list))
(left (car sides))
(right (cadr sides)))
(merge (merge-sort left merge)
(merge-sort right merge)))))
We still need the merge procedure. Rather than the standard one that takes two lists and returns a list of their sorted elements, we need one that can take two lists, where each has at most one element, and at most one of the lists may be empty. If either list is empty, the non-empty list is returned. If both lists are non-empty, then the one with the smaller element is returned. I've called it min-list.
(define (min-list l1 l2)
(cond
((null? l1) l2)
((null? l2) l1)
(else (if (< (car l1) (car l2))
l1
l2))))
In this case, you can define min* to make a call to merge-sort, where the merge procedure is min-list. Merge-sort will return a list containing one element, so we need car to take that element from the list.
(define (min* a . rest)
(car (merge-sort (cons a rest) min-list)))
(min* 7 2 3 6)
;=> 2

Resources