How do I add each element into a list? - racket

So Im' trying to print out a list of numbers but instead of printing all the numbers only the last number is put into the list. I know that means that the other numbers are not being inserted but I dont know how to fix this problem. I tried moving my cons around the function but nothign changes.
I'm new to racket so if Im not understanding a concept, please let me know.
should look like:
(gen-list 1 4)
output:
'(1 2 3 4)
(define (gen-list start end)
(if (> start end)
'()
(cond ((<= start end)
(gen-list start (- end 1))
)))
(cons end '()))

I see you would like to use recursion, so I would suggest to use printf to understand what really happen.
The idea is quite simple, you have start and end, what you want to have is the following:
Step 1: start=1 end=4
Step 2: start=2 end=4
Step 3: start=3 end=4
Step 4: start=4 end=4
Step 5: start=5 end=4, here we stop the recursion
So you need to increment start at each step of the recursion when the condition is met (<= start end).
(define (gen-list start end)
(printf "CALL ~A ~A~%" start end)
(cond
((<= start end)
(cons start
(gen-list (+ start 1) end)))
(else '())))
(gen-list 1 4)
Will return:
CALL 1 4
CALL 2 4
CALL 3 4
CALL 4 4
CALL 5 4
'(1 2 3 4)
EDIT: if you concern is to write programs, you could also use built-in functions, which are ready for use:
> (range 1 5)
(1 2 3 4)
> (sequence->list (in-inclusive-range 1 4))
'(1 2 3 4)
> (build-list 4 (lambda (x) x))
'(0 1 2 3)
https://docs.racket-lang.org/reference/sequences.html

Related

generate multiple values during iteration

Is there a way I can generate multiple values in for/list during each iteration and have the results "flattened"?
For instance:
(for/list ([i (range n)]) (values i (+ i 1)))
I'd like the result to be (list 0 1 1 2 2 3 3 4 ...).
This question is very much relevant to https://github.com/racket/racket/pull/2483. In the link, you will find:
An unmerged PR that lets you write (for/append-list ([i (range n)]) (list i (+ i 1))).
My proposal to let you write (for/list* ([i (range n)]) (values i (+ i 1))) (with caveat, see the link for more details).
But since these don't exist in Racket yet, the easiest way to get what you want is:
(append* (for/list ([i (range n)]) (list i (+ i 1))))

How can I write a MEMBER function using the DO macro in Common Lisp?

I am trying to make a function which works like MEMBER function in Common Lisp.
So, I want to make this function work like this :
(my-member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)
This is exactly same as how MEMBER function works.;
(member 2 '(1 4 5 5 3 2 5 6 9))
=> (2 5 6 9)
The condition is that I should use 'DO' macro to make this function.
This is my code that I have written to make this function :
(defun my-member (item x)
"This function works like MEMBER function."
(do ((z x (rest z))
(e (first x) (first z)))
(:when (equal item (first z))
(return z))))
But it doesn't work..
(my-member 2 '(3 4 5 2 1 1))
-> (3 4 5 2 1 1)
What should I do to solve this problem?
Here is the correct way to use do:
(do ((var 0 (1+ var))
(lst '() (cons var lst)))
((= var 5) lst)))
; ==> (4 3 2 1 0)
So both var and lst are variables initialised to 0 and () and after each iteration the variable is set to (1+ var) and (cons var lst).
What determines when it should stop is (= var 5) becoming not nil and when that happens the result of the whole do form is lst. This is the second part of the do and the last this has since I do not supply a body.
You can make an equivalent of the member function with using only one variable and a second part with an end condition and what should be the result of the do. Good luck!

Object appears at least twice in list?

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).

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)

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.