(defun sum-n-numbers(n)(if(=n 1)
1
(+N(sum-n-numbers(-n 1)))))
Edit 2:(defun sum-n-numbers(n)
(if(=n 1)
1
(+N(sum-n-numbers(-n 1))
)
)
)
The above code runs but when I type (SUM-N-NUMBERS 1 3 2) for the output,it does not work and I get errors.
I know this simple code can also be executed by the inbuild lisp function (+ 1 3 2) that automatically calculates the sum of the numbers,but I have an exam question where it is asked to calculate the sum of n numbers using the defun function.
Edit 1: This is the error that I am getting:
Error: Call ((LAMBDA (#:N) (DECLARE (SPECIAL:SOURCE #) (LAMBDA-NAME SUM-N-NUMBERS)) (BLOCK #:SUM-N-NUMBERS (IF # 1 #))) 1 3 2) has the wrong number of arguments.
1 (abort) Return to level 1.
2 Return to debug level 1.
3 Return to level 0.
4 Return to top loop level 0.
What's wrong with:
(apply '+ '(1 3 2))
??
(defun sum (numbers)
(if (null numbers)
0
(+ (first numbers) (sum (rest numbers)))))
(sum '(1 3 2))
Didn't test. I don't have a lisp interpreter at hand.
To get exactly what you want:
(defun sum-n-numbers (&rest nums)
(if (null nums) 0
(+ (car nums) (apply #'my-sum (cdr nums)))))
This will take an arbitrary number of arguments and recursively compute their sum. For instance:
(sum-n-numbers 1 2 3) => 6
Using iteration, not recursion:
(defun sum-n-numbers (&rest nums)
(loop for num in nums summing num))
From the user's point of view, these are the same, just a little bit different in how they work inside. And I've tested both of these to ensure they work.
The function you wrote accepts one argument and returns the sum of of numbers from 1 to the argument (note that it will never return - theoretically - and fail with a stack overflow - in practice - for negative arguments).
That function cannot accept 3 arguments you passed to it, so you got an error.
Related
CL-USER> (a-sum 0 3)
->> 6
I wrote this program :
(defun a-sum (x y)
(if (and (> x -1) (> y -1))
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1)))
(setq sum (+ sum num))
(setq num (+ num 1))
sum)
(print " NOPE")))
put if I run it in the terminal it returns nil and not the answer stated above;
can someone help with the problem so it returns the value then Boolean.
DO,DO* Syntax
The entry for DO,DO* says that the syntax is as follows:
do ({var | (var [init-form [step-form]])}*)
(end-test-form result-form*)
declaration*
{tag | statement}*
The body is used as a list of statements and no intermediate value in this body is used as the result form of the do form. Instead, the do form evaluates as the last expression in result-form*, which defaults to nil.
(do ((i 0 (1+ i))
(sum 0)
(num x))
((equal i (+ (- y x) 1))
;;; RESULT FORMS HERE
)
(setq sum (+ sum num)) ;; (*)
(setq num (+ num 1)) ;; (*)
sum ;; (*)
)
All the expressions marked commented (*) above are used for side-effects only: the result of their evaluation is unused and discarded.
Problem statement
It is not clear to me what Σpi=ni means, and your code does not seem to compute something that could be expressed as that mathematical expression.
One red flag for example is that if (+ (- y x) 1) is negative (i.e. if y < x-1, for example y=1,x=3), then your loop never terminates because i, which is positive or null, will never be equal to the other term which is negative.
I would try to rewrite the problem statement more clearly, and maybe try first a recursive version of your algorithm (whichever is easier to express).
Remarks
Please indent/format your code.
Instead of adding setq statements in the body, try to see if you can define them in the iteration clauses of the loop (since I'm not sure what you are trying to achieve, the following example is only a rewrite of your code):
(do ((i 0 (1+ i))
(sum 0 (+ sum num)
(num x (1+ num))
(... sum))
Consider what value(s) a function returns. It's the value of the last form evaluated. In your case, that appears to be a do or maybe a setq or print (It's difficult to read as it's formatted now, and I don't have question edit privileges).
In short, the form that's returning the value for the function looks to be one evaluated for side-effects instead of returning a value.
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))
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)
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.
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