Code: Select all
(data-type (tree data children))
If the data is an integer, then an example of a node containing 2 leaf nodes is this:
Code: Select all
(tree 0 ((tree 1 ()) (tree 2 ())))
Any help is much appreciated!
Code: Select all
(data-type (tree data children))
Code: Select all
(tree 0 ((tree 1 ()) (tree 2 ())))
Code: Select all
;;---------------------------------------------------------------------------
;; Labeled binary trees.
;;---------------------------------------------------------------------------
(define (make-TREE label left right)
(list 'labeled-binary-tree label left right))
(define (is-TREE x)
(and (list? x) (= (first x) 'labeled-binary-tree)))
(define (TREE-label tree) (tree 2))
(define (TREE-left tree) (tree 3))
(define (TREE-right tree) (tree 4))
(define (set-TREE-label tree value)
(nth-set (tree 2) value))
;;---------------------------------------------------------------------------
;; Display the contents of a binary tree in depth-first order.
;;---------------------------------------------------------------------------
(define (TREE-display tree)
(cond ((null? tree))
(true (print (TREE-label tree))
(TREE-display (TREE-left tree))
(TREE-display (TREE-right tree)))))
;;---------------------------------------------------------------------------
;; Find the binary subtree with the specified label.
;;---------------------------------------------------------------------------
(define (find-subtree tree label)
(cond ((null? tree) nil)
((= label (TREE-label tree)) tree)
(true (or (find-subtree (TREE-left tree) label)
(find-subtree (TREE-right tree) label)))))
;;---------------------------------------------------------------------------
;; Build a depth 3 binary tree labeled according to depth-first traversal.
;;---------------------------------------------------------------------------
(define (make-depth-3-binary-tree )
(make-TREE 1 (make-TREE 2 (make-TREE 3 '()'())
(make-TREE 4 '()'()))
(make-TREE 5 (make-TREE 6 '()'())
(make-TREE 7 '()'()))))
;;---------------------------------------------------------------------------
;; Build a depth n binary tree labeled according to depth-first traversal.
;;---------------------------------------------------------------------------
(define (make-binary-tree n)
(make-depth-n-binary-tree n 1))
(define (make-depth-n-binary-tree depth root-label)
(cond ((= depth 0) '())
(true (make-TREE root-label
(make-depth-n-binary-tree (- depth 1)
(+ root-label 1))
(make-depth-n-binary-tree (- depth 1)
(+ root-label
(exp 2 (- depth 1))))))))
Read chapter "17. Object-Oriented Programming in newLISP" in the latest development version 9.2.8 manual.Also, I do not want this to be a solution involving creating a context for every object, because I want to be able to refer to these things anonymously and in general that's not a very elegant solution as it requires that you have a naming scheme for your context symbols
Code: Select all
(set-TREE-label (find-subtree tree 5) 2000)
Code: Select all
(set 'my-tree (make-depth-3-binary-tree))
(println (find-subtree my-tree 3))
Code: Select all
(define (TREE-label tree) (tree 1))
(define (TREE-left tree) (tree 2))
(define (TREE-right tree) (tree 3))
(define (set-TREE-label tree value)
(nth-set (tree 1) value))
Code: Select all
(set 'my-tree (make-depth-3-binary-tree))
(set-TREE-label (find-subtree my-tree 3) 2000)
(println "3: " (find-subtree my-tree 3))
(println "2000: " (find-subtree my-tree 2000))
Code: Select all
3: nil
2000: (labeled-binary-tree 2000 () ())
Code: Select all
...(ATOM ((STATE "SOLID")) (NAME "Gold") (ATOMIC_WEIGHT "196.9665")
(ATOMIC_NUMBER "79")
(OXIDATION_STATES "3, 1")
(BOILING_POINT ((UNITS "Kelvin")) "3130")...
Code: Select all
(set 'gold-ref (ref "Gold" sxml))
;-> (0 8 2 1)
Code: Select all
(sxml (chop gold-ref))
;-> (NAME "Gold")
Code: Select all
(nth-set (sxml (chop gold-ref)) (list 'NAMES (list 'ENGLISH (sxml gold-ref)) (list 'LATIN "Aurum")))
Code: Select all
... (ATOM ((STATE "SOLID")) (NAMES (ENGLISH "Gold") (LATIN "Aurum"))
(ATOMIC_WEIGHT "196.9665")
(ATOMIC_NUMBER "79") ...
Oh... why yes, most definitely. :)cormullion wrote:Are you thinking about speed? The need for speed...?! :)
It's for my artificial intelligence final class project. I was originally planning on using a tree, but since I ran out of time I decided to go with a simpler method... Essentially I wrote a program in newLISP that tried its best to eliminate as many pieces as possible from a ChainShot game.cormullion wrote:I wonder how big your lists are going to be... What's the application, out of interest?
Well actually the binary tree was just an example, the original tree that I had in mind was like the one I gave in the first post, where it could have an arbitrary number of children. The main thing I wanted to be able to do was to quickly add/remove children from it.Lutz wrote:Perhaps you are looking for is some sort of associative data access. A way to access a piece of information via a key pointing to a data-value. This is what binary-trees are used for in 99% of the cases.
Yeah I've read that, those are cool, but not exactly what I needed for this project. I still think you should consider adding the 'unsafe-ref' function (or something like it). :-DnewLISP has bult-in very fast associative data access by usage of contexts/namespaces, which internally are binary trees (the red-black kind of optiized binary tree.
Here is short chapter in the manual with examples, which might help you:
http://newlisp.org/downloads/newlisp_manual.html#hash
Lutz
Code: Select all
;; Simple memory allocation hack ;-)
;;
(context 'memory)
(if (not n)
(set 'n 0))
(define (memory:new)
(inc 'n)
(sym (string "p" n)))
(set 'EMPTY-FIELD 'VOID)
(define (memory:delete ptr)
(set ptr EMPTY-FIELD))
(define (memory:write ptr data)
(if (!= (eval ptr) EMPTY-FIELD)
(set ptr data)
(throw-error (string "Memory field " ptr " does not exist!"))))
(define (memory:read ptr)
(if (!= (eval ptr) EMPTY-FIELD)
(eval ptr)
(throw-error (string "Memory field " ptr " does not exist!"))))
(context MAIN)
Code: Select all
;; *** Demo ***
;; p = malloc(sizeof(int));
(set 'p (memory:new)) ; => memory:p1
;; *p = 10;
(memory:write p 10) ; => 10
;; x = *p;
(set 'x (memory:read p)) ; => 10
;; free(p);
(memory:delete p) ; => memory:VOID
;; access error
(memory:read p)
=>
user error : Memory field p1 does not exist!
called from user defined function memory:read
Code: Select all
;; * Binary tree *
; btree -> (data left-btree right-btree)
(define (btree-create-leaf ptr v)
(set ptr (memory:new))
(memory:write (eval ptr) (list v nil nil)))
(define (btree-add ptr v)
(let (p nil ind 0)
(if (< v (first (memory:read ptr)))
(set 'ind 1)
(set 'ind 2))
(if (!= ((memory:read ptr) ind) nil)
(btree-add ((memory:read ptr) ind) v)
(begin
(btree-create-leaf 'p v)
(memory:write ptr (set-nth ((memory:read ptr) ind) p))))))
; fill it with numbers
(set 'numbers (randomize (sequence 1 10)))
(btree-create-leaf 'btree (first numbers))
(dolist (x (rest numbers))
(btree-add btree x))
Code: Select all
> numbers
(4 8 1 2 6 10 9 7 5 3)
> btree
memory:p1
> (memory:read btree)
(4 memory:p3 memory:p2)
> (memory:read 'memory:p3)
(1 nil memory:p4)
> (memory:read 'memory:p2)
(8 memory:p5 memory:p6)
> (memory:read 'memory:p4)
(2 nil memory:p10)
> (memory:read 'memory:p5)
(6 memory:p9 memory:p8)
> (memory:read 'memory:p6)
(10 memory:p7 nil)
Wow, that's pretty neat. It's still doing a context-like trick by using named symbols for the pointers, and evaluating a pointer takes log(n) time (b/c of the red-black tree), but that's still a really cool trick. Thanks for sharing!Fanda wrote:I implemented a simple memory allocation hack:
Well, almost, it's kinda difficult to make newLISP that bad. ;-)Fanda wrote:Using this approach, code readability goes down to... lets say... C/C++ ;-)))
Yeah, I think I might actually, once I finish all my finals for school. Then if there's time I might enter it into the '07 newLISP competition. :-Dcormullion wrote:Nice project. Perhaps you could add a GUI to it one day..!itistoday wrote:Essentially I wrote a program in newLISP that tried its best to eliminate as many pieces as possible from a ChainShot game.