Dr.Racket, cons: expect 2 argument, but found 3 - functional-programming

I have this function along with some other functions, but when I run it, dr.racket says:
cons: expect 2 argument, but found 3
I can't figure out where I got the cons incorrect, can someone help me?
;; Component -> ListOfCode
;; produce a list of codes of all parts required to build the given component
;; if a part appears twice, the code of the bar should also appear twice
(check-expect (list-code C0) (cons "000000" (cons "111000" (cons "222000" empty))))
(check-expect (list-code C1) (cons "000000" (cons "111000" (cons "111000" (cons 444000 empty)))))
(check-expect (list-code C3) (cons "000000" (cons "111000" (cons "555000" (cons "666000" (cons "666000" (cons "000000" (cons "111000" (cons "222000" (cons "000000" (cons "111000" (cons "111000" (cons 444000 empty)))))))))))))
;(define (list-code c) loc)
(define (list-code c)
(cons (find-codes-loc (component-loc c)) ;fn-for-loc
(get-code-lop (component-lop c)) ;fn-for-lop
empty))

Here:
(define (list-code c)
(cons (find-codes-loc (component-loc c)) -- argument 1
(get-code-lop (component-lop c)) -- argument 2
empty)) -- argument 3

Related

Return the longest sequence of consecutive numbers from list in lisp

I am a lisp newbie.
I'm trying to create a function in lisp that receives an unsorted list and the function has to sort de list and return a list with the longest sequence of numbers.
Example: (2 1 8 9 3 11 10 20 12 21)(1 2 3 8 9 10 11 12 20 21) -> return (8 9 10 11 12)
I don't want to use the sort function and I have created 2 functions (With some help) to sort, but now I have no idea how I could find and return the longest sequence of numbers.
I could go through the list but, how I can store the numbers and check if a list of consecutive numbers is longer than another?
This are my functions to sort
(defun sortOne (list)
(let ((ca1 (car list)) (cd1 (cdr list)))
(if (null cd1)
list
(let ((cd (sortOne cd1))) ; cd = sorted tail
(let ((ca2 (car cd)) (cd2 (cdr cd)))
(if (<= ca1 ca2)
(cons ca1 cd)
(cons ca2 (cons ca1 cd2))))))))
(defun sortAll (list)
(if (null list)
nil
(let ((s (sortOne list)))
(cons (car s) (sortAll (cdr s))))))
Hope someone can help me.
¡Thanks!
Tonight I managed to do it, but surely it is not the best solution, I would like to know how to use a lambda function or recursion to do it better.
(defun listilla (lista)
(setq lista (sort lista #'<))
(setq lista1 (list (car lista)))
(setq lista2 '())
(loop for i from 0 to (- (length lista) 2) do
(cond ((= (nth i lista) (- (nth (+ i 1) lista) 1))
(push (nth (+ i 1) lista) (cdr (last lista1))))
(t (push lista1 lista2)
(setq lista1 (list (nth (+ i 1) lista)))
)
)
)
(push lista1 lista2)
(setq masLargo (car lista2))
(loop for i from 1 to (- (length lista2) 2) do
(if (< (length (nth i lista2)) (length (nth (+ i 1) lista2)))
(setq masLargo (nth (+ i 1) lista2))
)
)
masLargo
)
(print (listilla '(23 15 6 5 78 4 77)))
(defun group-consecutives (l &optional (acc '()))
(cond ((null l) (nreverse acc))
((and acc (= 1 (- (car l) (caar acc)))) (consecutives (cdr l) (cons (cons (car l) (car acc)) (cdr acc))))
(t (consecutives (cdr l) (cons (list (car l)) (when acc (cons (nreverse (car acc)) (cdr acc))))))))
(defun longest-consecutive (l)
(car (sort (consecutives (sort l #'<)) #'> :key #'length)))
(longest-consecutive '(2 1 8 9 3 11 10 20 12 21))
;;=> (8 9 10 11 12)
Probably the second function is easier to understand like this:
(defun sort-increasing (l)
(sort l #'<))
(defun sort-groups-by-length (groups)
(sort groups #'> #'length))
(defun longest-consecutive (l)
(car (sort-groups-by-length (group-consecutives (sort-increasing l))))))))

Scheme - Recursive cases

I'm finishing up a Scheme assignment and I'm having some trouble with the recursive cases for two functions.
The first function is a running-sums function which takes in a list and returns a list of the running sums i.e (summer '(1 2 3)) ---> (1 3 6) Now I believe I'm very close but can't quite figure out how to fix my case. Currently I have
(define (summer L)
(cond ((null? L) '())
((null? (cdr L)) '())
(else (cons (car L) (+ (car L) (cadr L))))))
I know I need to recursively call summer, but I'm confused on how to put the recursive call in there.
Secondly, I'm writing a function which counts the occurrences of an element in a list. This function works fine through using a helper function but it creates duplicate pairs.
(define (counts L)
(cond ((null? L) '())
(else (cons (cons (car L) (countEle L (car L))) (counts (cdr L))))))
(define (countEle L x)
(if (null? L) 0
(if (eq? x (car L)) (+ 1 (countEle (cdr L) x)) (countEle (cdr L) x))))
The expected output is:
(counts '(a b c c b b)) --> '((a 1) (b 3) ( c 2))
But it's currently returning '((a . 1) (b . 3) (c . 2) (c . 1) (b . 2) (b . 1)). So it's close; I'm just not sure how to handle checking if I've already counted the element.
Any help is appreciated, thank you!
To have a running sum, you need in some way to keep track of the last sum. So some procedure should have two arguments: the rest of the list to sum (which may be the whole list) and the sum so far.
(define (running-sum L)
(define (rs l s)
...)
(rs L 0))
For the second procedure you want to do something like
(define (count-elems L)
(define (remove-elem e L) ...)
(define (count-single e L) ...)
(if (null? L)
'()
(let ((this-element (car L)))
(cons (list this-element (count-single this-element L))
(count-elems (remove-elem this-element (cdr L)))))))
Be sure to remove the elements you've counted before continuing! I think you can fill in the rest.
To your first problem:
The mistake in your procedure is, that there is no recursive call of "summer". Have a look at the last line.
(else (cons (car L) (+ (car L) (cadr L))))))
Here is the complete solution:
(define (summer LL)
(define (loop sum LL)
(if (null? LL)
'()
(cons (+ sum (car LL)) (loop (+ sum (car ll)) (cdr LL)))))
(loop 0 LL))

Create list such that the min is separated from the list recursively in scheme?

i need to create a list such that the min is always at the outside in a list.
Example
input (1 2 3)
output (1 (2 3))
Here is my code, assuming that the numbers are in descending order, which i wish to extent later to a general case.
I am getting an unexpected output of (3 2 1 0 -1 -2 -3 ()).
How do I achieve this in scheme any ideas?'
(define (find-min-rest L)
(if (null? (cdr L)) (let ( (x (car L))) (cons x '( ())))
(let* ((ret-ans (find-min-rest (cdr L))) (cur-elem (car L)) (mini (car ret-ans)) (rem-list (cdr ret-ans)))
(cond ((> cur-elem mini) (cons cur-elem (cons mini rem-list)))))))
It'll be simpler if you use built-in procedures, and split the problem in parts. Notice that the following assumes that there's a single minimum, adjust as necessary:
(define (find-min-rest L)
(let* ((the-min (apply min L))
(the-rest (remove the-min L)))
(list the-min the-rest)))
(find-min-rest '(1 2 3))
=> '(1 (2 3))
The code
(define (find-min-rest L)
(if (null? (cdr L)) (let ( (x (car L))) (cons x '( ())))
(let* ((ret-ans (find-min-rest (cdr L))) (cur-elem (car L)) (mini (car ret-ans)) (rem-list (cdr ret-ans)))
(cond ((> cur-elem mini) (cons cur-elem (cons mini rem-list)))))))

Scheme List of lists zipping

If my input is a list of lists, then I want to output a list with elements from the input so that they are shuffled like a deck of playing cards.
For example, if input is '((1 2 3) (4 5)) then I want output to show up as '(1 4 2 5 3).
My idea is to first remove an element from the first list inside of a list, and then move that list of a list to the back of the list. This way, the first element of the next list of a list can then be appended.
Here is my code so far:
(define (shuffle ls)
(if (null? ls) '()
(cond ((null? car (ls)) (append (cdr (ls)) (list (cdr(car(ls)))))))
(else (car (car (ls)))
(append (cdr (ls)) (list (cdr (car (ls))))
(shuffle (cdr (ls)))))))
[All the code snippets here require SRFI 1 to be loaded first.]
What you seem to be wanting is to zip the lists:
> (zip '(1 2 3) '(4 5))
((1 4) (2 5))
However, as you can see, this stops when it gets to the end of the shortest list. Maybe you can write a custom zip that will stop after all elements are exhausted:
(define (my-zip l1 l2)
(cond ((and (null? l1) (null? l2)) '())
((null? l1) (cons (car l2) (my-zip l1 (cdr l2))))
((null? l2) (cons (car l1) (my-zip (cdr l1) l2)))
(else (cons* (car l1) (car l2) (my-zip (cdr l1) (cdr l2))))))
Let's try it out!
> (my-zip '(1 2 3) '(4 5))
(1 4 2 5 3)
> (my-zip '(1 2 3) '(4 5 6 7))
(1 4 2 5 3 6 7)
this would work too... i use chicken scheme so i have to "import" filter from srfi-1.
(use srfi-1)
(define *deck* '((1 2 3 4) (5 6 7) (9 10 11 12)))
(define nullcar?
(lambda (x)
(if (not (null? x))
(null? (car x)))))
(define nullcdr?
(lambda (x)
(if (not (null? x))
(null? (cdr x)))))
(define notnulls
(lambda (x)
(filter (lambda (e)
(not (null? e)))
x)))
(define firsts
(lambda (l)
(if (not (null? l))
(map (lambda (x)
(if (not (null? x))
(car x)
'()))
l))))
(define shuf
(lambda (d)
(notnulls
(append (firsts d)
(if (not (nullcar? d))
(if (not (nullcdr? d))
(shuf (map cdr (notnulls d)))
'())
'())))))
cheers!

homework on scheme

how to design a function content which
inputs a single list of atoms lat and which returns
the content of lat.Thus the content of '(a b c a b c d d) is '(a b c d).
The procedure content below should get you what you need.
(define (work x y)
(if (null? (cdr x))
(if (in? (car x) y)
y
(cons (car x) y))
(if (in? (car x) y)
(work (cdr x) y)
(work (cdr x) (cons (car x) y)))))
(define (in? x y)
(if (null? y)
#f
(if (equal? x (car y))
#t
(in? x (cdr y)))))
(define (content x) (work x (list)))
The procedure content accepts a list as a parameter. It sends the list to another procedure called work. This procedure processes the list and adds the items in the list to a new list (if they are not already in the new list). The work procedure makes use of yet another procedure called in, which checks to see if an item is a member of a list.
My solution essentially divides your problem into two sub-problems and makes use of procedures which operate at a lower level of abstraction than your original problem.
Hope that helps.
It is PLT Scheme solution:
(define (is_exists list element)
(cond
[(empty? list) false]
[else
(cond
[(= (first list) element) true]
[else (is_exists (rest list) element)])]))
(define (unique list target)
(cond
[(empty? list) target]
[else
(cond
[(is_exists target (first list)) (unique (rest list) target)]
[else (unique (rest list) (cons (first list) target))])]))
(define (create_unique list)
(unique list empty))
Check it:
> (define my_list (cons '1 (cons '2 (cons '3 (cons '2 (cons '1 empty))))))
> my_list
(list 1 2 3 2 1)
> (create_unique my_list)
(list 3 2 1)
How about little schemer style,
(define (rember-all a lat)
(cond
((null? lat) '())
((eq? a (car lat)) (rember-all a (cdr lat)))
(else (cons (car lat) (rember-all a (cdr lat))))))
(define (content lat)
(cond
((null? lat) '())
(else (cons (car lat)
(content (rember-all (car lat) (cdr lat)))))))
Start from a procedure that simply creates a copy of the passed-in list (very easy to do):
(define (unique-elements seq)
(define (loop ans rest)
(cond ((null? rest) ans)
(else
(loop (cons (car rest) ans)
(cdr rest)))))
(loop '() seq))
To ensure that the output list's elements are unique, we should skip the CONS if the head of REST is already a member of ANS. So we add another condition to do just that:
;;; Create list containing elements of SEQ, discarding duplicates.
(define (unique-elements seq)
(define (loop ans rest)
(cond ((null? rest) ans)
((member (car rest) ans) ; *new*
(loop ans (cdr rest))) ; *new*
(else
(loop (cons (car rest) ans)
(cdr rest)))))
(loop '() seq))
The following function takes in a list and returns a new list with only the unique inputs of it's argument using recursion:
(defun uniq (list)
(labels ((next (lst new)
(if (null lst)
new
(if (member (car lst) new)
(next (cdr lst) new)
(next (cdr lst) (cons (car lst) new))))))
(next list ())))
As was mentioned in the comments, common lisp already has this function:
(defun uniq (list)
(remove-duplicates list))
(define (remove-duplicates aloc)
(cond
((empty? aloc) '())
(else (cons (first aloc)
(remove-duplicates
(filter (lambda (x)
(cond
((eq? x (first aloc)) #f)
(else #t)))
(rest aloc)))))))

Resources