Object appears at least twice in list? - racket

Let's say we have a: (list 1 2 3 5 2 6 7 4)
I want to know if 2 appears at least twice.
member? checks if it appears at all. I suppose I could check member? then run remove then check member? again. Is there a more efficient method?

You should use count, which receives a lambda for checking any condition you want and a list to be checked. It returns the number of elements in the list that meet the condition:
(count (lambda (n) (= n 2)) (list 1 2 3 5 2 6 7 4))
=> 2
Then it's a simple matter to verify if the count fulfills the requirement that the number appears at least twice.

One can use member function with recursion to check if first element is the desired number and is also part of rest of the list- then loop again with rest of the list:
(define (is_duplicated n L)
(let loop ((L L))
(cond
[(empty? L) #f]
[(and (= n (first L))
(member n (rest L))) #t]
[else (loop (rest L))]
)))
(is_duplicated 2 (list 1 2 3 5 2 6 7 4))
Note that it is "member" and not "member?" which is part of Racket base functions (https://docs.racket-lang.org/search/index.html?q=member%3F).

Related

How do you compare 3 arguments or more in racket?

I know that in Racket to compare for example two numbers you will have something like this.
(define (myMax x y)
(if (< x y) y x))
My question is how do you compare for a function with 3 arguments or more. For example to get the highest number from the arguments.
(define (myMax x y z)
If you want to process an undefined number of elements, you need to work with list.
The idiomatic way is to use recursion to process the elements. Each function call need to process one element (car) and the rest of the list cdr.
You can find an implementation on a another post:
https://stackoverflow.com/a/42463097/10953006
EDIT 1: EXAMPLE
(define (maximum L)
(if (null? (cdr L))
(car L)
(if (< (car L) (maximum (cdr L)))
(maximum (cdr L))
(car L))))
(maximum '( 1 2 3 ))
(maximum '( 1 2 3 4))
(maximum '( 1 2 3 4 5))
Give the results:
3
4
5
EDIT 2: if the real question is about variable number of arguments in Racket, you could use the following notation:
(define (test-function . L)
(printf "~S~%" L)) ;; Here: L is the list (1 2 3)
(test-function 1 2 3)
Which will display (printf):
(1 2 3)

Scheme: vector function that returns the first odd number

I can't figure out on how to write a vector function that returns the first odd number in the list.
Ex: (check-expect (first-oddnumb 2 3 4 5 6) 3)) ;;it returns 3 because 3 is the first odd number in the list.
I can't figure out on how to write a vector function that returns the first odd number in the list.
My confusion is the same as #Sylwester's: "vector function"? The rest of the question seems to make sense tho.
I can help you write a function that returns the first odd number in the list.
We want the function to work like this
(first-odd-number 2 3 4 5 6) ;; => 3
So the first thing we have to do is learn how to write a function that accepts a variable number of arguments
(define (variadic . xs) xs)
(variadic 1 2) ;; => '(1 2)
(variadic 1 2 3) ;; => '(1 2 3)
(variadic 1 2 3 4) ;; => '(1 2 3 4)
(variadic) ;; => '()
Note the . before the xs parameter. This gives us a way to collect all of the passed arguments into the bound identifier, xs. Notice how the arguments are collected into a list. Also pay attention to how xs will still be a list (empty list '()) even if no arguments are given in the function call.
Now we can begin writing your function
(define (first-odd-number . xs)
;; so we know xs will be a list here ...
)
Let's talk about the possible states of xs
xs could be empty, in which case what should we return? maybe a 0 or something? (more on this later)
Otherwise, xs has at least one number ...
is the first number an odd number? if so, return that number
is the first number an even number? if so, return first-odd-number of the remaining numbers in xs
OK, we can pretty much define this in Racket verbatim
(define (first-odd-number . xs)
;; begin case analysis of xs
(cond
;; is the list of numbers empty? return 0
[(empty? xs) 0]
;; the list is not empty, continue ...
;; is the first number odd?
[(odd? (car xs)) (car xs)]
;; otherwise...
;; the number even, check remaining numbers
[else (apply first-odd-number (cdr xs))]))
(first-odd-number 2 3 4 5 6) ;; => 3
(first-odd-number 3 4 5 6) ;; => 3
(first-odd-number 4 5 6) ;; => 5
(first-odd-number) ;; => 0
And that's pretty much it !
Improvements...
If you're like me tho, that 0 is making you feel uneasy. What if you were given a list of only even numbers? What should the return value be?
(first-odd-number 2 4 6) ;; => 0
This is kind of weird. We could use the 0 to mean that no odd number was found, but Maybe there's a better way ...
(struct Just (value) #:transparent)
(struct None () #:transparent)
(define (first-odd-number . xs)
(cond
;; no odd number was found; return None
[(empty? xs) (None)]
;; an odd number was found, return (Just n)
[(odd? (car xs)) (Just (car xs))]
;; otherwise check the remaining numbers
[else (apply first-odd-number (cdr xs))]))
(first-odd-number 2 3 4 5 6) ;; => (Just 3)
(first-odd-number 3 4 5 6) ;; => (Just 3)
(first-odd-number 4 5 6) ;; => (Just 5)
(first-odd-number) ;; => (None)
Now when the caller of our first-odd-number is working with the function, we don't have to don't have to remember that 0 is a special case we need to consider
(define (print-the-first-odd-number . xs)
(match (apply first-odd-number xs)
[(Just x) (printf "the number is ~a\n" x)]
[(None) (printf "no odd number was found\n")]))
(print-the-first-odd-number 2 3 4 5 6) ;; the number is 3
(print-the-first-odd-number 2 4 6) ;; no odd number was found
Another way is to use a comprehension to iterate over the vector (or whatever), specifically, for/first, which returns the value returned by the first body that gets evaluated, combined with a #:when clause to limit said evaluation to the first odd element of a vector:
#lang racket/base
(define (first-odd-number container)
(for/first ([num container]
#:when (odd? num))
num))
(displayln (first-odd-number #(2 3 4 5 6))) ; 3, passing a vector
(displayln (first-odd-number '(2 3 4 5 6))) ; 3, passing a list
If no odd number is present, it returns #f.
While you get better performance by using type specific sequence builders like in-vector with a for loop, using a container directly like this gives more flexibility (It would also work with sets of numbers and a few other standard types)
If instead wanting a function that takes a variable number of arguments, use a hardcoded in-list and the appropriate formals:
(define (first-odd-number . numbers)
(for/first ([num (in-list numbers)]
#:when (odd? num))
num))

Racket function that returns all numbers whose sum is <= given number?

I'm taking an intro to computer science course and one question needs me to write a function that takes a list of numbers and a number and returns the numbers in the list whose sum is less than the given number. I've written the function signature, definition, and check-expects, but I'm stuck. The function needs to assume intermediate student with lambda. I don't want any direct answers here; just help so that I can reach the answer myself.
I know it needs to use recursion. Perhaps a helper function would be needed.
;; sum-up-to: lon, number -> lon
;; consumes a list of numbers and a number and
;; returns the numbers in the list whose sum is
;; less than or equal to the given number
(define the-numbers (list 1 2 3 4 5 6 7 8 9))
(check-expect (sum-up-to the-numbers 7) (list 1 2 3))
(check-expect (sum-up-to the-numbers 18) (list 1 2 3 4 5))
(check-expect (sum-up-to the-numbers 45) the-numbers)
This problem can be simplified if we sort the list first and if we define a helper function that keeps track of the accumulated sum. Here's a skeleton, fill-in the blanks with the missing expressions and you'll have the solution:
(define (sum-up-to lst n)
(helper <???> n 0)) ; sort the input list, pass it to the helper
(define (helper lst n sum)
(cond (<???> '()) ; if the list is empty, end the recursion
((> <???> n) '()) ; also end recursion if sum + current element > n
(else
(cons <???> ; otherwise cons current element
(helper <???> ; advance recursion over list
n
(+ <???> <???>)))))) ; update sum
Following recursive method keeps adding numbers from the list sequentially to an initially empty outlist, till the sum is reached:
(define the-numbers (list 1 2 3 4 5 6 7 8 9))
(define (f lst sum)
(let loop ((lst lst)
(ol '()))
(if (or (..ENTER CONDITION FOR EMPTY LIST..)
(..ENTER CONDITION WHEN SUM IS REACHED..)
(..ENTER HOW TO PUT THE NEW LIST OUT..)
(loop (..ENTER ARGUMENTS TO BE SENT TO NEXT LOOP..)
))))
(f the-numbers 7)
(f the-numbers 18)
(f the-numbers 45)
Output:
'(1 2 3)
'(1 2 3 4 5)
'(1 2 3 4 5 6 7 8 9)

Building a random list

I am trying to write a function that takes in the length of a list and a maximum number value and returns a list that is the length given with numbers between 1 and the given max randomly.
so far I have
(define (randomlist n max)
(cond
[(= n 0)empty]
[else
(cons (build-list n (random 1 max))
(randomlist max (- n 1)))]))
I get an error when I run this and was wondering if anybody could help me out.
One can also use for/list to combine loop and list formation:
(define (randomlist n mx)
(for/list ((i n))
(add1 (random mx))))
Testing:
(randomlist 5 10)
Output:
'(5 9 10 4 7)
(random numbers, hence output is very likely to be different each time).
There are several bugs in your code:
It's a bad idea to call a parameter max, that clashes with a built-in procedure. So I renamed it to mx.
There's absolutely no reason to use build-list, that's not how we build an output list, just cons one element with the rest.
random receives zero or one parameters, not two. The single-parameter version returns an integer in the range 0..n-1, hence we have to add 1 to the result to be in the range 1..n.
You switched the order of the parameters when recursively calling randomlist.
This should take care of the problems:
(define (randomlist n mx)
(cond
[(= n 0) empty]
[else
(cons (+ 1 (random mx))
(randomlist (- n 1) mx))]))
It works as expected:
(randomlist 5 10)
=> '(10 7 1 4 8) ; results will vary, obviously

Writing the Foo Function In LISP With the following Specification

I am struggling to find the right approach to solve the following function
(FOO #'– '(1 2 3 4 5))
=> ((–1 2 3 4 5) (1 –2 3 4 5) (1 2 –3 4 5) (1 2 3 –4 5) (1 2 3 4 –5))
The first Parameter to the foo function is supposed to be a function "-" that has to be applied to each element returning a list of list as shown above. I am not sure as to what approach I can take to create this function. I thought of recursion but not sure how I will preserve the list in each call and what kind of base criteria would I have. Any help would be appreciated. I cannot use loops as this is functional programming.
It's a pity you cannot use loop because this could be elegantly solved like so:
(defun foo (fctn lst)
(loop
for n from 0 below (length lst) ; outer
collect (loop
for elt in lst ; inner
for i from 0
collect (if (= i n) (funcall fctn elt) elt))))
So we've got an outer loop that increments n from 0 to (length lst) excluded, and an inner loop that will copy verbatim the list except for element n where fctn is applied:
CL-USER> (foo #'- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
Replacing loop by recursion means creating local functions by using labels that replace the inner and the outer loop, for example:
(defun foo (fctn lst)
(let ((len (length lst)))
(labels
((inner (lst n &optional (i 0))
(unless (= i len)
(cons (if (= i n) (funcall fctn (car lst)) (car lst))
(inner (cdr lst) n (1+ i)))))
(outer (&optional (i 0))
(unless (= i len)
(cons (inner lst i) (outer (1+ i))))))
(outer))))
Part of the implementation strategy that you choose here will depend on whether you want to support structure sharing or not. Some of the answers have provided solutions where you get completely new lists, which may be what you want. If you want to actually share some of the common structure, you can do that too, with a solution like this. (Note: I'm using first/rest/list* in preference to car/car/cons, since we're working with lists, not arbitrary trees.)
(defun foo (operation list)
(labels ((foo% (left right result)
(if (endp right)
(nreverse result)
(let* ((x (first right))
(ox (funcall operation x)))
(foo% (list* x left)
(rest right)
(list* (revappend left
(list* ox (rest right)))
result))))))
(foo% '() list '())))
The idea is to walk down list once, keeping track of the left side (in reverse) and the right side as we've gone through them, so we get as left and right:
() (1 2 3 4)
(1) (2 3 4)
(2 1) (3 4)
(3 2 1) (4)
(4 3 2 1) ()
At each step but the last, we take the the first element from the right side, apply the operation, and create a new list use revappend with the left, the result of the operation, and the rest of right. The results from all those operations are accumulated in result (in reverse order). At the end, we simply return result, reversed. We can check that this has the right result, along with observing the structure sharing:
CL-USER> (foo '- '(1 2 3 4 5))
((-1 2 3 4 5) (1 -2 3 4 5) (1 2 -3 4 5) (1 2 3 -4 5) (1 2 3 4 -5))
By setting *print-circle* to true, we can see the structure sharing:
CL-USER> (setf *print-circle* t)
T
CL-USER> (let ((l '(1 2 3 4 5)))
(list l (foo '- l)))
((1 . #1=(2 . #2=(3 . #3=(4 . #4=(5))))) ; input L
((-1 . #1#)
(1 -2 . #2#)
(1 2 -3 . #3#)
(1 2 3 -4 . #4#)
(1 2 3 4 -5)))
Each list in the output shares as much structure with the original input list as possible.
I find it easier, conceptually, to write some of these kind of functions recursively, using labels, but Common Lisp doesn't guarantee tail call optimization, so it's worth writing this iteratively, too. Here's one way that could be done:
(defun phoo (operation list)
(do ((left '())
(right list)
(result '()))
((endp right)
(nreverse result))
(let* ((x (pop right))
(ox (funcall operation x)))
(push (revappend left (list* ox right)) result)
(push x left))))
The base case of a recursion can be determined by asking yourself "When do I want to stop?".
As an example, when I want to compute the sum of an integer and all positive integers below it, I can do this recusively with a base case determined by answering "When do I want to stop?" with "When the value I might add in is zero.":
(defun sumdown (val)
(if (zerop val)
0
(+ (sumdown (1- val)) val)))
With regard to 'preserve the list in each call', rather than trying to preserve anything I would just build up a result as you go along. Using the 'sumdown' example, this can be done in various ways that are all fundamentally the same approach.
The approach is to have an auxiliary function with a result argument that lets you build up a result as you recurse, and a function that is intended for the user to call, which calls the auxiliary function:
(defun sumdown1-aux (val result)
(if (zerop val)
result
(sumdown1-aux (1- val) (+ val result))))
(defun sumdown1 (val)
(sumdown1-aux val 0))
You can combine the auxiliary function and the function intended to be called by the user by using optional arguments:
(defun sumdown2 (val &optional (result 0))
(if (zerop val)
result
(sumdown2 (1- val) (+ val result))))
You can hide the fact that an auxiliary function is being used by locally binding it within the function the user would call:
(defun sumdown3 (val)
(labels ((sumdown3-aux (val result)
(if (zerop val)
result
(sumdown3-aux (1- val) (+ val result)))))
(sumdown3-aux val 0)))
A recursive solution to your problem can be implemented by answering the question "When do I want to stop when I want to operate on every element of a list?" to determine the base case, and building up a result list-of-lists (instead of adding as in the example) as you recurse. Breaking the problem into smaller pieces will help - "Make a copy of the original list with the nth element replaced by the result of calling the function on that element" can be considered a subproblem, so you might want to write a function that does that first, then use that function to write a function that solves the whole problem. It will be easier if you are allowed to use functions like mapcar and substitute or substitute-if, but if you are not, then you can write equivalents yourself out of what you are allowed to use.