Iteration over a list with a for loop (Racket) - racket

I need help with writing a function that uses a for loop to iterate over a list of numbers and returns all numbers that are less than 10. I have no idea where to start if anyone could help with even a starting point I'd appreciate it.
Thank you :)

The "standard" way to do such a thing is with the filter procedure. It takes a predicate (a procedure that indicates whether a condition is true) and a list, and produces a new list containing those elements in the input list that satisfy the predicate. For example, we can produce a list that contains only the even numbers from an input list of numbers like so:
(filter even? '(0 1 2 3 4 5 6))
;; => (0 2 4 6)
In your case, there's no "built in" predicate for testing whether a number is less than 10, but we can easily define one:
(define (<10 n)
(< n 10))
and then filter any list using it:
(filter <10 '(1 4 15 23 25 4 8))
;; => (1 4 4 8)
In this case though, I think most would prefer to use a lambda instead:
(filter (lambda (n) (< n 10))
'(1 4 15 23 25 4 8))
;; => (1 4 4 8)
Hope this helps!

Related

Exercise about substitution in nested lisp [duplicate]

I’m trying to write a function with two arguments of this type:
substitutions (list_one, list_two)
list_one has always this form (letters can change according to the input):
(1 ((1 2 ((1 2 r) (3 2 t) (4 3 c))) (3 4 ((5 6 y) (5 7 i)))))
list_two has always this form (numbers can change according to the input):
(2 3 4 5 6)
I want to substitute in this way:
r-> 2
t -> 3
c -> 4
y -> 5
i -> 6
Can you help me please?
A not so efficient solution is to first find a list of all the letters in the fist tree structure (the first list) and then to LOOP over the results calling SUBST repeatedly.
To find the list of non numeric atoms in the first list (the 'letters') you need to traverse the tree structure (le first list) recurring both on the FIRST and on the REST of the list.
Hope it helps.
MA
If the lists are proper you can iterate them with the loop macro and pop off the arguments in the accessible free variable:
(defun template-replace (template replacements)
(labels ((iterate (template)
(loop :for element :in template
:collect
(cond ((consp element) (iterate element))
((symbolp element) (pop replacements))
(t element)))))
(iterate template)))
(template-replace '(1 rep (4 rep (9 rep)) rep) '(foot inch mm multiplied))
; ==> (1 foot (4 inch (9 mm)) multiplied)

Substitutions in Common Lisp

I’m trying to write a function with two arguments of this type:
substitutions (list_one, list_two)
list_one has always this form (letters can change according to the input):
(1 ((1 2 ((1 2 r) (3 2 t) (4 3 c))) (3 4 ((5 6 y) (5 7 i)))))
list_two has always this form (numbers can change according to the input):
(2 3 4 5 6)
I want to substitute in this way:
r-> 2
t -> 3
c -> 4
y -> 5
i -> 6
Can you help me please?
A not so efficient solution is to first find a list of all the letters in the fist tree structure (the first list) and then to LOOP over the results calling SUBST repeatedly.
To find the list of non numeric atoms in the first list (the 'letters') you need to traverse the tree structure (le first list) recurring both on the FIRST and on the REST of the list.
Hope it helps.
MA
If the lists are proper you can iterate them with the loop macro and pop off the arguments in the accessible free variable:
(defun template-replace (template replacements)
(labels ((iterate (template)
(loop :for element :in template
:collect
(cond ((consp element) (iterate element))
((symbolp element) (pop replacements))
(t element)))))
(iterate template)))
(template-replace '(1 rep (4 rep (9 rep)) rep) '(foot inch mm multiplied))
; ==> (1 foot (4 inch (9 mm)) multiplied)

clisp positive number founder

I am trying to return a list which contains non-negative numbers from function parameter list using clisp.
(defun recursive (L)
(setq ret (list))
(setq first (car L))
(setq rest (cdr L))
(if (null L)
0
(if (>= first 0)
(nconc ret (first))
(recursive rest))))
(setq mylist (list 1 2 3 -1 0 -3))
(write (recursive mylist))
I wrote this and expecting an output as (1 2 3 0)
What is wrong in that code?
Let filter be the function you want to implement.
Then (filter nil) should return nil.
In the general case, you compte (filter (number . tail)) recursively. Assuming that filter computes the list of positive numbers in a list, you can solve the problem for tail, and call (filter tail). In order to solve your current problem, you have to consider if number is positive or not, and add the element to the recursive result accordingly.
(defun filter (list)
(etypecase list
(null nil)
(cons (destructuring-bind (number . tail) list
(if (plusp number)
(cons number (filter tail))
(filter tail))))))
I am using ETYPECASE, PLUSP, DESTRUCTURING-BIND, but you can express the same differently. Note that you used NCONC which requires iterating over the whole list, which is not required and makes your whole aproach quadratic in time.
The above function has a flaw because the size of the call stack grows linearly with the size of your input list. Each time you call filter, a new frame is allocated on the stack, which can be easily seen with TRACE:
CL-USER> (trace filter)
(FILTER)
CL-USER> (filter '(0 1 -2 3 -4 -5 6 7 -8 9))
0: (FILTER (0 1 -2 3 -4 -5 6 7 -8 9))
1: (FILTER (1 -2 3 -4 -5 6 7 -8 9))
2: (FILTER (-2 3 -4 -5 6 7 -8 9))
3: (FILTER (3 -4 -5 6 7 -8 9))
4: (FILTER (-4 -5 6 7 -8 9))
5: (FILTER (-5 6 7 -8 9))
6: (FILTER (6 7 -8 9))
7: (FILTER (7 -8 9))
8: (FILTER (-8 9))
9: (FILTER (9))
10: (FILTER NIL)
10: FILTER returned NIL
9: FILTER returned (9)
8: FILTER returned (9)
7: FILTER returned (7 9)
6: FILTER returned (6 7 9)
5: FILTER returned (6 7 9)
4: FILTER returned (6 7 9)
3: FILTER returned (3 6 7 9)
2: FILTER returned (3 6 7 9)
1: FILTER returned (1 3 6 7 9)
0: FILTER returned (1 3 6 7 9)
This happens because you need to remember each intermediate value of number across recursive calls, in order to cons them with a recursive result. If you could instead have done all your work before descending into a recursive call, then there would be no need to retain intermediate values, and the function would be recursive terminal and could be subject to what is known as tail-call optimization.
In order to do that, you have to build the resulting list before calling the recursive call, through an accumulator:
(defun filter (list accumulator)
(etypecase list
(null accumulator)
(cons (destructuring-bind (head . tail) list
(if (plusp head)
(filter tail (cons head accumulator))
(filter tail accumulator))))))
Notice the repetition, which can be refactored as:
(filter tail (if (plusp head) (cons head accumulator) accumulator))
Here above, we added an accumulator, which holds the new list. Initially, you should pass an empty list. When you reach the end of your input list, you return the accumulator. Otherwise, you add the number to the accumulator before calling filter recursively. The difference is that you don't need to store intermediate values in the call stack. The trace macro produces this:
0: (FILTER (0 1 -2 3 -4 -5 6 7 -8 9) NIL)
1: (FILTER (1 -2 3 -4 -5 6 7 -8 9) NIL)
2: (FILTER (-2 3 -4 -5 6 7 -8 9) (1))
3: (FILTER (3 -4 -5 6 7 -8 9) (1))
4: (FILTER (-4 -5 6 7 -8 9) (3 1))
5: (FILTER (-5 6 7 -8 9) (3 1))
6: (FILTER (6 7 -8 9) (3 1))
7: (FILTER (7 -8 9) (6 3 1))
8: (FILTER (-8 9) (7 6 3 1))
9: (FILTER (9) (7 6 3 1))
10: (FILTER NIL (9 7 6 3 1))
10: FILTER returned (9 7 6 3 1)
9: FILTER returned (9 7 6 3 1)
8: FILTER returned (9 7 6 3 1)
7: FILTER returned (9 7 6 3 1)
6: FILTER returned (9 7 6 3 1)
5: FILTER returned (9 7 6 3 1)
4: FILTER returned (9 7 6 3 1)
3: FILTER returned (9 7 6 3 1)
2: FILTER returned (9 7 6 3 1)
1: FILTER returned (9 7 6 3 1)
0: FILTER returned (9 7 6 3 1)
Please note that the function is tail-recursive, but doesn't look like it was optimized away because there is an arrow-shaped trace. However, trace is not a reliable way of knowing if the function is or isn't tail-recursive, because the act of tracing changes hat is actually done. Or, maybe the debug quality is so high that tail-call optimization is not applied. This depends on your implementation. Please note that the trace clearly shows how the intermediate list is built, and how the result is passed unchanged from deep levels to higher ones. See also that the list is being built in reverse, because we keep calling cons with the accumulator (which is efficient, contrary to nconc).
Since you didn't specify if you want the elements of the list to retain the same order as the input list, I assumed that this is not required.
However, you could also call NREVERSE on the resulting list to reverse it destructively (i.e. in-place, without allocating memory). This is ok if here because you own the fresh list being built, so you can safely modify it before giving it to the caller. This is best done by wrapping the implementation detail inside a local function:
(defun filter (list)
(labels ((filter (list accumulator)
(etypecase list
(null accumulator)
(cons (destructuring-bind (head . tail) list
(filter tail (if (plusp head)
(cons head accumulator)
accumulator)))))))
(nreverse (filter list nil))))
Note that filter is lexically bound to a local function inside the global filter function. See also LABELS.
However, you can better spend your time than writing recursive functions to perform loops. Common Lisp provide iteration construction, which means you can simply do this:
(defun filter (list)
(loop for number in list
when (plusp number)
collect number))
Note that removing elements from lists is also easily done with REMOVE-IF-NOT.
First off, your code doesn't work, because of the way you are using first as a function ((first)) in the then-branch of your if.
Apart from that, every time you call recursive, you re-initialize ret to an empty list. And inside the if you only recurse if the number is not bigger than 0.
Here's a working solution using cond:
(defun filter-non-negative (l)
(cond
((null l) ;; empty list
nil)
((>= (first l) 0) ;; number >= 0
(cons (first l) (filter-non-negative (rest l))))
(t ;; all other cases
(filter-non-negative (rest l)))))
(write (filter-non-negative '(1 2 3 -1 0 -3)))
;; (1 2 3 0)
First of all, the variables ret, first and rest should be defined locally with a let. In your version they are global variables. Note that you don't need these variables at all, you can simply use the function calls directly.
In the line before last, you have (first), which will signal an error because this function expects an argument. However, what you want is not the function first but the variable first, therefore you need (list first).
When the list is null, you return a 0. Since you will reach this point at the end of every recursive call, this will add a 0 to any input argument. You should return nil instead.
Finally, instead of nconc look at the function cons.
Incidentally, note that there is a function remove-if that will do exactly the job you want, but I understand that you are trying to learn about recursive calls.
I hope this helps.
You want to keep the positive numbers. Positive numbers are greater 0.
Let's remove all numbers which are not positive:
CL-USER 24 > (remove-if-not #'plusp (list 1 2 3 -1 0 -3))
(1 2 3)
or
CL-USER 25 > (remove-if (complement #'plusp) (list 1 2 3 -1 0 -3))
(1 2 3)

Members in a list - LISP [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I need to write a program in Lisp to see the number of occurrences of a specific character in a list. For example the occurrences of 1 in the following list [1, 2, 3, 1,1]
A list in Lisp is a sequence of cons nodes: pairs of pointers - the first to the payload datum, and the second to the rest of the list. E.g. for [1,2,3,1,1],
.
/ \
1 .
/ \
2 .
/ \
3 ...... .
/ \
1 NIL
NIL is a special value signaling the empty list, such that the system knows not to try to explore it any further. In Scheme,
(define NIL '())
Recursive list processing paradigm is captured by the notion of fold, where each node . is "replaced" with a binary function f, and the special node NIL is replaced with some special "zero" value z, to create an application chain (f 1 (f 2 (f 3 (... (f 1 z) ...)))). In Scheme,
(define (myfold f z list)
(cond
((null? list) z) ; replace NIL with the initial ("zero") value
(else
(f ; combine
(car list) ; the payload datum, and the delayed,
(lambda () ; by creating a function to calculate it,
(myfold f z ; result of recursively folding
(cdr list))))))) ; the rest of list
That way, the combining function f must process two values: one is a node's payload datum, the other is the (delayed) result of recursively folding, with the same f and z, the rest of the list after that node.
(define (keep-equals v list)
(myfold
(lambda (a r) ; combine ...
(if (equal? v a)
(cons a ... ) ; the same thing goes over the dots, here
... )) ; and here
'() ; replace the NIL of the argument list with this
list))
Since the recursive folding results' calculation is delayed by creating a function to-be-called when the results are needed, we need to "force" that calculation to be performed, when we indeed need those results, by calling that function.
And if you want to count the number of occurrences instead of collecting them in a list, you just need to use a different combining function with a different initial ("zero") value.
In particular, we build a list by consing a value onto the rest of list (with NIL as the initial value, the empty list); whereas we count by incrementing a counter (with 0 as the initial value of that counter).
Calculating e.g. a list's length by folding, we essentially turn its elements each into 1: length [a,b,c,d,e] == 1 + (1 + (1 + (1 + (1 + 0)))). Here, the combining function will need to increment the counter conditionally, only when the payload data are such that we want to count them.
I like pretty well the answers already posted to this question. But it seems like they both involve a fair bit more than the necessary amount of work. On the other hand, given all the thought everyone's put into this, I'm almost embarrassed of how simple my answer is. Anyway, here's what I did:
(defun count-things-in (needle haystack)
"Count the number of NEEDLEs in HAYSTACK."
(reduce '+
(map 'list
#'(lambda (straw)
(if (equalp straw needle) 1 0))
haystack)))
(count-things-in 1 '(1 2 3 1 1))
;; => 3
It's pretty straightforward: you just map over HAYSTACK a function which returns 1 for an element which is EQUALP to NEEDLE or 0 for an element which isn't, and then reduce the resulting list by +. For the given example list, the map operation results in a list (1 0 0 1 1), which the reduce operation then treats as (1 + (0 + (0 + (1 + 1)))), which evaluates to 3.
Benefits of this approach include the use of an equality predicate loose enough to work with strings as well as numbers, and with numbers of different types but the same value -- that is, (equalp 1 1.0) => t; if you desire different behavior, use another equality predicate instead. Using the standard MAP and REDUCE functions, rather than implementing your own, also gives you the benefit of whatever optimizations your Lisp system may be able to apply.
Drawbacks include being not nearly as impressive as anyone else's implementation, and being probably not low-level enough to satisfy the requirements of the asker's homework problem -- not that that latter especially dismays me, given that this answer does satisfy the stated requirement.
I'm new to lisp myself but here is how I would do it. I haven't looked at the other answer yet from Will so I'll check that out after I post this. The member function has the utility of both telling you if it found something in a list, and also returning the rest of that list starting from where it found it:
CL-USER> (member '1 '(0 1 2 3))
(1 2 3)
You could then recursively call a function that uses member and increment a counter from returned values in a variable from a let:
(defun find1 (alist)
(let ((count 0))
(labels ((findit (list)
(let ((part (member '1 list)))
(if part
(progn (incf count)
(findit (rest part)))
0))
count))
(findit alist))))
Here is the result:
CL-USER> (find1 '(1 2 3 4 5))
1
CL-USER> (find1 '(1 1 2 3 4 5))
2
CL-USER> (find1 '(1 1 1 2 3 1 4 5 1 1))
6
You could get rid of that unattractive progn by using cond instead of if
UPDATE: Here is an updated and more elegant version of the above, based on the comments, that I think would qualify as tail recursive as well:
(defun find1 (alist &optional (accum 0))
(let ((part (member '1 alist)))
(if part
(find1 (rest part) (+ accum 1))
accum)))
Here it is in action:
CL-USER> (find1 '(1 2 3 4))
1
CL-USER> (find1 '(1 1 1 1))
4
CL-USER> (find1 '(1 1 0 1 1))
4
CL-USER> (find1 '(0 2 1 0 1 1 0 1 1))
5

Unexpected List Duplication using Sort with Common Lisp

EDIT: The solution is to replace the '(1) with (list 1) in the first (let...) form. This is because I was trying to modify literal data. Thanks for the help! (I would give upvotes, but apparently you need 15 reputation...)
This is my first post on this site.
I was solving some Project Euler problems today and I came across some unexpected list sorting behavior (well, at least to me) in Common Lisp:
I have a function that finds all of the proper divisors of a number x:
(defun divisors (x)
"Finds all of the proper divisors of x."
(let ((sq (sqrt x)) (divs '(1)))
(when (integerp sq) (push sq divs))
(loop for i from 2 to (1- (floor sq)) do
(let ((div (/ x i)))
(when (integerp div)
(push i divs)
(push div divs))))
divs))
This function works great. For example:
(divisors 100)
==> (20 5 25 4 50 2 10 1)
The problem arises whenever I try to sort the resulting list:
(sort (divisors 100) #'<)
==> (1 2 4 5 10 20 25 50)
Well, that worked fine. But what happens when I call divisors again?
(divisors 100)
==> (20 5 25 4 50 2 10 1 2 4 5 10 20 25 50)
What? Maybe if I try a different number...
(divisors 33)
==> (11 3 1 2 4 5 10 20 25 50)
The divisors from previous queries are persistent after I sort the resulting list. If I recompile the function, I get no errors until I sort the resulting list again. I am assuming I have messed up somewhere in the function definition, but I am pretty new to Lisp and I cannot find the error. Could it be a problem with the nested (let...) forms?
Thanks in advance!
Frequently asked.
You've modified literal data. You need to cons up new data. Use the function LIST or the function to make a copy.
Rainer is right; if it isn't obvious, the code can be fixed with this change:
(let ((sq (sqrt x)) (divs (list 1)))