how to return the value of a prime number while trying to print the sum of prime numbers in a range of numbers from check-prime to prime-sum - lisp

I was working on this question to print the sum of prime numbers in a range of numbers. The range values will be be taken as an input from the user. I got the syntax errors all cleared out but could not figure out how to return the value of the prime no. to the sum if it is true.
(defun check-prime(num)
(if (= num 1) nil)
;(setq i 2)
(loop for i from 2 to ( isqrt num) do
(if (= (mod num i) 0) nil t)
(= i (+ i 1))
)
)
(defun prime-sum(*begin* *end*)
(defvar *s* 0)
(defvar *i* *end*)
(loop for *i* from *end* to *begin* do
;i= 13
(if (check-prime *i*)
(= *s* (+ *s* *i* ) )
)
(= *i* (- *i* 1))
)
(write *s*)
)
(defun vals()
(print "enter the range1: ")
(defvar *begin* (read))
(print "enter the range2: ")
(defvar *end* (read))
(prime-sum *begin* *end*)
)
(print(vals))
;b =4
;e 13

Here is your function, cleaned up a bit and formatted in a conventional way:
(defun check-prime(num)
(if (= num 1) nil)
(loop
for i from 2 to (isqrt num)
do
(if (= (mod num i) 0) nil t)
(= i (+ i 1))))
There are multiple things that are incorrect, and they boil down to how are Lisp forms evaluated.
There is a special form progn in Common Lisp that is used to evaluate a list of expressions, with the following pattern:
(progn E1 E2 ... EN)
A lot of other functions in Lisp are described has having "an implicit progn", that's the case for defun which allows for more than one expression in its body, but since the progn doesn't appear literally it is implicit. The behavior is however always the same: each expression E1 to EN is evaluated in sequence, and evaluation of the whole progn are the values returned by the last expression, EN (that's where the N comes from in the name). In other words, the intermediate values from E1 etc. are discarded, the expressions are only useful for their side-effects.
In your code, that's the case for (if (= num 1) nil), which is an expression in the body of defun which is not the last one, and which doesn't even have side-effects. It is thus completely useless.
Likewise, in the loop macro, all that follows the do keyword are expressions that are evaluated for their side effects and do not contribute to the resulting value of the whole loop form.
In fact, loop is a bit complicated but here your don't have any accumulating clause in your loop (something like collect, append, sum etc. that would compute a result). Instead, your loop will always return nil.
Note also that for i from 2 to (isqrt num) takes care of incrementing i, you don't have to do it yourself like you tried in the do. Moreover, = is a comparison operator, in order to mutate i you would need to use setf instead: (setf i (+ i 1)), or (incf i) (which I repeat is unnecessary here).
To combine the first two expressions, I would write:
(if (= num 1) nil ...)
Where ... is the loop: because if is a functional if, it evaluates to whichever branch is selected by the condition.
And inside the loop, I would use never:
(loop for i from 2 to (isqrt num) never (= 0 (mod num i)))
The never clause makes the loop compute a boolean and halt as soon as the result is false.

Related

a function called A-SUM that calculates Σpi=ni, where n≥0,p≥0. Below are examples of what A-SUM returns considering different arguments

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.

Sum of odd and even numbers

I'm new to lisp programming and I'm trying to create a program that accept six numbers and check whether each number is either odd or even number.
(princ"Input six number: ")
(setq a(read))
(setq b(read))
(setq c(read))
(setq d(read))
(setq e(read))
(setq f(read))
(format t "~% ~d" a)
(format t "~% ~d" b)
(format t "~% ~d" c)
(format t "~% ~d" d)
(format t "~% ~d" e)
(format t "~% ~d" f)
(if(= 0(mod a 2))
(print"even")
(print"odd"))
(if(= 0(mod b 2))
(print"even")
(print"odd"))
(if(= 0(mod c 2))
(print"even")
(print"odd"))
(if(= 0(mod d 2))
(print"even")
(print"odd"))
(if(= 0(mod e 2))
(print"even")
(print"odd"))
(if(= 0(mod f 2))
(print"even")
(print"odd"))
(terpri)
You have a lot of code that looks like this:
(if(= 0(mod ... 2))
(print"even")
(print"odd"))
(this might be a copy/paste problem but in your question they are indented more and more to the right. They are however not nested, they are all at the same depth (they are toplevel expressions) so by convention they should not be indented).
A first step would be to factor them using a function like this one:
(defun check-even-odd (number)
(if (= 0 (mod number 2))
(print "even")
(print "odd")))
The above defines a function named check-even-odd of one parameter number, and it applies the same logic you originally had for any arbitrary number.
The rest of your code can be simplified as:
(check-even-odd a)
(check-even-odd b)
(check-even-odd c)
(check-even-odd d)
(check-even-odd e)
(check-even-odd f)
Now, you can define two additional global variables:
(defparameter total-even 0)
(defparameter total-odd 0)
Each of them holds a sum, and is initialized to 0.
You can rewrite the check-even-odd function as follows to update the counters. First of all, let's just rewrite the current code by using cond, since we are going to need to perform multiple actions in each case, and if only accepts one expression for each branch (the combination if and progn is a bit ugly):
(defun check-even-odd (number)
(cond
((= 0 (mod number 2))
(print "even"))
(t
(print "odd"))))
This above behaves as the original code.
In order to increment a variable by a certain amount, you can use INCF:
(defun check-even-odd (number)
(cond
((= 0 (mod number 2))
(print "even")
(incf total-even number))
(t
(print "odd")
(incf total-odd number))))
When you execute your whole script, the total will be initialized to zero, then each call to check-even-odd will add the number to the appropriate counter.
Notes:
You may find other places where you can use functions to abstract duplicated code
You should use defparameter instead of setq when initializing a, b, etc, because otherwise the variables are not declared and calling setq on undeclared variables is not standard
In fact, it is possible to rewrite the whole program without having any global state, this could be a good next exercise
You can generalize for less or more numbers instead of 6, you would need to write a loop or a recursive function to repeat the same code an arbitrary amount of time
Input/output may need to be flushed (see finish-output, clear-input) otherwise you could experience strange behavior when the underlying stream is buffered.

lisp (prime number) code not working

this is a code that takes an input and prints if it is prime or not
the last if always prints "false" , why ?
(print "Enter a positive integer")
(setq num (read))
(setq i 2)
(setq prime t)
(loop
(if(=(rem num i)0)(setq prime nil) break)
(incf i)
(when (<= (/ num 2)i)(return t))
)
(if()(print "True")(print "False"))
In Common Lisp the false value, the empty list and the symbol nil is the same. Disregarding every line of code except the last is basically:
(if nil ; nil is false
(print "True")
(print "False"))
So here false is always false so it will always pick the alternative (print "False"). That is why.
Other errors:
In this code is setq variables i and prime without defineing them and since they will be special they should have been given *earmuffs* so that you see they are in contrast to lexical bindings.
The loop macro is slightly odd in the way it does not use any loop macro keywords. There is a evaluation of the variable break that seem to be undefined. The loop macro is a whole different syntax and language by itself that you need to learn in the same manner as lisp. It is not lispy in it's syntax.
You should abstract. Make functions that do some work good. Use them in you code. Here is what I gathered you wanted to do:
(defun primep (num)
(loop :for i :from 2 :to (/ num 2)
:never (zerop (rem num i))))

function (OccurencesOfPrimes < list >) which counts the number of primes in a (possibly nested) list

I am working on problem to get the occurence of Prime in a list in lisp.
Input:
Write a function (OccurencesOfPrimes < list >) which counts the number of primes in a (possibly nested) list.
Output: Example: (OccurencesOfPrimes (((1)(2))(5)(3)((8)3)) returns 4.
I am using the below code but getting the error like:
(
defun OccurencesOfPrimes (list)
(loop for i from 2 to 100
do ( setq isPrime t)
(loop for j from 2 to i
never (zerop (mod i j))
(setq isPrime f)
(break)
)
)
(if (setq isPrime t)
(append list i)
)
)
)
LOOP: illegal syntax near (SETQ ISPRIME F) in
(LOOP FOR J FROM 2 TO I NEVER (ZEROP (MOD I J)) (SETQ ISPRIME F) (BREAK)
)
Any help.
It is important to keep the format consistent with the expected conventions of the language. It helps when reading the code (in particular with other programmers), and can help you see errors.
Also, you should use an editor which, at the minimum, keep tracks of parentheses. In Emacs, when you put the cursor in the first opening parenthesis, the matching parenthesis is highlighted. You can spot that you have one additional parenthesis that serves no purpose.
(
defun OccurencesOfPrimes (list)
(loop for i from 2 to 100
do ( setq isPrime t)
(loop for j from 2 to i
never (zerop (mod i j))
(setq isPrime f)
(break)
)
)
(if (setq isPrime t)
(append list i)
)
) ;; <- end of defun
) ;; <- closes nothing
In Lisp, parentheses are for the computer, whereas indentation is for humans. Tools can automatically indent the code according to the structure (the parenthesis), and any discrepancy between what indentation you expect and the one being computed is a hint that your code is badly formed. If you look at the indentation of your expressions, you can see how deep you are in the form, and that alone helps you understand the code.
Symbol names are dash-separated, not camlCased.
Your code, with remarks:
(defun occurences-of-primes (list)
;; You argument is likely to be a LIST, given its name and the way
;; you call APPEND below. But you never iterate over the list. This
;; is suspicious.
(loop
for i from 2 to 100
do
(setq is-prime t) ;; setting an undeclared variable
(loop
for j from 2 to i
never (zerop (mod i j))
;; the following two forms are not expected here according
;; to LOOP's grammar; setting IS-PRIME to F, but F is not
;; an existing variable. If you want to set to false, use
;; NIL instead.
(setq is-prime f)
;; BREAK enters the debugger, maybe you wanted to use
;; LOOP-FINISH instead, but the NEVER clause above should
;; already be enough to exit the loop as soon as its
;; sub-expression evaluates to NIL.
(break)))
;; The return value of (SETQ X V) is V, so here your test would
;; always succeed.
(if (setq is-prime t)
;; Append RETURNS a new list, without modifying its
;; arguments. In particular, LIST is not modified. Note that "I"
;; is unknown at this point, because the bindings effective
;; inside the LOOP are not visible in this scope. Besides, "I"
;; is a number, not a list.
(append list i)))
Original question
Write one function which counts all the occurrences of a prime number in a (possibly nested) list.
Even though the homework questions says "write one function", it does not say that you should write one big function that compute everything at once. You could write one such big function, but if you split your problem into sub-problems, you will end with different auxiliary functions, which:
are simpler to understand (they do one thing)
can be reused to build other functions
The sub-problems are, for example: how to determine if a number is a prime? how to iterate over a tree (a.k.a. a possibly nested list)? how to count
the occurrences?
The basic idea is to write an "is-prime" function, iterate over the tree and call "is-prime" on each element; if the element is prime and was never seen before, add 1 to a counter, local to your function.
You can also flatten the input tree, to obtain a list, then sort the resulting
list; you iterate over the list while keeping track of the last
value seen: if the value is the same as the previous one, you
already know if the number is prime; if the previous number differs, then
you have to test if the number is prime first.
You could also abstract things a little more, and define a higher-order tree-walker function, which calls a function on each leaf of the tree. And write another higher-order function which "memoizes" calls: it wraps around a
function F so that if you call F with the same arguments as before,
it returns the result that was stored instead of recomputing it.
Example
I'll combine the above ideas because if you give that answer to a teacher you are likely to have to carefully explain what each part does (and if you can, great for you); this is not necessarily the "best" answer, but it covers a lot of things.
(defun tree-walk-leaves (tree function)
(typecase tree
(null nil)
(cons
(tree-walk-leaves (car tree) function)
(tree-walk-leaves (cdr tree) function))
(t (funcall function tree))))
(defun flatten (tree &optional keep-order-p)
(let ((flat nil))
(tree-walk-leaves tree (lambda (leaf) (push leaf flat)))
(if keep-order-p
(nreverse flat)
flat)))
(defun prime-p (n)
(or (= n 2)
(and (> n 2)
(oddp n)
(loop
for d from 3 upto (isqrt n) by 2
never (zerop (mod n d))))))
(defun count-occurences-of-prime (tree)
(count-if #'prime-p (remove-duplicates (flatten tree))))
(count-occurences-of-prime '(((1)(2))(5)(3)((8)3)))
=> 4
If, instead, you don't want to remove duplicates but count the multiple times a prime number occurs, you can do:
(count-if (memoize #'prime-p) (flatten tree))
... where memoize is:
(defun memoize (function &key (test #'equalp) (key #'identity))
(let ((hash (make-hash-table :test test)))
(lambda (&rest args)
(let ((args (funcall key args)))
(multiple-value-bind (result exists-p) (gethash args hash)
(values-list
(if exists-p
result
(setf (gethash args hash)
(multiple-value-list (apply function args))))))))))
(memoize is useless if there are no duplicates)

`A' is not of the expected type `REAL'

The code below server to show the number of integer in a list.
(defun isNum (N)
(and (<= N 9) (>= N 0)))
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
(((and (<= N 9) (>= N 0))) item)(incf count))
(setq(0 + count))))))
I get the error A' is not of the expected typeREAL' when I run the command
(count-numbers '(3 4 5 6 a 7 b) )
I'm surprised it runs at all, given that your cond is improperly constructed, you switch to infix notation in the unnecessarily side-effect-generating bit of your code and you're using unbound variables in count-numbers. Hypothetically, if it did run, that error sounds about right. You're doing numeric comparisons on a parameter (and those error on non-numeric input).
I've got my codereview hat on today, so lets go through this a bit more in-depth.
Lisp (it actually doesn't matter which, afaik this applies to CL, Scheme and all the mongrels) uses lower-case-snake-case-with-dashes, and not lowerCamelCase for variable and function names.
(defun is-num (n)
(and (<= n 9) (>= n 0)))
Common Lisp convention is to end a predicate with p or -p rather than begin them with is-. Scheme has the (IMO better) convention of ending predicates with ? instead
(defun num-p (n)
(and (<= n 9) (>= n 0)))
((and (<= N 9) (>= N 0))) is not how you call a function. You actually need to use its name, not just attempt to call its body. This is the source of one of the many errors you'd get if you tried to run this code.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((num-p item) item)(incf count))
(setq(0 + count))))))
numberp already exists, and does a type check on its input rather than attempting numeric comparisons. You should probably use that instead.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((numberp item) item)(incf count))
(setq(0 + count))))))
((numberp item) item) (incf count)) probably doesn't do what you think it does as a cond clause. It actually gets treated as two separate clauses; one checks whether item is a number, and returns it if it is. The second tries to check the variable incf and returns count if it evaluates to t (which it doesn't, and won't). What you seem to want is to increment the counter count when you find a number in your list, which means you should put that incf clause in with the item.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
(setq (0 + count)))))
(setq (0 + count)) is the wrong thing for three reasons
You seem to have tripped back into infix notation, which means that the second bit there is actually attempting to call the function 0 with the variables + and count as arguments.
You don't have a second part to the setq, which means you're trying to set the above to NIL implicitly.
You don't actually need to set anything in order to return a value
At this point, we finally have a piece of code that will evaluate and run properly (and it doesn't throw the error you mention above).
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
count)))
dolist is an iteration construct that does something for each element in a given list. That means you don't actually need to test for list termination manually with that cond. Also, because dolist doesn't collect results, there's no reason to return item to it. You're also unnecessarily shadowing the local count you declare in the let.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list)
(when (numberp item) (incf count)))
count))
As usual, you can do all this with a simpler loop call.
(defun count-numbers (list)
(loop for item in list
when (numberp item) sum 1))
which makes the counter implicit and saves you from needing to return it manually. In fact, unless this was specifically an exercise to write your own iteration function, Common Lisp has a built in count-if, which takes predicate sequence [some other options] and returns the count of items in sequence that match predicate. If you wanted to name count-numbers specifically, for stylistic reasons, you could just
(defun count-numbers (list) (count-if #'numberp list))
and be done with it.
In conclusion, good try, but please try reading up on the language family for realzies before asking further questions.
Yet another way to do it would be:
(reduce
#'(lambda (a b)
(if (numberp b) (1+ a) a))
'(3 4 5 6 a 7 b) :initial-value 0) ; 5
I.e. process the sequence in a way that you are given at each iteration the result of the previous iteration + the next member of the sequence. Start with zero and increment the result each time the element in the sequence is a number.
EDIT
Sorry, I haven't seen Inaimathi mentioned count-if. That would be probably better.