0

I have

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d))) 

(defun drumuri (l3) 
  (cond ((atom l3) (cons l3 nil))
     (t (append
           (cons (car l3) nil)
           (drumuri (cadr l3))
           (cons (car l3) nil)
           (drumuri (caddr l3))))))

(drumuri l2)

and it gives me:

 Break 2 
[4]>     DRUMURI
 Break 2 
[4]>     (1 2 B 2 C 1 C B 1 A 1 2 1 NIL A D)

but i need:

((1 2 B)(1 2 C 1)(1 2 C B)(1 A 1 2)(1 A D)) 

Ok good news i found some of the answers:

(setq l2 '(1 (2 b (c 1 b))(a (1 2) d)))
( defun drumuri (l3) 
( cond ( (atom l3) ( cons l3 nil))
       (t (append  ( cons ( car l3 ) nil)
          (drumuri ( cadr l3) )))))
          (drumuri l2)

and the answer to that is:

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D))
[2]> 
DRUMURI
[3]> 
(1 2 B)

Next is the second answer:

(defun drumuri (l4) 
    (cond ((atom l4)(cons l4 nil))
    ( t   ( append  (cons ( car l4)nil)
        (drumuri ( caddr l4))))))
            (drumuri l2)

and the answer to that is:

[1]> 
(1 (2 B (C 1 B)) (A (1 2) D))
[2]> 
DRUMURI
[3]> 
(1 A D)

So all that is left is to find:

(1 2 C 1) (1 2 C B) (1 A 1 2)

4
  • please format your code and replace the tabs with spaces - select the text and press the "101010" button on the editor. Commented May 14, 2010 at 17:34
  • Indentation is very important for clarity when programming Lisp. I've fixed this for you, but please keep it mind for future. Commented May 15, 2010 at 5:43
  • thanks but can you help with code Commented May 15, 2010 at 6:01
  • marcelo thanks but its still do not work like it has to Commented May 15, 2010 at 8:55

1 Answer 1

1

A tricky problem. Not particularly complex, but with some finicky edges. Since this is obviously homework, I'm going to try to help you, but at the same time avoid just spoon-feeding you (and possibly fail at one or both of these goals). So I've written it in Python. Hopefully that's far enough away from Lisp that you'll still have to do a good slab of thinking for yourself.

>>> import operator
>>> def drumuri(a):
...     if isinstance(a, list):
...         return reduce(operator.add,
...                       [[a[:1] + d for d in drumuri(x)] for x in a[1:]])
...     else:
...         return [[a]]
... 
>>> drumuri( [1, [2, 'b', ['c', 1, 'b']], ['a', [1, 2], 'd']] )
[[1, 2, 'b'], [1, 2, 'c', 1], [1, 2, 'c', 'b'], [1, 'a', 1, 2], [1, 'a', 'd']]
>>> 

Here's the key insight lacking from your Lisp version. Because drumuri is recursive, every level must return the same kind of structure to its caller: a list of paths, where each path is a list. In short, drumuri must always return a list of lists. Your leaf case returns a list containing a single atom.

You are also making some mistakes with the use of append, but the leaf issue is probably bending everything else out of shape.

EDIT: Let's see if can help you discover the solution for yourself. Follow these steps:

  1. Write a function called prepend-to-paths that takes a single head and a list of paths, and returns a list of paths with the head added to the front of each original path. It should work as follows:

    > (prepend-to-paths 1 '((2 B) (2 C 1) (2 C B) (A 1 2) (A D))) ;'
    ((1 2 B) (1 2 C 1) (1 2 C B) (1 A 1 2) (1 A D))
    
  2. Write a function called convert-to-paths that takes a list of unprocessed tail elements and converts them to paths. Rather than doing all the work itself, however, it should only worry about mapping the input to a list of paths (relying on the as-yet unwritten drumuri to map each element) and then concatenating the returned lists of paths into a single list of paths. The output (once drumuri exists) should be like so:

    > (convert-to-paths '((2 b (c 1 b)) (a (1 2) d))) ;'
    ((2 B) (2 C 1) (2 C B) (A 1 2) (A D))
    
  3. Write the drumuri function. It should use cond as per your original, but replace the leaf case with an expression that returns the atom as a list of paths:

    > (drumuri 'b) ;'
    ((b))
    

    Then replace the (append ...) with code that uses the functions you wrote in the previous steps to transform the head and tail of the input list input a list of paths.

  4. Once the three functions are working together nicely, you could try to figure out how to fold the first two into the body of drumuri. Note that the end-result of this may be structurally different to the Python solution I gave.

If and when you get stuck, just update your question with whatever progress you've made and whatever code you've managed to cobble together.

Sign up to request clarification or add additional context in comments.

4 Comments

marcelo thanks a lot, if only you can help with append and positioning the car, cddr, or other stuff that would be great ...i am at my limit with this program :(
If you use a two-level map operation, you won't need caddr, just car and cdr. I might see if I can offer a bit more help later today (I'm late for work right now; sorry).
i did a few answers, but im out of solutions sooo please hellpppp :( Marcelo
I've updated my answer with a step-by-step walk-through of one possible solution (slightly different to the Python one).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.