convert to lists

This is a discussion on convert to lists within the lisp forums in Programming Languages category; 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 ...

Go Back   Application Development Forum > Programming Languages > lisp

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 01-19-2008, 12:23 PM
AngelP
Guest
 
Default convert to lists

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?
Reply With Quote
  #2  
Old 01-19-2008, 12:45 PM
Brian
Guest
 
Default Re: convert to lists

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
Reply With Quote
  #3  
Old 01-19-2008, 01:12 PM
vanekl
Guest
 
Default Re: convert to lists

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*)
Reply With Quote
  #4  
Old 01-19-2008, 02:27 PM
AngelP
Guest
 
Default Re: convert to lists

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

Reply With Quote
  #5  
Old 01-19-2008, 02:42 PM
AngelP
Guest
 
Default Re: convert to lists

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?
Reply With Quote
  #6  
Old 01-19-2008, 03:35 PM
vtail
Guest
 
Default Re: convert to lists

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.
Reply With Quote
  #7  
Old 01-19-2008, 03:47 PM
Brian
Guest
 
Default Re: convert to lists

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.
Reply With Quote
  #8  
Old 01-19-2008, 03:56 PM
vtail
Guest
 
Default Re: convert to lists

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 .
Reply With Quote
  #9  
Old 01-19-2008, 04:33 PM
John Thingstad
Guest
 
Default Re: convert to lists

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
Reply With Quote
  #10  
Old 01-19-2008, 05:05 PM
AngelP
Guest
 
Default Re: convert to lists

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!
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 10:43 PM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.