Code for calculating difference of sets not working

You have problems, and we're glad to hear them. Explain the problem, what you have tried, and where you got stuck.
Feel free to share a little info on yourself and the course.
Forum rules
Please respect your teacher's guidelines. Homework is a learning tool. If we just post answers, we aren't actually helping. When you post questions, be sure to show what you have tried or what you don't understand.

Code for calculating difference of sets not working

Postby kiwifreak3 » Sat Jun 09, 2012 8:42 am

Hi everyone,
I'm trying to write a program (in emacslisp) to calculate the difference of two lists; could someone give me a hint as to why my code is returning an error saying "invalid function...", when I try it on an example?
I'd be grateful for help,
Thanks
Code: Select all
(defun diff (A B)
; calculates A\B
(setq index 0)
(if (or (equal A []) (equal B []))
    (print A)
(; else:
(while (< index (length A))
(
(if (string-equal (elt A index) (car B))
    ((aset A index (elt A 0)) (setq A (cdr A)))
)
(setq index (+ index 1))
)
)
(diff (A (cdr B)))
)
)
)
(diff [1 a c 5] [1 3 "foo" 4 7])
kiwifreak3
 
Posts: 5
Joined: Sat Jun 09, 2012 8:23 am

Re: Code for calculating difference of sets not working

Postby Ramarren » Sun Jun 10, 2012 12:06 am

In Lisp all parentheses are usually meaningful, they are not just grouping/block delimiters. In your case you have superfluous parentheses around the else branch of IF and around the body of WHILE. This makes the system interpret those as function calls, and an entire expression does not name a function.

Additionally even with this fixed your code will not work. In EmacsLisp arrays and lists are different types, and CAR and CDR will not work on the former. Also you shouldn't just SETQ variables. Establish variables with LET.
Ramarren
 
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland

Re: Code for calculating difference of sets not working

Postby kiwifreak3 » Sun Jun 10, 2012 2:04 am

Thanks a lot Ramarren, you really helped me out there... I see I made quite some mistakes; I think I've got rid of them now although I'm still using the setq command within the while-loop, because I can't quite figure out where I should put the end-bracket of let otherwise (- perhaps after the end-bracket of the while-loop?)
perhaps someone could look at my new code; I think I'm nearly there - it's just returning nil instead of A\B...
I'd be grateful!
Code: Select all
(defun diff (A B)
; calculates A\B
(if (or (equal 0 (length A)) (equal 0 (length B)))
   A
; else:
(let ((index 0))
(while (< index (length A))
(if (equal (elt A index) (car B))
    (aset A index (elt A 0)) (setq A (cdr A))
)
(setq index (+ 1 index))
)
)
(diff A (cdr B))
)
)
(diff '(a b c d e) '(d e f g h))
kiwifreak3
 
Posts: 5
Joined: Sat Jun 09, 2012 8:23 am

Re: Code for calculating difference of sets not working

Postby Ramarren » Sun Jun 10, 2012 5:17 am

kiwifreak3 wrote:I think I've got rid of them now although I'm still using the setq command within the while-loop, because I can't quite figure out where I should put the end-bracket of let otherwise


Sorry, I misspoke, you shouldn't create variables with SETQ, because they will be set as global variables and leak out of your function, and it also risks changing a variable with the same name which belongs to a surrounding context. Inside a LET which establishes your own context for the variable using SETQ is fine.

You are trying to use both iteration and recursion, and modifying the list at the same time. This seems overly complicated. I suggest using a nested iteration and an accumulator variable. That is, use LET to initialize a variable to NIL, and then PUSH on it. To decide what to push use a loop over A. To check if an element of A is in B use MEMBER or implement an equivalent if you can only use primitives. Don't forget to return you accumulator (possibly REVERSE'd, if order seems important) and the end of the function.

Rather than using index and ELT to loop over lists you should probably either use DOLIST or at least a (while list-variable ... (setq list-variable (cdr list-variable))). Note that in EmacsLisp empty list is false, and so can be used as a termination condition.
Ramarren
 
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland

Re: Code for calculating difference of sets not working

Postby kiwifreak3 » Sun Jun 10, 2012 6:23 am

Tanks so much, that realy is so much more simple than my version...
Code: Select all
; calculates A\B
(let (C)
  (dolist (element A)
    (if (not (member element B))
   (push element C)
    )
  )
C
)
)
(diff '(a b a c d) '(c d e d e f))
kiwifreak3
 
Posts: 5
Joined: Sat Jun 09, 2012 8:23 am


Return to Homework

Who is online

Users browsing this forum: No registered users and 0 guests

cron