| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| Hi, I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] [ 1 2 ] 3 ]) to a lisp list - '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) I got to this, but it does not work (defun to-lisp (all) (let ((stack (list (list)))) (dolist (x all) (print x) (print stack) (cond ((equal (first all) '[) (push (list) stack)) ((equal (first all) ']) (let (( l (pop stack))) (setf (first stack) (append (first stack) l)))) (t (setf (first stack) (list* x (first stack)))))) stack)) Can you give me a hint? |
|
#2
| |||
| |||
| On Jan 19, 11:23 am, AngelP <angelpo...@gmail.com> wrote: > Hi, > I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] > [ 1 2 ] 3 ]) to a lisp list - > '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) > I got to this, but it does not work > (defun to-lisp (all) > (let ((stack (list (list)))) > (dolist (x all) > (print x) > (print stack) > (cond > ((equal (first all) '[) (push (list) stack)) > ((equal (first all) ']) (let (( l (pop stack))) > (setf (first stack) (append (first stack) l)))) > (t (setf (first stack) (list* x (first stack)))))) > stack)) > > Can you give me a hint? 1) (first all) will not do what you want here 2) (append '(1 2) '(3 4)) => (1 2 3 4); not (1 2 (3 4)) 3) You are putting new elements at the wrong end of a list |
|
#3
| |||
| |||
| AngelP wrote: > Hi, > I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] > [ 1 2 ] 3 ]) to a lisp list - > '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) > I got to this, but it does not work > (defun to-lisp (all) > (let ((stack (list (list)))) > (dolist (x all) > (print x) > (print stack) > (cond > ((equal (first all) '[) (push (list) stack)) > ((equal (first all) ']) (let (( l (pop stack))) > (setf (first stack) (append (first stack) l)))) > (t (setf (first stack) (list* x (first stack)))))) > stack)) > > Can you give me a hint? you mean this? or is this cheating? (defun pf-reader (stream char) (declare (ignore char)) (let ((lst (read-delimited-list #\] stream t))) lst)) (defun enable-pf-reader () (set-macro-character #\[ #'pf-reader t) (set-syntax-from-char #\] #\) )) (enable-pf-reader) (defparameter *v* nil) (setf *v* '(1 2 3 [4 5][6 [7 8]])) (format t "~s~%" *v*) |
|
#4
| |||
| |||
| On 19 ñÎ, 20:12, vanekl <va...@acd.net> wrote: > AngelP wrote: > > Hi, > > I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] > > [ 1 2 ] 3 ]) to a lisp list - > > '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) > > I got to this, but it does not work > > (defun to-lisp (all) > > (let ((stack (list (list)))) > > (dolist (x all) > > (print x) > > (print stack) > > (cond > > ((equal (first all) '[) (push (list) stack)) > > ((equal (first all) ']) (let (( l (pop stack))) > > (setf (first stack) (append (first stack) l)))) > > (t (setf (first stack) (list* x (first stack)))))) > > stack)) > > > Can you give me a hint? > > you mean this? or is this cheating? > > (defun pf-reader (stream char) > (declare (ignore char)) > (let ((lst (read-delimited-list #\] stream t))) > lst)) > > (defun enable-pf-reader () > (set-macro-character #\[ #'pf-reader t) > (set-syntax-from-char #\] #\) )) > > (enable-pf-reader) > > (defparameter *v* nil) > > (setf *v* '(1 2 3 [4 5][6 [7 8]])) > (format t "~s~%" *v*) Thanks, That is what I need. In the beginning I think it should be easy to implement, but after 3 hours trying iterative recursive and what else comes in mind. I decided to ask for help. Your solution could be a cheating, but it is nice cheating :-) Thanks |
|
#5
| |||
| |||
| On 19 ñÎ, 19:45, Brian <quickbasicg...@gmail.com> wrote: > On Jan 19, 11:23 am, AngelP <angelpo...@gmail.com> wrote: > > > Hi, > > I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] > > [ 1 2 ] 3 ]) to a lisp list - > > '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) > > I got to this, but it does not work > > (defun to-lisp (all) > > (let ((stack (list (list)))) > > (dolist (x all) > > (print x) > > (print stack) > > (cond > > ((equal (first all) '[) (push (list) stack)) > > ((equal (first all) ']) (let (( l (pop stack))) > > (setf (first stack) (append (first stack) l)))) > > (t (setf (first stack) (list* x (first stack)))))) > > stack)) > > > Can you give me a hint? > > 1) (first all) will not do what you want here > 2) (append '(1 2) '(3 4)) => (1 2 3 4); not (1 2 (3 4)) > 3) You are putting new elements at the wrong end of a list Thanks, after your comments, the solution is: (defun to-lisp (all) (let ((stack (list (list)))) (dolist (x all) (print x) (print stack) (cond ((equal x '[) (push (list) stack)) ((equal x ']) (let (( l (pop stack))) (setf (first stack) (append (first stack) (list l) )))) (t (setf (first stack) (append(first stack) (list x)))))) stack)) but is it lispish enough? |
|
#6
| |||
| |||
| On Jan 19, 1:42 pm, AngelP <angelpo...@gmail.com> wrote: > On 19 ñÎ, 19:45, Brian <quickbasicg...@gmail.com> wrote: > > > > > On Jan 19, 11:23 am, AngelP <angelpo...@gmail.com> wrote: > > > > Hi, > > > I have started with task to convert list '(1 2 3 4 [ 1 2 3 [ 1 2 ] > > > [ 1 2 ] 3 ]) to a lisp list - > > > '(1 2 3 4 ( 1 2 3 ( 1 2 ) ( 1 2 ) 3 )) > > > I got to this, but it does not work [skipped] > > > Can you give me a hint? > > > 1) (first all) will not do what you want here > > 2) (append '(1 2) '(3 4)) => (1 2 3 4); not (1 2 (3 4)) > > 3) You are putting new elements at the wrong end of a list > > Thanks, after your comments, the solution is: > > (defun to-lisp (all) > (let ((stack (list (list)))) > (dolist (x all) > (print x) > (print stack) > (cond > ((equal x '[) (push (list) stack)) > ((equal x ']) (let (( l (pop stack))) > (setf (first stack) (append (first stack)(list l) )))) > (t (setf (first stack) (append(first stack) (list x)))))) > stack)) > > but is it lispish enough? (setf accumulator (append accumulator (list elt))) is a bad (= too verbose, inefficient) lisp idiom for collecting elements into accumulator. Better use (push elt acc) and (nreverse acc) once you've finished collecting. Also, if you're using recursion, than (trace convert) would provide you with enough debugging information to understand the sequence of calls, their arguments and return values. I've come up with something like: (defun convert (lst &optional acc) (cond ((null lst) (nreverse acc)) ((eq (first lst) '[) (multiple-value-bind (a l) (convert (cdr lst)) (convert l (push a acc)))) ((eq (first lst) ']) (values (nreverse acc) (cdr lst))) (t (convert (cdr lst) (push (first lst) acc))))) Try (trace convert) and then (convert `(1 2 [ 3 4 [ 5 [ 6 7 ] 8 [ 9 10 ] ] ])) to understand how does it work. These is not the best way to solve the problem, as convert is not exactly tail recursive... Best, Victor. |
|
#7
| |||
| |||
| On Jan 19, 1:42 pm, AngelP <angelpo...@gmail.com> wrote: > Thanks, after your comments, the solution is: > > (defun to-lisp (all) > (let ((stack (list (list)))) > (dolist (x all) > (print x) > (print stack) > (cond > ((equal x '[) (push (list) stack)) > ((equal x ']) (let (( l (pop stack))) > (setf (first stack) (append (first stack) (list l) )))) > (t (setf (first stack) (append(first stack) (list x)))))) > stack)) > > but is it lispish enough? A few more: You want (first stack) at the end instead of stack and you can get rid of the print statements Now, you are doing a lot APPENDing. The PUSH and NREVERSE idiom would be more efficient: (defun to-lisp2 (all) (let ((stack (list (list)))) (dolist (x all) (cond ((equal x '[) (push (list) stack)) ((equal x ']) (let ((l (pop stack))) (push (nreverse l) (first stack)))) (t (push x (first stack))))) (nreverse (first stack)))) A quick test with your sample input showed that this version was about 2.37x faster and consed about 59% less. |
|
#8
| |||
| |||
| On Jan 19, 2:47 pm, Brian <quickbasicg...@gmail.com> wrote: > On Jan 19, 1:42 pm, AngelP <angelpo...@gmail.com> wrote:> Thanks, after your comments, the solution is: > > > (defun to-lisp (all) > > (let ((stack (list (list)))) > > (dolist (x all) > > (print x) > > (print stack) > > (cond > > ((equal x '[) (push (list) stack)) > > ((equal x ']) (let (( l (pop stack))) > > (setf (first stack) (append (first stack) (list l) )))) > > (t (setf (first stack) (append(first stack) (list x)))))) > > stack)) > > > but is it lispish enough? > > A few more: You want (first stack) at the end instead of stack and > you can get rid of the print statements > > Now, you are doing a lot APPENDing. The PUSH and NREVERSE idiom would > be more efficient: > (defun to-lisp2 (all) > (let ((stack (list (list)))) > (dolist (x all) > (cond > ((equal x '[) (push (list) stack)) > ((equal x ']) (let ((l (pop stack))) > (push (nreverse l) (first stack)))) > (t (push x (first stack))))) > (nreverse (first stack)))) > > A quick test with your sample input showed that this version was about > 2.37x faster and consed about 59% less. You don't need the second let: ((equal x ']) (push (nreverse (pop stack)) (first stack)) will work . |
|
#9
| |||
| |||
| På Sat, 19 Jan 2008 19:12:43 +0100, skrev vanekl <vanek@acd.net>: > > you mean this? or is this cheating? > I like that as it has the same meaning as [ and ] have in Scheme. You should probably have a function disable-pf-reader also unless you want all brackets in all code you compile to behave like this. (defun pf-reader (stream char) (declare (ignore char)) (let ((lst (read-delimited-list #\] stream t))) lst)) (let (old-table) (defun enable-pf-reader () (setf old-table (copy-readtable)) (set-macro-character #\[ #'pf-reader t) (set-syntax-from-char #\] #\) )) (defun disable-pf-syntax () (setf *readtable* old-table))) (defparameter *v* nil) (enable-pf-reader) (defun test () (setf *v* '(1 2 3 [4 5][6 [7 8]])) (format t "~s~%" *v*)) (disable-pf-syntax) (defun test2 () (setf *v* '(1 2 3 [4 5][6 [7 8]])) (format t "~s~%" *v*)) prints: CL-USER 1 > (test) (1 2 3 (4 5) (6 (7 8))) NIL CL-USER 2 > (test2) (1 2 3 [4 5][6 [7 8]]) NIL -------------- John Thingstad |
|
#10
| |||
| |||
| On 19 Ян, 23:33, "John Thingstad" <jpth...@online.no> wrote: > På Sat, 19 Jan 2008 19:12:43 +0100, skrev vanekl <va...@acd.net>: > > > > > you mean this? or is this cheating? > > I like that as it has the same meaning as [ and ] have in Scheme. > You should probably have a function disable-pf-reader also unless you want > all brackets in all code you compile to behave like this. > > (defun pf-reader (stream char) > (declare (ignore char)) > (let ((lst (read-delimited-list #\] stream t))) > lst)) > > (let (old-table) > (defun enable-pf-reader () > (setf old-table (copy-readtable)) > (set-macro-character #\[ #'pf-reader t) > (set-syntax-from-char #\] #\) )) > (defun disable-pf-syntax () > (setf *readtable* old-table))) > > (defparameter *v* nil) > > (enable-pf-reader) > > (defun test () > (setf *v* '(1 2 3 [4 5][6 [7 8]])) > (format t "~s~%" *v*)) > > (disable-pf-syntax) > > (defun test2 () > (setf *v* '(1 2 3 [4 5][6 [7 8]])) > (format t "~s~%" *v*)) > > prints: > > CL-USER 1 > (test) > (1 2 3 (4 5) (6 (7 8))) > NIL > > CL-USER 2 > (test2) > (1 2 3 [4 5][6 [7 8]]) > NIL > > -------------- > John Thingstad Thanks a lot! |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.