Nelly
Nelly

Reputation: 309

number of sub-lists in a list, having an even sum, from odd levels in Lisp

I have a non-linear list. I need to find out the number of sub-lists at any level in the initial list, for which the sum of the numerical atoms at the odd levels, is an even number. The superficial level is counted as 1. I wrote something like:

 (defun numbering (l level)
 ;counts the levels that verify the initial conditions 
 (cond
       ((null l) l)
       ((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l))))
       (T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
 )
 )

 (defun verify (n)
 ;returns true if the parameter "n" is even, or NIL, otherwise
 (cond
      ((numberp n)(= (mod n 2) 0))
      (T f)
 )
 )

 (defun sumlist (l)
 ;returns the sum of the numerical atoms from a list, at its superficial level
 (cond
      ((null l) 0)
      ((numberp (car l)) (+ (car l) (sumlist(cdr l))))
      (T (sumlist(cdr l)))
 )
 )

 (defun mainNumbering (l)
 ; main function, for initializing the level with 1
      (numbering l 1)
 )

If I run "(mainnum '(1 2 (a b 4) 8 (6 g)))" I get the error: " Undefined function MAPCAR# called with arguments ((LAMBDA (A) (NUMEROTARE A #)) (1 2 (A B 4) 8 (6 G)))."

Does anyone know, what am I missing? Thanks in advance!

Upvotes: 0

Views: 319

Answers (3)

sss
sss

Reputation: 1

in numbering you should add the case when l is a number,so (defun numbering (l level) ;counts the levels that verify the initial conditions

(cond
   ((null l) l)
   ((atom l)0)
   ((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar #' (lambda (a) (numbering a (+ 1 level))) l))))
  (T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
 )
)

will resolve the problem

Upvotes: 0

Renzo
Renzo

Reputation: 27424

Here is a possible solution, if I have interpreted correctly your specification:

(defun sum(l)
  (loop for x in l when (numberp x) sum x))

(defun test(l &optional (level 1))
  (+ (if (and (oddp level) (evenp (sum l))) 1 0)
     (loop for x in l when (listp x) sum (test x (1+ level)))))

(test '(1 2 (a b 4) 7 (6 2 g) (7 1 (2 (3) (4 4) 2) 1 a)))  ;  => 2

The function sum applied to a list returns the sum of all its numbers (without entering in its sublists).

The function test, for a list with an odd level, sum its numbers, and, if the result is even, add 1 to the sum of the results of the function applied to the sublists of l, 0 otherwise.

Upvotes: 0

sheikh_anton
sheikh_anton

Reputation: 3452

Well, that's true, there is no such function as mapcar#, it's just a typo, you missing space in this line:

(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))

It should be:

(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))

Upvotes: 1

Related Questions