"pair required" error when trying to count how many times the first number is repeated in a list of lists with Scheme - recursion

I am trying to count how many times the first number of the list of list called one, two or three is repeated, the idea of the code that I made is for example to choose the list of list called "one" and then take the first letter that has "a" inside and then compare in this case the first value that would be "10" with the others in this list , in this case I should get it to say that the "10" was repeated once, then it would continue with the other two "b" and "c", but when doing the following code
(define a (list 10 2 3 54 6 9 7 10))
(define b (list 5 1 8 6 5 5 4 77 8 6))
(define c (list 80 80 80))
(define e (list 99 156 54 48 99))
(define d (list 16 94 75 30 56 16 8 16))
(define one (list a b c))
(define two (list c e b a))
(define three (list b c d e))
; receives 'one', 'two' or 'three' and finds how many times the first number of the list is repeated in the list of lists
(define (find-repeated-number list)
(define (find-repeated-number-helper list)
(if (null? list)
0
(if (equal? (car list) (car (cdr list)))
(+ 1 (find-repeated-number-helper (cdr list)))
; displays the number of times the first number of the list is repeated in the list of lists
(find-repeated-number-helper (cdr list)))))
(find-repeated-number-helper list))
(find-repeated-number one)
I get the following error, why is it? how can i get what i want to do? I would appreciate any help
*** ERROR: pair required, but got ()
While loading "./jdoodle.sc" at line 19
Stack Trace:
_______________________________________
0 (car (cdr list))
at "./jdoodle.sc":14
1 (equal? (car list) (car (cdr list)))
at "./jdoodle.sc":14
Command exited with non-zero status 70

I'm still not sure if the main point of this exercise is to write low-level recursive code or use some functions provided by the standard library (in this case, count or a combination of filter and length), but here's my wild guess:
(define a (list 10 2 3 54 6 9 7 10))
(define b (list 5 1 8 6 5 5 4 77 8 6))
(define c (list 80 80 80))
(define e (list 99 156 54 48 99))
(define d (list 16 94 75 30 56 16 8 16))
(define one (list a b c))
(define two (list c e b a))
(define three (list b c d e))
(define (find-count lst element)
(count (lambda (n) (= n element))
lst))
(define (print-count lst)
(let ((number-count (find-count (cdr lst) (car lst))))
(write (string-append
"number of times the first number is repeated: "
(number->string (car lst))
" is "
(number->string number-count)
(if (= number-count 1)
" time"
" times")))
(newline)))
(for-each print-count one)
Output:
"number of times the first number is repeated: 10 is 1 time"
"number of times the first number is repeated: 5 is 2 times"
"number of times the first number is repeated: 80 is 2 times"

Related

How to display fibonacci sequences less than upper bound (CLISP)

I am trying to display a Fibonacci sequence less than an upper bound, but I'm having trouble printing out the series that is constrained by that upper bound.
Without using imperative programming principles with declaring variables such as setf, setq, and set, etc. How can I solve this problem?
So far I have
(defun fibonacci (n &optional (a 0) (b 1))
(if (or (zerop n) (< a n)
nil)
(cons a (fibonacci (1- n) b (+ a b)))))
Expected output of (fibonacci 100): (0 1 1 2 3 5 8 13 21 34 55 89). However, what I am getting is (0 1 1 2 3 5 8 13 21 34 55).
You are decreasing upper bound for no reason. When you remove 1- and move one ) to right place, it works as expected:
(defun fibonacci (n &optional (a 0) (b 1))
(if (or (zerop n) (> a n))
nil
(cons a (fibonacci n b (+ a b)))))
Tests:
CL-USER 4 > (fibonacci 10)
(0 1 1 2 3 5 8)
CL-USER 5 > (fibonacci 100)
(0 1 1 2 3 5 8 13 21 34 55 89)
What you meant is
(defun fibonacci (n &optional (a 0) (b 1))
(if (or (zerop n) (> a n))
nil
(cons a (fibonacci n b (+ a b)))))
You had a ) placement typo / error, and the flipped test. Also, n is the upper limit, not a count. So there's no reason to decrease it.

How to write a function that counts increases in a list?

The task I'm given is, in Racket, to "write a function, countIncreases, which takes a list of numbers and returns how many times the consecutive numbers increase in value. For example, countIncreases '(1 3 2 4 5 1) should return 3 because there are three increases: 1 3, 2 4, 4 5."
I've written a recursive function with the base case being if the list is empty, return 0. I believe my problem is properly comparing one value to the next. Should I be using a standard library list iteration function like foldr or map to accomplish this?
My code and tests are below, and a screenshot of error messages is attached here
(define (countIncreases aList)
(if (empty? aList)
0
(if (< (first aList) (rest aList))
(+ 1 (countIncreases (rest aList)))
(countIncreases (rest aList)))))
(check-expect (countIncreases '(1 3 2 4 5 1)) 3)
(check-expect (countIncreases '()) 0)
(check-expect (countIncreases '(1 2 3 4 5)) 4)
(check-expect (countIncreases '(5 4 3 2 1 2)) 1)

How to Recursively iterate through 2 lists

For my homework problem, I have to remove the duplicates in a list if part of the list is inside another. The expected outcome is supposed to be this:
(remove-redundant '((R (1 2 3 8 e 4 7 6 5))
(U (e 2 3 1 8 4 7 6 5))
(D (1 2 3 7 8 4 e 6 5)))
'((D (1 2 3 e 8 4 7 6 5))
(L (e 2 3 1 8 4 7 6 5))
(U (2 e 3 1 8 4 7 6 5))
(U (2 8 3 1 e 4 7 6 5))))
Returns:
((R (1 2 3 8 e 4 7 6 5)) (D (1 2 3 7 8 4 e 6 5)))
It is supposed to check to see if the list inside each list, for the 1st parameter appears anywhere in the 2nd. If it does appear, then remove that from the 1st list. Basically, if (1 2 3 e 8 4 7 6 5) matches something in the 1st list, remove it from the 1st list. I need to do this recursively, it is supposed to be a functional program.
I have already tried recursing through the list, but it doesn't reset (i.e. it will check the second list for the beginning of the first list but then will return.
(defun same-state (l1 l2)
(if (equal (cadr l1) (cadr l2)) t nil))
(defun remove-redundant (l1 l2)
(cond
((null l2) l1)
((null l1) nil)
((same-state (car l1) (car l2)) (remove-redundant (cdr l1) (cdr l2))
(T (remove-redundant l1 (cdr l2)))))
You're close, but there should be some accumulation of the cells you want to keep in the t case of your cond form,
eg.
;; ...
(t
(cons (car l1) (remove-redundant (cdr l1) (cdr l2))))
and when you check if the first element of l1 exists in l2 there should be another loop or recursion to check against all the elements in l2, eg.
(defun same-state (l1 l2)
(find l1 l2 :key #'cadr :test #'equal))
(defun remove-redundant (l1 l2)
(cond
((null l2) l1)
((null l1) nil)
((same-state (cadar l1) l2)
(remove-redundant (cdr l1) (cdr l2)))
(t (cons (car l1)
(remove-redundant (cdr l1) (cdr l2))))))
;; => ((R (1 2 3 8 e 4 7 6 5)) (D (1 2 3 7 8 4 e 6 5)))
You will need two loops: one to go through the first list, and then one per element of that to find matches in the second list.

Scheme, stopping my recursion

The function firstnprimes is supposed to return the first n primes. Arguments are n the number of primes, nlist a list from 2-m of integers. and slist is the solution list and is initially empty and is added to and reconstructed each call to firstnprimes.
It works by removing the first number from the list and then removing all multiples of that number from nlist with listminusnonprimes; which I know works. The problem is that I can't control this action, I figure for each pass if slist's length was equal to the number of primes you want then you're done.
Code:
(define firstnprimes
(lambda (n nlist slist)
(let ((slist (cons (car nlist) slist)))
(if (zero? n)
slist
(firstnprimes (- n 1) (listMinusNonprimes (car nlist) (car nlist) nlist) slist)))))
(define listminusnonprimes
(lambda (num d lst)
(if (null? lst)
'()
(if (= d (car lst))
(listminusnonprimes num (+ num d) (cdr lst))
(cons (car lst) (listminusnonprimes num d (cdr lst)))))))
Your definition of listminusnonprimes is wrong. Imagine the call (listminusnonprimes 3 3 '(3 5 7 9 11 ...)) (as this would happen after you remove all multiples of 2). Now 3 is removed, and recursively you call (listminusnonprimes 6 3 '(5 7 9 11 ...)), but 6 is not there, so the call does nothing and the result is (3 5 7 9 11 ...).
I would suggest implementing this function using the mod operation.
You don't need (let ((slist (cons (car nlist) slist))). Also, use append instead of cons as shown
(define firstnprimes
(lambda (n nlist slist)
(if (zero? n)
slist
(firstnprimes (- n 1) (listminusnonprimes (car nlist) (car nlist) nlist) (append slist (list (car nlist)))))))
So,
(firstnprimes 2 '(2 4 7 9 21 36) '()) => '(2 7)
(firstnprimes 3 '(2 4 7 9 21 36) '()) => '(2 7 9)
Lots of problems with your implementation though. First, the list has to be in increasing order. Also, the list has to start with a prime number. Also, the number of prime numbers in the nlist has to be less than or equal to n.
(firstnprimes 4 '(2 4 7 9 21 36) '()) => '(2 7 9 21) which is wrong
Here is a slightly better implementation of your concept.
(define firstnprimes
(lambda (n nlist slist)
(if (or (zero? n) (null? nlist))
slist
(firstnprimes (- n 1) (listminusnonprimes (car nlist) (car nlist) nlist) (append slist (list (car nlist)))))))
(define listminusnonprimes
(lambda (num d lst)
(if (null? lst)
'()
(if (< d (car lst))
(listminusnonprimes num (+ num d) lst)
(if (= d (car lst))
(listminusnonprimes num (+ num d) (cdr lst))
(cons (car lst) (listminusnonprimes num (+ num d) (cdr lst))))))))
Now,
(firstnprimes 2 '(2 4 7 9 21 36) '()) => '(2 7)
(firstnprimes 3 '(2 4 7 9 21 36) '()) => '(2 7 9)
(firstnprimes 4 '(2 4 7 9 21 36) '()) => '(2 7 9)
But the first element still has to be prime though

Counting unique elements in Scheme

Write a recursive Scheme procedure count-dist elements that takes a list with duplicate elements and returns the number of distinct elements in the list.
This is my code, but it is not working correctly. Please help! Thanks!!
(define (count-dist-elements lis)
(cond
((null? lis) 0)
((null? (cdr lis))0)
((member (car lis)(cdr lis)))
(else(+ 1(count-dist-elements (cdr lis))))))
p/s: let it be (count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9))
It looks like you're getting pretty close.
What happens when you pass your function a list with one element? What should your function return in this case?
What about a two-element list with the same element (eg. (5 5))? Does your function return a sensible value?
First: Why are you returning zero in the (null? (cdr lis)) case?
Second: What do you think your code returns in the case where the first element also occurs later in the list? Are you sure?
(define (count-dist-elements lst dist-elems count)
(cond ((null? lst) count)
((member (car lst) dist-elems)
(count-dist-elements (cdr lst) dist-elems count))
(else
(count-dist-elements (cdr lst)
(cons (car lst) dist-elems)
(+ 1 count)))))
(count-dist-elements '(a b b c) '() 0) ==> 3
(count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9) '() 0) ==> 9
Or, if you want it recursive and not iterative (and, it has to use a function call like the one shown),
(define (count-dist-elements lst . dist-elems)
(let ((dist-elems (if (null? dist-elems) '() (car dist-elems))))
(cond ((null? lst) 0)
((member (car lst) dist-elems)
(count-dist-elements (cdr lst) dist-elems))
(else
(+ 1 (count-dist-elements (cdr lst) (cons (car lst) dist-elems)))))))
Gives the same results.
(count-dist-elements '(1 2 1 1 2 3 4 5 5 6 6 7 7 8 8 8 9)) ==> 9

Resources