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


i working on problem occurence of prime in list in lisp. input: write function (occurencesofprimes < list >) counts number of primes in (possibly nested) list.

output: example: (occurencesofprimes (((1)(2))(5)(3)((8)3)) returns 4.

i using below code getting error like:

(  defun occurencesofprimes (list)         (loop 2 100              ( setq isprime t)             (loop j 2                 never (zerop (mod j))                     (setq isprime f)                     (break)             )         )         (if (setq isprime t)             (append list i)         )         )     )  loop: illegal syntax near (setq isprime f) in (loop j 2 never (zerop (mod j)) (setq isprime f) (break) 

)

any help.

it important keep format consistent expected conventions of language. helps when reading code (in particular other programmers), , can see errors.

also, should use editor which, @ minimum, keep tracks of parentheses. in emacs, when put cursor in first opening parenthesis, matching parenthesis highlighted. can spot have 1 additional parenthesis serves no purpose.

(  defun occurencesofprimes (list)         (loop 2 100              ( setq isprime t)             (loop j 2                 never (zerop (mod j))                     (setq isprime f)                     (break)             )         )         (if (setq isprime t)             (append list i)         )         ) ;; <- end of defun     ) ;; <- closes nothing 

in lisp, parentheses computer, whereas indentation humans. tools can automatically indent code according structure (the parenthesis), , discrepancy between indentation expect , 1 being computed hint code badly formed. if @ indentation of expressions, can see how deep in form, , alone helps understand code.

symbol names dash-separated, not camlcased.

your code, remarks:

(defun occurences-of-primes (list)   ;; argument list, given name , way   ;; call append below. never iterate on list.   ;; suspicious.   (loop      2 100              (setq is-prime t) ;; setting undeclared variable        (loop           j 2           never (zerop (mod j))              ;; following 2 forms not expected here according             ;; loop's grammar; setting is-prime f, f not             ;; existing variable. if want set false, use             ;; nil instead.             (setq is-prime f)              ;; break enters debugger, maybe wanted use             ;; loop-finish instead, never clause above should             ;; enough exit loop             ;; sub-expression evaluates nil.             (break)))    ;; return value of (setq x v) v, here test   ;; succeed.   (if (setq is-prime t)       ;; append returns new list, without modifying       ;; arguments. in particular, list not modified. note "i"       ;; unknown @ point, because bindings effective       ;; inside loop not visible in scope. besides, "i"       ;; number, not list.       (append list i))) 

original question

write 1 function counts occurrences of prime number in (possibly nested) list.

even though homework questions says "write 1 function", not should write 1 big function compute @ once. could write 1 such big function, if split problem sub-problems, end different auxiliary functions, which:

  1. are simpler understand (they 1 thing)
  2. can reused build other functions

the sub-problems are, example: how determine if number prime? how iterate on tree (a.k.a. possibly nested list)? how count occurrences?

the basic idea write "is-prime" function, iterate on tree , call "is-prime" on each element; if element prime , never seen before, add 1 counter, local function.

you can flatten input tree, obtain list, sort resulting list; iterate on list while keeping track of last value seen: if value same previous one, know if number prime; if previous number differs, have test if number prime first.

you abstract things little more, , define higher-order tree-walker function, calls function on each leaf of tree. , write higher-order function "memoizes" calls: wraps around function f if call f same arguments before, returns result stored instead of recomputing it.

example

i'll combine above ideas because if give answer teacher have explain each part (and if can, great you); not "best" answer, covers 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               d 3 upto (isqrt n) 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, don't want remove duplicates count multiple times prime number occurs, can do:

(count-if (memoize #'prime-p) (flatten tree)) 

... 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 useless if there no duplicates)


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -