(nstree(:require[clojure.spec.alpha:ass]))(s/def::valueany?)(s/def::children(s/coll-of::tree:kindvector?))(s/def::tree(s/keys:req-un[::value]:opt-un[::children]))(defprotocolTreeOperations"Protocol defining fundamental tree operations"(add-child[thischild-value]"Adds a new child node with the specified value")(remove-child[thisindex]"Removes the child at the specified index")(update-node-value[thisnew-value]"Updates the value of the current node")(get-child-at[thisindex]"Gets the child node at the specified index")(get-tree-depth[this]"Calculates the depth of the tree")(get-tree-size[this]"Calculates the total number of nodes in the tree"))(defrecordTreeNode[valuechildren]TreeOperations(add-child[thischild-value](let[new-child(->TreeNodechild-value[])](if(s/valid?::treenew-child)(updatethis:children(fnilconj[])new-child)(throw(ex-info"Invalid child node"{:valuechild-value:spec-error(s/explain-str::treenew-child)})))))(remove-child[thisindex](if(and(>=index0)(<index(count(:childrenthis))))(updatethis:children#(vec(concat(subvec%0index)(subvec%(incindex)))))this))(update-node-value[thisnew-value](let[updated(assocthis:valuenew-value)](if(s/valid?::treeupdated)updated(throw(ex-info"Invalid node value"{:valuenew-value:spec-error(s/explain-str::treeupdated)})))))(get-child-at[thisindex](get-inthis[:childrenindex]))(get-tree-depth[this](if(empty?(:childrenthis))1(inc(applymax(mapget-tree-depth(:childrenthis))))))(get-tree-size[this](inc(reduce+0(mapget-tree-size(:childrenthis))))))(defncreate-tree"Creates a new tree with the specified value"[value](let[tree(->TreeNodevalue[])](if(s/valid?::treetree)tree(throw(ex-info"Invalid tree structure"{:valuevalue:spec-error(s/explain-str::treetree)})))))(defnpre-order"Performs a pre-order traversal of the tree"[tree](when(s/valid?::treetree)(cons(:valuetree)(mapcatpre-order(:childrentree)))))(defnpost-order"Performs a post-order traversal of the tree"[tree](when(s/valid?::treetree)(concat(mapcatpost-order(:childrentree))[(:valuetree)])))(defnbreadth-first"Performs a breadth-first traversal of the tree"[tree](when(s/valid?::treetree)(loop[queue[tree]result[]](if(empty?queue)result(let[current(firstqueue)](recur(concat(restqueue)(:childrencurrent))(conjresult(:valuecurrent))))))))(defnfind-node"Finds a node in the tree that satisfies the predicate"[treepred](when(s/valid?::treetree)(cond(predtree)tree(empty?(:childrentree))nil:else(some#(find-node%pred)(:childrentree)))))(defnmap-tree"Applies function f to each node value in the tree"[ftree](when(s/valid?::treetree)(->TreeNode(f(:valuetree))(mapv#(map-treef%)(:childrentree)))))(comment(defsample-tree(->(create-tree1)(add-child2)(add-child3)(add-child4)))(defnested-tree(->sample-tree(add-child5)(add-child6)))(pre-ordernested-tree);; => (1 2 3 4 5 6)(post-ordernested-tree);; => (2 3 4 5 6 1)(breadth-firstnested-tree);; => [1 2 3 4 5 6](get-tree-depthnested-tree);; => 2(get-tree-sizenested-tree);; => 6(map-tree#(*2%)nested-tree);; => TreeNode with doubled values(find-nodenested-tree#(=3(:value%)));; => TreeNode{:value 3, :children []})