applyintree =: 2 : 0
i =. >^:((1=#)@>) {. n
(u`(u applyintree (}.n))@.(1<#n)&.:> i{y) i} y
:
i =. >^:((1=#)@>) {. n
((x&u)`(x&(u applyintree (}.n)))@.(1<#n)&.:> i{y) i} y
)
NB. where depth vector is sorted nodes by parent/child relationship. No skipped
depths or boxing levels.
NB. use {:: to get map of tree.
NB. Nodes form tree hierarchy represented as parent(s) (, <) children
NB. result boxes have value -1 for (sub)parent node, 0 for leaf node
depth2box =: <: leaf@:({. , <@}.)@:(<;.(1)~ 1 , 2&(( 1 = ])/\))^:(1 <#)
leaf(^:_)
NB. x in format of 2 column table of leaves and paths. y is matching preboxed
structure to fill.
appintreeV =: 4 : 'for_i. x do. y=. (> {. i) [ applyintree ( > {: i) y end.'
NB. y depthvector restricted by depth2box conditions. x nodes.
NB.maketreefromdepth =: (] appintreeV~ boxopen"_1@[ ,. < S:1@:{::@]) depth2box
maketreefromdepth =: (] appintreeV~ boxopen"_1@[ ,. < S:1@:({. L:0)@:{::@])
depth2box NB. {:: creates non scalar indexes. Applyintree requires scalars.
(maketreefromdepth~ (i.@#)) 0 1 2 2 1 1 2 2 2 3
┌─┬───────────────────────────────┐
│0│┌─────────┬─┬─────────────────┐│
│ ││┌─┬─────┐│4│┌─┬─────────────┐││
│ │││1│┌─┬─┐││ ││5│┌─┬─┬───────┐│││
│ │││ ││2│3│││ ││ ││6│7│┌─┬───┐││││
│ │││ │└─┴─┘││ ││ ││ │ ││8│┌─┐│││││
│ ││└─┴─────┘│ ││ ││ │ ││ ││9││││││
│ ││ │ ││ ││ │ ││ │└─┘│││││
│ ││ │ ││ ││ │ │└─┴───┘││││
│ ││ │ ││ │└─┴─┴───────┘│││
│ ││ │ │└─┴─────────────┘││
│ │└─────────┴─┴─────────────────┘│
└─┴───────────────────────────────┘
I think this is the right representation... parent node has one adjacent box
for its children.
Each box in that box is a child.
If a child has children, then recursively the cell is divided into 2 boxes.
Left is parent, right contains children one level below.
On Friday, August 7, 2020, 12:13:27 p.m. EDT, ethiejiesa via Programming
<[email protected]> wrote:
Thanks for the thoughts!
> not as pretty, but simpler and pretty enough?
>
> (":"0@i.@# (,~ #&'-')"1 0 ]) 0 1 2 2 1 1 2 2 3
>
> 0
>
> -1
>
> --2
>
> --3
>
> -4
>
> -5
>
> --6
>
> --7
>
> ---8
This is sort of in between the raw depth vector and the graph representation.
It's probably fine for smallish trees, but especially with larger trees, I find
it hard to visually pick out subtrees. For that, the explicit links between
sibling nodes is really helpful.
Otherwise, an even more minimal "mountain graph" is probably serviceable:
(=/ ~.) d
1 0 0 0
0 1 0 0
0 0 1 0
0 0 1 0
0 1 0 0
0 1 0 0
0 0 1 0
0 0 1 0
0 0 0 1
> J has several functions built in to process trees that are represented as
> nested box structures, and so may be useful in converting from various
> representations to and from such boxed structures. Or more interesting to
> me, but I need more thought on this.
It really depends. Nested boxes require quite a lot of overhead, no? Pilfering
the structure of an example tree from Voc, Appendix A (Foreign Conjunction),
Representation (5!:) [0]:
[ s=: (((0;1;2);3;<4;5));6;7 NB. Nested box representation
┌─────────────────┬─┬─┐
│┌───────┬─┬─────┐│6│7│
││┌─┬─┬─┐│3│┌─┬─┐││ │ │
│││0│1│2││ ││4│5│││ │ │
││└─┴─┴─┘│ │└─┴─┘││ │ │
│└───────┴─┴─────┘│ │ │
└─────────────────┴─┴─┘
7!:5 <'s'
512
[ t=: 0 1 2 3 3 3 2 2 3 3 1 1 NB. Depth vector representation
7!:5 <'t'
256
That said, it would be neat if we could trick (5!:4) into pretty-printing (s)
for us.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm