Remove a sublist from a list in Lisp - recursion

I have a function which adds two polynomials together, however if the sum of two polynomials comes to 0 then that is still being returned in the answer. I need to be able to remove 0 coefficients and their terms from my list.
My polynomials are represented such that 5x^2 is ((5((2 x))))
For example if a polynomial was 2x^2+3y+0x^2 it would look like.
((5 ((2 x)))
(3 ((1 y)))
(0 ((2 x))))
I have some code which identifies if the first list in the list has a 0 coefficient but I am struggling to get it to recurse through the list and remove if the coefficient is 0.
Here is my code:
(defun my-remove(a)
(if(null a)
a
(if(equal (car(car a)) 0)
t
nil)))
At the moment it just returns true if the coefficient of the first list is 0 and false if it isn't.

CL-USER 52 > (remove 0 '((5 ((2 x)))
(3 ((1 y)))
(0 ((2 x))))
:key #'first)
((5 ((2 X))) (3 ((1 Y))))

Related

Generating a list of all possible combinations of true or false for n given variables in LISP

I want to define a function that takes an input "n" (the number of variables) and return all possible truth values. Here, I represent the truth values for a variable i (1 <= i <= n) with +i representing true, and -i representing false.
For example:
(generate-values 2)
should return:
((2 1)(2 -1)(-2 1)(-2 -1))
(generate-values 3)
should return:
((3 2 1)(3 2 -1)(3 -2 1)(3 -2 -1)(-3 2 1)(-3 2 -1)(-3 -2 1)(-3 -2 -1))
Here is my incorrect attempt:
(defun generate-values (n)
(cond
((equal n 0) nil)
(t (list (cons n (generate-values (- n 1)))
(cons (- 0 n) (generate-values (- n 1)))))))
I know why this is incorrect, but I am not able to find a way to generate (3 2 1) and then move on to (3 2 -1). My program outputs:
((3 (2 (1) (-1)) (-2 (1) (-1))) (-3 (2 (1) (-1)) (-2 (1) (-1))))
Any help with this question qould be thoroughly appreciated! Thanks!
It might be easiest to approach this in the easiest way possible, and then to figure out how to make it a bit simpler or more efficient afterward.
If you're doing this recursively, it's important to consider what the bases cases are. A reasonable base case here is probably when n = 0. The function is always supposed to return a list of lists. In the n = 0 case, there are no "variables", so the result has to be a list of the empty list: (()).
For the case that n is anything else, consider what the function returns for n-1. It's a list of all the combinations on n-1 "variables". All you need to do is prepend n to each of those, and prepend -n to each of those, and then make sure you end up with a list of all of those.
Encoding that directly, we end up with something like this:
(defun table (n)
(if (zerop n)
'(())
(let* ((table (table (1- n)))
(plus-pos-n (mapcar (lambda (subtable)
(list* n subtable))
table))
(plus-neg-n (mapcar (lambda (subtable)
(list* (- n) subtable))
table)))
(nconc plus-pos-n plus-neg-n))))
CL-USER> (table 3)
((3 2 1) (3 2 -1) (3 -2 1) (3 -2 -1) (-3 2 1) (-3 2 -1) (-3 -2 1) (-3 -2 -1))
Now, let's look at what your current implementation is doing differently, noting that it doesn't have to be exactly the same algorithm, of course.
(defun generate-values (n)
(cond
((equal n 0)
nil)
(t
(list (cons n
(generate-values (- n 1)))
(cons (- 0 n)
(generate-values (- n 1)))))))
Stylistically, since there are only two branches, I'd prefer if to cond here, but that's not a problem. Before attacking the base case, lets look at the recursive case, when n ≠ 0. First, you're calling generate-values twice; it would be more efficient to call it once and save the result. That could end up being important later if you're calling this function with big values of n, but it doesn't make the function incorrect. But remember what generate-values returns; it returns a list of the different combinations. That means that your call to (cons n (generate-values …)) is returning a list whose first element is n, and whose remaining elements are the combinations for n-1. E.g., you're doing something like:
CL-USER> (table 1)
((1) (-1))
CL-USER> (cons 2 (table 1))
(2 (1) (-1))
But that's not what you want. You really want to add n to each of those lists:
CL-USER> (mapcar (lambda (x)
(cons 2 x))
(table 1))
((2 1) (2 -1))
That's the issue in the recursive case. There's an issue in the base case, too. In the recursive case, you want to add n and -n to each of the sublists from the n-1 case. So what happens when you have n = 1? You want to be getting (cons 1 '()) and (cons -1 '()). But since the second argument to cons is going to be each list inside of the result of (generate-values 0), you really need to have something in the list returned by (generate-values 0). What needs to be there? The empty list needs to be there. So the base case needs to return (()), not (). So, after making those changes, your code would be:
(defun generate-values (n)
(cond
((equal n 0)
'(()))
(t
(list (mapcar (lambda (x)
(cons n x))
(generate-values (- n 1)))
(mapcar (lambda (x)
(cons (- 0 n) x))
(generate-values (- n 1)))))))
CL-USER> (generate-values 3)
(((3 (2 (1)) (2 (-1))) (3 (-2 (1)) (-2 (-1))))
((-3 (2 (1)) (2 (-1))) (-3 (-2 (1)) (-2 (-1)))))
That's closer, but it's still not quite right. There's another in the recursive case. You end up generating the values that have n in the beginning (a list of them), and the values that have -n in the beginning (a list of them), but then you're using list to combine them. That returns a single list with two values. Instead, you want a single list that has the values from each of them. You want to combine them with append (or, since all the structure is newly generated, you could use nconc):
(defun generate-values (n)
(cond
((equal n 0)
'(()))
(t
(append (mapcar (lambda (x)
(cons n x))
(generate-values (- n 1)))
(mapcar (lambda (x)
(cons (- 0 n) x))
(generate-values (- n 1)))))))
CL-USER> (generate-values 3)
((3 2 1) (3 2 -1) (3 -2 1) (3 -2 -1) (-3 2 1) (-3 2 -1) (-3 -2 1) (-3 -2 -1))
This final implementation isn't exactly what I started with, but it's essentially the same in terms of the algorithm. The differences are mostly stylistic, but there are some efficiency concerns, too. Using nconc instead of append would save some memory, and it really would be good to cache the results from the recursive call, rather than recomputing it. Stylistic issues that don't affect correctness might be using if instead of cond, using list* instead of cons (to indicate that we're working with lists, not trees of cons cells), and it's nice to note that you don't have to do (- 0 n), - with a single argument returns the argument's negation. That is, (- n) = -n.

Common Lisp permutation pairs without identical values

I'm trying to make a function that, given a list, will return a list of pairs of elements where the two elements are not equal. For example, given the list (1 2 3) it would return ((1 2) (1 3) (2 1) (2 3) (3 1) (3 2)). The code I have now works, but it adds nil to each spot where it would have matching numbers; (1 1) for example.
(defun make-permutations-without-identical(list)
(loop for x in list
append (loop for y in list
collect (append (if (not (equal x y)) (list x y))))))
This code, given (1 2 3) returns (NIL (1 2) (1 3) (2 1) NIL (2 3) (3 1) (3 2) NIL). How do I get rid of the NIL's?
Since the lists generated by the inner loop are fresh, you can nconc them. The loop macro has unless part so that you can conditionally collect parts. Thus you can just collect except when (equal x y):
CL-USER> (loop for x in '(1 2 3)
nconcing (loop for y in '(1 2 3)
unless (equal x y)
collect (list x y)))
((1 2) (1 3) (2 1) (2 3) (3 1) (3 2))
If you don't want to see NIL in the result list, just don't collect NILs. Collect only the items you want to be in the result list.

Scheme: given a list of lists and a permutation, permute

I am practicing for my programming paradigms exam and working through problem sets I come to this problem. This is the first problem after reversing and joining lists recursively, so I suppose there is an elegant recursive solution.
I am given a list of lists and a permutation. I should permute every list including a list of lists with that specified permutation.
I am given an example:
->(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
->((1 3 2) (5 7 6) (a c b))
I have no idea even how to start. I need to formulate the problem in recursive interpretation to be able to solve it, but I can not figure out how.
Well, let's see how we can break this problem down. We are given a list of lists, and a list of numbers, and we want to order each list according to the order specified by the list of numbers:
=>(permute '((1 2 3) (4 5 6)) '(3 2 1))
'((3 2 1) (6 5 4))
We can see that each list in the list of lists can be handled separately, their solutions are unrelated to each other. So we can have a helper permute1 that handles the case of one list, then use map to apply this function to each of the lists (with the same ordering each time):
(define (permute lists ordering)
(map (lambda (xs) (permute1 xs ordering))
lists))
(define (permute1 items ordering)
...)
Now, to calculate (permute1 '(4 5 6) '(3 2 1)), what we mean is:
The first item of the new list will be the 3rd item of items, because the first number in ordering is 3.
The rest of the items of the new list will be determined by using the rest of the numbers in the ordering.
If the ordering is the empty list, return the empty list.
This forms the base case (3), the recursive case (1), and the steps to recur deeper (2). So a sketch of our solution would look like:
(define (permute1 items ordering)
(if (empty? ordering)
'()
(let ([next-item ???])
(??? next-item
(permute1 items (rest ordering))))))
Where the ???s represent getting the item based on the first number in ordering and combining this item with the remainder of the calculation, respectively.
Here's another option, using higher-order functions. This is the idiomatic way to think about a solution in a functional language - we split the problem in sub-problems, solve each one using existing procedures and finally we compose the answer:
(define (atom? x)
(and (not (null? x))
(not (pair? x))))
(define (perm lst order)
(foldr (lambda (idx acc)
(cons (list-ref lst (sub1 idx)) acc))
'()
order))
(define (permute lst order)
(if (atom? lst)
lst
(perm (map (lambda (x) (permute x order)) lst)
order)))
We start by defining atom?, a generic predicate and perm, a helper that will reorder any given list according to the ordering specified in one of its parameters. It uses foldr to build the output list and list-ref to access elements in a list, given its 0-based indexes (that's why we subtract one from each index).
The main permute function takes care of (recursively) mapping perm on each element of an arbitrarily nested input list, so we can obtain the desired result:
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
=> '((1 3 2) (5 7 6) (a c b))
I am given an example:
(permute ('(1 2 3) '(a b c) '(5 6 7)) '(1 3 2))
((1 3 2) (5 7 6) (a c b))
The syntax you've given isn't correct, and will cause an error, but it's fairly clear what you mean. You want that
(permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
;=> ((1 3 2) (5 7 6) (a c b))
Now, it's not clear how you're indicating the permutation. Is '(1 3 2) a permutation because it has some (1-based) indices, and indicates the way to rearrange elements, or is it because it is actually a permutation of the elements of the first list of the first list? E.g., would
(permute '((x y z) (a b c) (5 6 7)) '(1 3 2))
;=> ((x z y) (5 7 6) (a c b))
work too? I'm going to assume that it would, because it will make the problem much easier.
I have no idea even how to start. I need to formulate the problem in
recursive interpretation to be able to solve it, but I can not figure
out how.
You need to write a function that can take a list of indices, and that returns a function that will perform the permutation. E.g,.
(define (make-permutation indices)
…)
such that
((make-permutation '(3 1 2)) '(a b c))
;=> (c a b)
One you have that, it sounds like your permute function is pretty simple:
(define (permute lists indices)
(let ((p (make-permutation indices)))
(p (map p lists))))
That would handle the case you've given in your example, since (map p lists) will return ((1 3 2) (a b c) (5 7 6)), and then calling p with that will return ((1 3 2) (5 7 6) (a c b)). If you need to be able to handle more deeply nested lists, you'll need to implement a recursive mapping function.
Here's my take, which seems to be shorter than the previous examples:
(define (permute lst ord)
(define ord-1 (map sub1 ord)) ; change from 1-based to 0-based indexes
(define (perm elts) ; recursive sub-procedure
(if (list? elts)
(map perm (map (curry list-ref elts) ord-1)) ; list -> recurse
elts)) ; else return unchanged
(perm lst)) ; initial call
testing
> (permute '((1 2 3) (a b c) (5 6 7)) '(1 3 2))
'((1 3 2) (5 7 6) (a c b))
> (permute '((1 (i permute did) 3) (a b (scheme cool is)) (5 6 7)) '(1 3 2))
'((1 3 (i did permute)) (5 7 6) (a (scheme is cool) b))

Processing pairs of successive elements in a list with standard mapping functions?

I have a small exercise in Lisp:
Write a function test-delta with parameters delta and lst, which will
check if the difference between successive elements in lst is smaller than
delta. Write the function in two ways:
recursively
using a mapping function
I have no problem writing that function recursively, but I don't know which mapping function I should use. All the standard mapping functions work with only one element of the list at a time. reduce cannot be used either, because I do not have some operation to use between successive elements. What function could I use here?
All standard functions are working only with one element at time.
Reduce function cannot be use either
because i do not have some operation to use between to elements.
There's already an answer by uselpa showing that you can do this with reduce, but it feels a bit awkward to me to bend reduce to this case.
It's much more natural, in my opinion, to recognize that the standard mapping functions actually let you work with multiple lists. I'll show mapcar and loop first, and then every, which I think is the real winner here. Finally, just for completeness, I've also included maplist.
mapcar
The standard mapcar can take more than one list, which means that you can take elements from two different lists at once. Of particular note, it could take a list and (rest list). E.g.,
(let ((list '(1 2 3 4 5 6)))
(mapcar 'cons
list
(rest list)))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
loop
You can use loop to do the same sort of thing:
(loop
with l = '(1 2 3 4 5 6)
for a in l
for b in (rest l)
collect (cons a b))
;=> ((1 . 2) (2 . 3) (3 . 4) (4 . 5) (5 . 6))
There are some other variations on loop that you can use, but some of them have less conventient results. E.g., you could loop for (a b) on list, but then you get a (perhaps) unexpected final binding of your variables:
(loop for (a b) on '(1 2 3 4 5 6)
collect (list a b))
;=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 NIL))
This is similar to what maplist will give you.
every
I think the real winners here, though, are going to the be every, some, notevery, and notany functions. These, like mapcar can take more than one list as an argument. This means that your problem can simply be:
(let ((delta 4)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> T
(let ((delta 2)
(lst '(1 2 4 7 9)))
(every (lambda (x y)
(< (abs (- x y)) delta))
lst
(rest lst)))
;=> NIL
maplist
You could also do this with maplist, which works on successive tails of the list, which means you'd have access to each element and the one following. This has the same 6 NIL at the end that the second loop solution did, though. E.g.:
(maplist (lambda (tail)
(list (first tail)
(second tail)))
'(1 2 3 4 5 6))
;=> ((1 2) (2 3) (3 4) (4 5) (5 6) (6 NIL))
reduce can be used:
(defun testdelta (delta lst)
(reduce
(lambda (r e)
(if (< (abs (- r e)) delta)
e
(return-from testdelta nil)))
lst)
t)
or, without return-from (but possibly slower):
(defun testdelta (delta lst)
(and
(reduce
(lambda (r e)
(and r (if (< (abs (- r e)) delta) e nil)))
lst)
t))

Pascal's Triangle Row Sequence

I'm currently working on finding the row sequences of Pascal's triangle. I wanted to input the row number and output the sequence of numbers in a list up until that row. For example, (Pascal 4) would give the result (1 1 1 1 2 1 1 3 3 1).
I am trying to use an algorithm that I found. Here is the algorithm itself:
Vc = Vc-1 * ((r - c)/c)
r and c are supposed to be row and column, and V0=1. The algorithm can be specifically found on the wikipedia page in the section titled "Calculating and Individual Row or Diagonal."
Here is the code that I have so far:
(define pascal n)
(cond((zero? n) '())
((positive? n) (* pascal (- n 1) (/ (- n c)c))))
I know that's hardly anything but I've been struggling a lot on trying to find scoping the function with a let or a lambda to incorporate column values. Additionally, I've also been struggling on the recursion. I don't really know how to establish the base case and how to get to the next step. Basically, I've been getting pretty lost everywhere. I know this isn't showing much, but any step in the right direction would be greatly appreciated.
Using as a guide the entry in Wikipedia, this is a straightforward implementation of the algorithm for calculating a value in the Pascal Triangle given its row and column, as described in the link:
#lang racket
(define (pascal row column)
(define (aux r c)
(if (zero? c)
1
(* (/ (- r c) c)
(aux r (sub1 c)))))
(aux (add1 row) column))
For example, the following will return the first four rows of values, noticing that both rows and columns start with zero:
(pascal 0 0)
(pascal 1 0)
(pascal 1 1)
(pascal 2 0)
(pascal 2 1)
(pascal 2 2)
(pascal 3 0)
(pascal 3 1)
(pascal 3 2)
(pascal 3 3)
Now we need a procedure to stick together all the values up until the desired row; this works for Racket:
(define (pascal-up-to-row n)
(for*/list ((i (in-range n))
(j (in-range (add1 i))))
(pascal i j)))
The result is as expected:
(pascal-up-to-row 4)
> '(1 1 1 1 2 1 1 3 3 1)
I discussed Pascal's Triangle at my blog.
In your question, the expression for Vc is just for one row. That translates to code like this:
(define (row r)
(let loop ((c 1) (row (list 1)))
(if (= r c)
row
(loop (+ c 1) (cons (* (car row) (- r c) (/ c)) row)))))
Then you just put together a bunch of rows to make the triangle:
(define (rows r)
(let loop ((r r) (rows (list)))
(if (zero? r)
rows
(loop (- r 1) (append (row r) rows)))))
And here's the output:
> (rows 4)
(1 1 1 1 2 1 1 3 3 1)
The base case is (= r c) in the first function and (zero? r) in the second.
If you want to write subscripts clearly, you can adopt the notation used by TeX: subscripts are introduced by an underscore and superscripts by a caret, with braces around anything bigger than one character. Thus Vc in your notation would be V_c, and Vc-1 in your notation would be V_{c-1}.

Resources