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.