Racket - Applying a Boolean to a list of lists - recursion

I have a function that utilizes a Boolean to replace the first number in a list with 1, regardless of its value:
f({(0, 1, 0), (0, 0, 1), (1, 0, 0), ...}) = {(1, 1, 0), (1, 0, 1), (1, 0, 0), ...}
So far I have
(define (procB set)
(map (λ (lst1) ((number? (first lst1)) (cons 1 (rest lst1)))) set))
The trouble is when the function is applied to the remaining parts of the set. I get the standard error
application: not a procedure;
expected a procedure that can be applied to arguments
given: #t
I get that it isn't working because there is a Boolean (given: #t), but I am not quite sure how to fix it.

You should use an if expression to test if the first value is a number - and if it is not, what should we do? we could leave it alone. Also you seem to have a couple of misplaced parentheses, this should fix the bugs:
(define (procB set)
(map (λ (lst1)
(if (number? (first lst1))
(cons 1 (rest lst1))
lst1))
set))
Now it works as expected:
(procB '((0 1 0) (0 0 1) (1 0 0)))
=> '((1 1 0) (1 0 1) (1 0 0))
Just to be sure... if the sublists can only contain numbers, then the if expression is superfluous, all you have to do inside the lambda is (cons 1 (rest lst1)).

It looks to me like you're missing an if. In your lambda in the map, (number? (first lst1)) will resolve to #t. It will then try to apply the procedure #t to (cons 1 (rest lst1)) which gives you the error you're seeing. I suspect you want your lambda to be closer to
(lambda (lst1)
(if (number? (first lst1))
; then cons 1 with the rest
; else don't replace with a 1

Related

Common Lisp Returning members of a list from one index to another

This is what ive tried till now, but im getting some errors and im kinda confused
What is want to do is:
For example calling (sub-list((2 3 4 5 6) 2 3))
will result in a recursive function like
x = 1,(sub-list('(3 4 5 6) 2 3))
x = 2, cons (car ls) (sub-list((4 5 6) 2 3))
x = 3 ,cons (car ls) (sub-list((5 6) 2 3))
x = 4 , nil since x is now greater than to.
and it should backtrack to return (4 5) something like that
(defvar *x* 1)
(defun sub-list(ls from to)
(cond
((<= *x* from) (sub-list((cdr ls) from to)))
((<= from *x* to)
(let (*x* (+ *x* 1))
cons a (sub-list((cdr ls) from to)))))
((> *x* to) nil)))
As a general recommendation, using a global and special variable to track internal state is not recommended.
As #coredump pointed out in a comment, Sublist in Lisp has an answer pointing in the right direction.
To avoid the special variable, you can (in principle) change the start and end index (as pointed out by #ScottHunter).
This means that you can change your "start accumulating" from (<= *x* from) to (<= from 0) and your "end accumulating" to (<= to 0).
This also requires changing each recursive call to be something like (sub-list (cdr list) (1- from) (1- to)) (and gets rid of the bug in the initial skip phase, where you are not incrementing *x*).

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.

Recursively adding to list returns null

I want to take a list of smaller lists and add a copy of the first element of each small list to the end of each small list. If that didn't make any sense, I'll give you an example:
f({(0, 0, 1), (1, 0, 0), (0, 1, 0), ...}) = {(0, 0, 1, 0), (1, 0, 0, 1), (0, 1, 0, 0), ...}
This is what I've got so far:
(define (add-end n set)
(cond
((null? set) '())
(cons (append (first set) (first (first set)))
(add-end n (rest set)))))
This keeps giving me a null result, and I don't exactly know why.
Your code fails because you forgot the else part in the cond expression, also the way you're appending a single element to the end of a list is incorrect. This should fix the problems:
(define (add-end set)
(cond ((null? set)
'())
(else
(cons (append (first set) (list (first (first set))))
(add-end (rest set))))))
But wait, there's a simpler solution if we use existing procedures:
(define (add-end set)
(map (lambda (lst)
(append lst (list (first lst))))
set))
Explanation:
We don't need an n parameter - for processing a list, we rarely have to know its length in advance
Notice that we have to process each element of the input list to create a new output list, using map is the way to go in these cases
Now it's a simple matter of appending the first element of each list
To build a proper list, remember that append requires that both of its arguments are lists, that explains the bit with the (list (first lst))
Either way, it works as expected:
(add-end '((0 0 1) (1 0 0) (0 1 0)))
=> '((0 0 1 0) (1 0 0 1) (0 1 0 0))

Position in list scheme

I'm not sure how to do this and couldn't find an example of it anywhere. How do I find the position of a value in a list. For example I have a (define findValue x lst) which accepts a value and list and from that list I want type in (findValue 3 '(1 2 0 8 5 6)) and it should return 0 since the value in position 3 is 0. From my understanding and how it usually is position 3 would be 8 and not 0 in arrays at least. How does it work in here and how do I approach this problem?
Thanks!
Try:
(define (at n xs)
(cond ((null? xs) xs)
((= n 1) (car xs))
(else (at (- n 1) (cdr xs)))))
Use it as follows:
(at 3 '(1 2 0 8 5 6)) => 0
For zero-based indexing change the (= n 1) check on the 3rd line to (= n 0).
Edit: So you want to partially apply the at function? All you need is curry and flip. They are defined as follows:
(define (curry func . args)
(lambda x (apply func (append args x))))
(define (flip func)
(lambda (a b) (func b a)))
Using curry and flip you can now partially apply at as follows:
(define position (curry (flip at) '(1 2 0 8 5 6)))
You can now use position as follows:
(position 3) => 0
(position 4) => 8
Hope that helped.
Usually indexes are counted starting from 0, and your understanding is correct. But if you're required to implement a findValue procedure that starts counting indexes from 1, it's not that hard to write the procedure:
(define (findValue idx lst)
(cond ((or (null? lst) (negative? idx)) #f)
((= idx 1) (car lst))
(else (findValue (sub1 idx) (cdr lst)))))
Explanation:
If the list received as parameter is empty or the index becomes negative, we treat that as a special case and return #f to indicate that the value was not found
If the index is 1 then we're right where we wanted, so it's time to return the current element
Otherwise advance the recursion: subtract one from the index and advance one position over the list
It works as expected:
(findValue 3 '(1 2 0 8 5 6))
=> 0
(findValue -1 '(1 2 0 8 5 6))
=> #f
(findValue 7 '(1 2 0 8 5 6))
=> #f

"application: not a procedure" in binary arithmetic procedures

I have a simple Racket definition for multiplying binary numbers together. It uses a well-tested "addWithCarry" definition that takes three parameters: two lists and a carry digit and returns the binary sum. The binary numbers are represented as lists in reverse order.
I stepped through the test line with the debugger, and it goes through the recursion properly. It performs the multBins each time shrinking the y list as appropriate, then conducts the addWithCarry functions as expected. As it rises back up the stack, it suddenly throws an exception "application: not a procedure, expected a procedure that can be applied to arguments" with the parameter '(0 0 0 1 0 1 1) which is the value of the highest "x" added to the total. I know this error can occur when you are attempting to apply the result of a function as a function with a parameter, but I don't see this here. Watching the debugger, everything seems to be working perfectly until the very end. Any ideas?
(define (multBins x y)
(cond
((null? y) '() )
((= (first y) 0) ((multBins (cons 0 x) (rest y))))
(#t ((addWithCarry x (multBins (cons 0 x) (rest y)) 0)))))
(test (multBins '(1 0 1 1)'(1 1 0 1))'(1 1 1 1 0 0 0 1))
Here is the addWithCarry definition:
(define (addWithCarry x y carry)
(cond
((and (null? x)(null? y)) (if (= carry 0) '() '(1)))
((null? x) (addWithCarry '(0) y carry))
((null? y) (addWithCarry x '(0) carry))
( #t (let ((bit1 (first x))
(bit2 (first y)))
(cond
((= (+ bit1 bit2 carry) 0) (cons 0 (addWithCarry (rest x) (rest y) 0)))
((= (+ bit1 bit2 carry) 1) (cons 1 (addWithCarry (rest x) (rest y) 0)))
((= (+ bit1 bit2 carry) 2) (cons 0 (addWithCarry (rest x) (rest y) 1)))
( #t (cons 1 (addWithCarry (rest x) (rest y) 1))))))))
In this line, you're calling multBins with (cons 0 x) and (rest y), and getting some result r, and then trying to call r:
((= (first y) 0) ((multBins (cons 0 x) (rest y))))
; ^ ^
; +--- function application -----+
The same kind of thing is happening in the next line, where you're calling addWithCarry with some arguments, getting a result r, and trying to call r:
(#t ((addWithCarry x (multBins (cons 0 x) (rest y)) 0)))))
; ^ ^
; +-------------- function application -------------+
Presumable the unapplicable value '(0 0 0 1 0 1 1) is being returned by one of these.
In a very simplified case, consider this transcript from the DrRacket REPL:
> (define (value) ; a function that returns the
'(0 0 0 1 0 1 1)) ; same value that yours should
> (value) ; calling it produces the value
(0 0 0 1 0 1 1)
> ((value)) ; calling it and then calling
; return value causes the same
; error that you're seeing
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: (0 0 0 1 0 1 1)
; arguments...: [none]
You didn't mention what editor/IDE/debugger you're using, but some should have made this a bit easier to spot. For instance, when I load your code (minus the call to test, whose definition I don't have, and with definitions of first and rest), DrRacket highlights the location of the offending call:
While both of the problematic calls that I've pointed out need to be fixed, the error that you're seeing right now is occurring in the second of the two.

Resources