Tree from nesting levels: Difference between revisions

Added C#
(J: draft implementation)
(Added C#)
 
(23 intermediate revisions by 9 users not shown)
Line 34:
===Iterative===
 
<langsyntaxhighlight lang="applescript">on treeFromNestingLevels(input)
set maxLevel to 0
repeat with thisLevel in input
Line 80:
set output to output as text
set AppleScript's text item delimiters to astid
return output</langsyntaxhighlight>
 
{{output}}
<langsyntaxhighlight lang="applescript">"{} nests to: {}
{1, 2, 4} nests to: {1, {2, {{4}}}}
{3, 1, 3, 1} nests to: {{{3}}, 1, {{3}}, 1}
{1, 2, 3, 1} nests to: {1, {2, {3}}, 1}
{3, 2, 1, 3} nests to: {{{3}, 2}, 1, {{3}}}
{3, 3, 3, 1, 1, 3, 3, 3} nests to: {{{3, 3, 3}}, 1, 1, {{3, 3, 3}}}"</langsyntaxhighlight>
 
===Recursive===
 
Same task code and output as above.
<langsyntaxhighlight lang="applescript">on treeFromNestingLevels(input)
script recursion
property emptyList : {}
Line 119:
return recursion's recurse(input, 1)
end treeFromNestingLevels</langsyntaxhighlight>
 
 
Line 126:
:# a generic ''forestFromNestLevels'' function to map from a normalised input list to a generic tree, and
:# a standard catamorphism over trees (''foldTree'') to generate both the nested list format, and the round-trip regeneration of a sparse list from the generic tree.
<langsyntaxhighlight lang="applescript">----------------- FOREST FROM NEST LEVELS ----------------
 
-- forestFromNestLevels :: [(Int, a)] -> [Tree a]
Line 581:
end repeat
v
end |until|</langsyntaxhighlight>
<pre>
INPUT -> NESTED -> ROUND-TRIP
Line 593:
=={{header|C++}}==
Uses C++20
<langsyntaxhighlight lang="cpp">#include <any>
#include <iostream>
#include <iterator>
Line 674:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 695:
[3, 3, 3, 1, 1, 3, 3, 3] Nests to:
[[[3, 3, 3]], 1, 1, [[3, 3, 3]]]
</pre>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|12}}
<syntaxhighlight lang="csharp">public static class TreeFromNestingLevels
{
public static void Main()
{
List<int[]> tests = [[], [1,2,4], [3,1,3,1], [1,2,3,1], [3,2,1,3], [3,3,3,1,1,3,3,3]];
Console.WriteLine($"{"Input",24} -> {"Nested",-32} -> Round-trip");
foreach (var test in tests) {
var tree = BuildTree(test);
string input = $"[{string.Join(", ", test)}]";
string roundTrip = $"[{string.Join(", ", tree.ToList())}]";
Console.WriteLine($"{input,24} -> {tree,-32} -> {roundTrip}");
}
}
 
private static Tree BuildTree(int[] levels)
{
Tree root = new(0);
Tree current = root;
foreach (int level in levels) {
while (current.Level > level) current = current.Parent;
current = current.Parent.Add(level);
}
return root;
}
 
private class Tree
{
public int Level { get; }
public Tree Parent { get; }
private readonly List<Tree> children = [];
 
public Tree(int level, Tree? parent = null)
{
Level = level;
Parent = parent ?? this;
}
 
public Tree Add(int level)
{
if (Level == level) return this;
Tree tree = new(Level + 1, this);
children.Add(tree);
return tree.Add(level);
}
 
public override string ToString() => children.Count == 0
? (Level == 0 ? "[]" : $"{Level}")
: $"[{string.Join(", ", children.Select(c => c.ToString()))}]";
 
public List<int> ToList()
{
List<int> list = [];
ToList(this, list);
return list;
}
 
private static void ToList(Tree tree, List<int> list)
{
if (tree.children.Count == 0) {
if (tree.Level > 0) list.Add(tree.Level);
} else {
foreach (Tree child in tree.children) {
ToList(child, list);
}
}
}
 
}
 
}</syntaxhighlight>
{{out}}
<pre>
Input -> Nested -> Round-trip
[] -> [] -> []
[1, 2, 4] -> [1, [2, [[4]]]] -> [1, 2, 4]
[3, 1, 3, 1] -> [[[3]], 1, [[3]], 1] -> [3, 1, 3, 1]
[1, 2, 3, 1] -> [1, [2, [3]], 1] -> [1, 2, 3, 1]
[3, 2, 1, 3] -> [[[3], 2], 1, [[3]]] -> [3, 2, 1, 3]
[3, 3, 3, 1, 1, 3, 3, 3] -> [[[3, 3, 3]], 1, 1, [[3, 3, 3]]] -> [3, 3, 3, 1, 1, 3, 3, 3]</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
 
const TreeData1: array [0..0] of integer = (0);
const TreeData2: array [0..2] of integer = (1, 2, 4);
const TreeData3: array [0..3] of integer = (3, 1, 3, 1);
const TreeData4: array [0..3] of integer = (1, 2, 3, 1);
const TreeData5: array [0..3] of integer = (3, 2, 1, 3);
const TreeData6: array [0..7] of integer = (3, 3, 3, 1, 1, 3, 3, 3);
 
 
function GetDataString(Data: array of integer): string;
var I: integer;
begin
Result:='[';
for I:=0 to High(Data) do
begin
if I<>0 then Result:=Result+', ';
Result:=Result+IntToStr(Data[I]);
end;
Result:=Result+']';
end;
 
 
function GetNestingLevel(Data: array of integer): string;
var Level,Level2: integer;
var I,J,HLen: integer;
begin
Level:=0;
Result:='';
for I:=0 to High(Data) do
begin
Level2:=Data[I];
if Level2>Level then for J:=Level to Level2-1 do Result:=Result+'['
else if Level2<Level then
begin
for J:=Level-1 downto Level2 do Result:=Result+']';
Result:=Result+', ';
end
else if Level2=0 then
begin
Result:='[]';
break;
end
else Result:=Result+', ';
Result:=Result+IntToStr(Level2);
Level:=Level2;
if (I<High(Data)) and (Level<Data[I+1]) then Result:=Result+', ';
end;
for J:=Level downto 1 do Result:=Result+']';
end;
 
 
procedure ShowNestData(Memo: TMemo; Data: array of integer);
begin
Memo.Lines.Add(GetDataString(Data)+' Nests to: ');
Memo.Lines.Add(GetNestingLevel(Data));
Memo.Lines.Add('');
end;
 
procedure ShowNestingLevels(Memo: TMemo);
var S: string;
begin
ShowNestData(Memo,TreeData1);
ShowNestData(Memo,TreeData2);
ShowNestData(Memo,TreeData3);
ShowNestData(Memo,TreeData4);
ShowNestData(Memo,TreeData5);
ShowNestData(Memo,TreeData6);
end;
 
 
 
</syntaxhighlight>
{{out}}
<pre>
[0] Nests to:
[]
 
[1, 2, 4] Nests to:
[1, [2, [[4]]]]
 
[3, 1, 3, 1] Nests to:
[[[3]], 1, [[3]], 1]
 
[1, 2, 3, 1] Nests to:
[1, [2, [3]], 1]
 
[3, 2, 1, 3] Nests to:
[[[3], 2], 1, [[3]]]
 
[3, 3, 3, 1, 1, 3, 3, 3] Nests to:
[[[3, 3, 3]], 1, 1, [[3, 3, 3]]]
 
 
Elapsed Time: 21.513 ms.
 
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Tree_from_nesting_levels}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Tree from nesting levels 01.png]]
In '''[https://formulae.org/?example=Tree_from_nesting_levels this]''' page you can see the program(s) related to this task and their results.
 
'''Test cases'''
 
[[File:Fōrmulæ - Tree from nesting levels 02.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 03.png]]
 
Notice that in Fōrmulæ an array of arrays (of the same cardinality each) is automatically shown as a matrix.
 
[[File:Fōrmulæ - Tree from nesting levels 04.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 05.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 06.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 07.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 08.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 09.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 10.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 11.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 12.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 13.png]]
 
'''Other test cases'''
 
Cases generated with random numbers:
 
[[File:Fōrmulæ - Tree from nesting levels 14.png]]
 
[[File:Fōrmulæ - Tree from nesting levels 15.png]]
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vb">Sub ShowTree(List() As Integer)
Dim As Integer I, NestLevel = 0
For I = 0 To Ubound(List)
While List(I) < NestLevel
Print "]";
NestLevel -= 1
Wend
If List(I) = 0 Then
Print
Elseif I <> Lbound(List) Then Print ", ";
End If
While List(I) > NestLevel
Print "[";
NestLevel += 1
Wend
If NestLevel <> 0 Then Print NestLevel;
Next I
End Sub
 
Dim As Integer list(0 To ...) = {0}
ShowTree(list())
Dim As Integer list0(0 To ...) = {1, 2, 4, 0}
ShowTree(list0())
Dim As Integer list1(0 To ...) = {3, 1, 3, 1, 0}
ShowTree(list1())
Dim As Integer list2(0 To ...) = {1, 2, 3, 1, 0}
ShowTree(list2())
Dim As Integer list3(0 To ...) = {3, 2, 1, 3, 0}
ShowTree(list3())
Dim As Integer list4(0 To ...) = {3, 3, 3, 1, 1, 3, 3, 3, 0}
ShowTree(list4())
Dim As Integer list5(0 To ...) = {1, 2, 4, 2, 2, 1, 0}
ShowTree(list5())
 
Sleep</syntaxhighlight>
{{out}}
<pre> 'Note that [0] displays nothing.
[ 1, [ 2, [[ 4]]]]
[[[ 3]], 1, [[ 3]], 1]
[ 1, [ 2, [ 3]], 1]
[[[ 3], 2], 1, [[ 3]]]
[[[ 3, 3, 3]], 1, 1, [[ 3, 3, 3]]]
[ 1, [ 2, [[ 4]], 2, 2], 1]</pre>
 
=={{header|Go}}==
===Iterative===
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 748 ⟶ 1,015:
fmt.Printf("%17s => %v\n", fmt.Sprintf("%v", test), nest)
}
}</langsyntaxhighlight>
 
{{out}}
Line 762 ⟶ 1,029:
===Recursive===
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 803 ⟶ 1,070:
fmt.Printf("%17s => %v\n", fmt.Sprintf("%v", test), nest)
}
}</langsyntaxhighlight>
 
{{out}}
Line 811 ⟶ 1,078:
 
=={{header|Guile}}==
<langsyntaxhighlight Schemelang="scheme">;; helper function that finds the rest that are less than or equal
(define (rest-less-eq x ls)
(cond
Line 847 ⟶ 1,114:
 
(run-examples examples)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 871 ⟶ 1,138:
See ''sparseLevelsFromTree'' below:
 
<langsyntaxhighlight lang="haskell">{-# LANGUAGE TupleSections #-}
 
import Data.Bifunctor (bimap)
Line 939 ⟶ 1,206:
(x, Just x) :
(succ x, Nothing) : normalised (y : xs)
| otherwise = (x, Just x) : normalised (y : xs)</langsyntaxhighlight>
{{Out}}
<pre>From: []
Line 1,046 ⟶ 1,313:
Without any use cases for these trees, it's difficult to know if any implementation is correct.
 
As a side note here, the notation used to describe these trees has some interesting consequences in the context of J:
Therefore, initially, we'll take the simplest implementation which satisfies an interpretation of the description of the task.
 
<syntaxhighlight lang="j"> [[[3]], 1, [[3]], 1
<lang J> <^:]each ''
1 1
[[[3]], 1, [[3]], 1]
|syntax error</syntaxhighlight>
 
But, on a related note, there are type issues to consider -- in J's type system, a box (which is what we would use here to represent a tree node) cannot exist in a tuple with an integer. A box can, however, contain an integer. This makes a literal interpretation of the task somewhat... difficult. We might, hypothetically, say that we are working with boxes containing integers and that it's these boxes which must achieve a specific nesting level. (If we fail to make this distinction then we wind up with a constraint which forces some tree nodes to be structured different from what appears to be the task specification. Whether or not this is an important issue is difficult to determine without use cases. So, for now, let's assume that this is an important distinction.)
<^:]each 1 2 4
 
┌───┬─────┬─────────┐
Anyways, here's an interpretation which might be close enough to the task description:
│┌─┐│┌───┐│┌───────┐│
 
││1│││┌─┐│││┌─────┐││
<syntaxhighlight lang="j">NB. first we nest each integer to the required depth, independently
│└─┘│││2│││││┌───┐│││
NB. then we recursively merge deep boxes
│ ││└─┘│││││┌─┐││││
NB. for consistency, if there are no integers, we box that empty list
│ │└───┘│││││4│││││
dtree=: {{
│ │ ││││└─┘││││
<^:(0=L.) merge <^:]each y
│ │ │││└───┘│││
}}
│ │ ││└─────┘││
 
│ │ │└───────┘│
merge=: {{
└───┴─────┴─────────┘
if.(0=#$y)+.2>L.y do.y return.end. NB. done if no deep boxes left
<^:]each 3 1 3 1
shallow=. 2 > L."0 y NB. locate shallow boxes
┌───────┬───┬───────┬───┐
group=. shallow} (+/\ shallow),:-#\y NB. find groups of adjacent deep boxes
│┌─────┐│┌─┐│┌─────┐│┌─┐│
merge each group ,each//. y NB. combine them and recursively merge their contents
││┌───┐│││1│││┌───┐│││1││
}}</syntaxhighlight>
│││┌─┐│││└─┘│││┌─┐│││└─┘│
 
││││3││││ ││││3││││ │
Task example:
│││└─┘│││ │││└─┘│││ │
 
││└───┘││ ││└───┘││ │
<syntaxhighlight lang="j"> dtree ''
│└─────┘│ │└─────┘│ │
┌┐
└───────┴───┴───────┴───┘
││
<^:]each 1 2 3 1
└┘
┌───┬─────┬───────┬───┐
dtree 1 2 4
│┌─┐│┌───┐│┌─────┐│┌─┐│
┌─────────────┐
││1│││┌─┐│││┌───┐│││1││
│┌─┬─────────┐│
│└─┘│││2│││││┌─┐│││└─┘│
││1│┌─┬─────┐││
│ ││└─┘│││││3││││ │
││ ││2│┌───┐│││
│ │└───┘│││└─┘│││ │
││ ││ ││┌─┐││││
│ │ ││└───┘││ │
││ ││ │││4│││││
│ │ │└─────┘│ │
││ ││ ││└─┘││││
└───┴─────┴───────┴───┘
││ ││ │└───┘│││
<^:]each 3 2 1 3
││ │└─┴─────┘││
┌───────┬─────┬───┬───────┐
│└─┴─────────┘│
│┌─────┐│┌───┐│┌─┐│┌─────┐│
└─────────────┘
││┌───┐│││┌─┐│││1│││┌───┐││
dtree 3 1 3 1
│││┌─┐│││││2│││└─┘│││┌─┐│││
┌─────────────────┐
││││3│││││└─┘││ ││││3││││
│┌─────┬─┬─────┬─┐│
│││└─┘│││└───┘│ │││└─┘│││
││┌───┐│1│┌───┐│1││
││└───┘││ │ ││└───┘││
│││┌─┐││ ││┌─┐││ ││
│└─────┘│ │ │└─────┘│
││││3│││ │││3│││ ││
└───────┴─────┴───┴───────┘
│││└─┘││ ││└─┘││ ││
<^:]each 3 3 3 1 1 3 3 3
││└───┘│ │└───┘│ ││
┌───────┬───────┬───────┬───┬───┬───────┬───────┬───────┐
│└─────┴─┴─────┴─┘│
│┌─────┐│┌─────┐│┌─────┐│┌─┐│┌─┐│┌─────┐│┌─────┐│┌─────┐│
└─────────────────┘
││┌───┐│││┌───┐│││┌───┐│││1│││1│││┌───┐│││┌───┐│││┌───┐││
dtree 1 2 3 1
│││┌─┐│││││┌─┐│││││┌─┐│││└─┘│└─┘│││┌─┐│││││┌─┐│││││┌─┐│││
┌─────────────┐
││││3│││││││3│││││││3││││ │ ││││3│││││││3│││││││3││││
│┌─┬───────┬─┐│
│││└─┘│││││└─┘│││││└─┘│││ │ │││└─┘│││││└─┘│││││└─┘│││
││1│┌─┬───┐│1││
││└───┘│││└───┘│││└───┘││ │ ││└───┘│││└───┘│││└───┘││
││ ││2│┌─┐││ ││
│└─────┘│└─────┘│└─────┘│ │ │└─────┘│└─────┘│└─────┘│
││ ││ ││3│││ ││
└───────┴───────┴───────┴───┴───┴───────┴───────┴───────┘</lang>
││ ││ │└─┘││ ││
││ │└─┴───┘│ ││
│└─┴───────┴─┘│
└─────────────┘
dtree 3 2 1 3
┌─────────────────┐
│┌───────┬─┬─────┐│
││┌───┬─┐│1│┌───┐││
│││┌─┐│2││ ││┌─┐│││
││││3││ ││ │││3││││
│││└─┘│ ││ ││└─┘│││
││└───┴─┘│ │└───┘││
│└───────┴─┴─────┘│
└─────────────────┘
dtree 3 3 3 1 1 3 3 3
┌─────────────────────────┐
│┌─────────┬─┬─┬─────────┐│
││┌───────┐│1│1│┌───────┐││
│││┌─┬─┬─┐││ │ ││┌─┬─┬─┐│││
││││3│3│3│││ │ │││3│3│3││││
│││└─┴─┴─┘││ │ ││└─┴─┴─┘│││
││└───────┘│ │ │└───────┘││
│└─────────┴─┴─┴─────────┘│
└─────────────────────────┘</syntaxhighlight>
 
Note that merge does not concern itself with the contents of boxes, only their nesting depth. This means that we could replace the implementation of dtree with some similar mechanism if we wished to use this approach with something else. For example:
 
<syntaxhighlight lang="j"> t=: ;:'(a b c) d (e f g)'
p=: ;:'()'
d=: +/\-/p=/t
k=: =/p=/t
merge d <@]^:[&.>&(k&#) t
┌───────┬─┬───────┐
│┌─┬─┬─┐│d│┌─┬─┬─┐│
││a│b│c││ ││e│f│g││
│└─┴─┴─┘│ │└─┴─┴─┘│
└───────┴─┴───────┘</syntaxhighlight>
 
Or, generalizing:
 
<syntaxhighlight lang="j">pnest=: {{
t=. ;:y NB. tokens
p=. (;:'()')=/t NB. paren token matches
d=: +/\-/p NB. paren token depths
k=: =/p NB. keep non-paren tokens
merge d <@]^:[&.>&(k&#) t NB. exercise task
}}</syntaxhighlight>
 
Example use:
 
<syntaxhighlight lang="j"> pnest '((a b) c (d e) f) g (h i)'
┌─────────────────┬─┬─────┐
│┌─────┬─┬─────┬─┐│g│┌─┬─┐│
││┌─┬─┐│c│┌─┬─┐│f││ ││h│i││
│││a│b││ ││d│e││ ││ │└─┴─┘│
││└─┴─┘│ │└─┴─┘│ ││ │ │
│└─────┴─┴─────┴─┘│ │ │
└─────────────────┴─┴─────┘</syntaxhighlight>
 
=={{header|Java}}==
 
<syntaxhighlight lang="java">
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
public final class TreeNestingLevels {
 
public static void main(String[] args) {
List<List<Integer>> lists = List.of(
Arrays.asList(),
Arrays.asList( 1, 2, 4 ),
Arrays.asList( 3, 1, 3, 1 ),
Arrays.asList( 1, 2, 3, 1 ),
Arrays.asList( 3, 2, 1, 3 ),
Arrays.asList( 3, 3, 3, 1, 1, 3, 3, 3 )
);
for ( List<Integer> list : lists ) {
List<Object> tree = createTree(list);
System.out.println(list + " --> " + tree);
}
}
private static List<Object> createTree(List<Integer> list) {
return makeTree(list, 0, 1);
}
private static List<Object> makeTree(List<Integer> list, int index, int depth) {
List<Object> tree = new ArrayList<Object>();
int current;
while ( index < list.size() && depth <= ( current = list.get(index) ) ) {
if ( depth == current ) {
tree.add(current);
index += 1;
} else {
tree.add(makeTree(list, index, depth + 1));
final int position = list.subList(index, list.size()).indexOf(depth);
index += ( position == -1 ) ? list.size() : position;
}
}
return tree;
}
}
</syntaxhighlight>
{{ out }}
<pre>
[] --> []
[1, 2, 4] --> [1, [2, [[4]]]]
[3, 1, 3, 1] --> [[[3]], 1, [[3]], 1]
[1, 2, 3, 1] --> [1, [2, [3]], 1]
[3, 2, 1, 3] --> [[[3], 2], 1, [[3]]]
[3, 3, 3, 1, 1, 3, 3, 3] --> [[[3, 3, 3]], 1, 1, [[3, 3, 3]]]
</pre>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">function makenested(list)
nesting = 0
str = isempty(list) ? "[]" : ""
Line 1,126 ⟶ 1,514:
end
 
</langsyntaxhighlight>{{out}}
<pre>
[] => []
Line 1,139 ⟶ 1,527:
In a strongly and statically typed language as Nim, there is no way to mix integer values and lists. So, we have defined a variant type <code>Node</code> able to contain either an integer value or a list of Node objects, depending on the value of a discriminator. The procedure <code>newTree</code> converts a list of levels into a list of nodes with the appropriate nesting.
 
<langsyntaxhighlight Nimlang="nim">import sequtils, strutils
 
type
Line 1,185 ⟶ 1,573:
@[3, 2, 1, 3],
@[3, 3, 3, 1, 1, 3, 3, 3]]:
echo ($list).align(25), " → ", newTree(list)</langsyntaxhighlight>
 
{{out}}
Line 1,194 ⟶ 1,582:
@[3, 2, 1, 3] → [[[3], 2], 1, [[3]]]
@[3, 3, 3, 1, 1, 3, 3, 3] → [[[3, 3, 3]], 1, 1, [[3, 3, 3]]]</pre>
 
=={{header|OxygenBasic}}==
 
<syntaxhighlight lang="text">
uses console
declare DemoTree(string src)
DemoTree "[]"
DemoTree "[1, 2, 4]"
DemoTree "[3, 1, 3, 1]"
DemoTree "[1, 2, 3, 1]"
DemoTree "[3, 2, 1, 3]"
DemoTree "[3, 3, 3, 1, 1, 3, 3, 3]"
pause
end
 
/*
RESULTS:
========
 
[]
[]
 
[1, 2, 4]
[ 1,[ 2,[[ 4]]]]
 
[3, 1, 3, 1]
[[[ 3]], 1,[[ 3]], 1]
 
[1, 2, 3, 1]
[ 1,[ 2,[ 3]], 1]
 
[3, 2, 1, 3]
[[[ 3], 2], 1,[[ 3]]]
 
[3, 3, 3, 1, 1, 3, 3, 3]
[[[ 3, 3, 3]], 1, 1,[[ 3, 3, 3]]]
*/
 
 
 
sub DemoTree(string src)
========================
 
string tree=nuls 1000 'TREE OUTPUT
int i=1 'src char iterator
int j=1 'tree char iterator
byte bs at strptr src 'src bytes
byte bt at strptr tree 'tree bytes
int bl=len src 'end of src
int lvl 'current tree level
int olv 'prior tree level
int v 'number value
string vs 'number in string form
 
do
exit if i>bl
select bs[i]
case 91 '['
i++
case 93 ']'
if i=bl
gosub writex
endif
i++
case 44 ','
i++
gosub writex
case 0 to 32 'white space
i++
'bt[j]=" " : j++
case 48 to 57 '0..9'
gosub ReadDigits
case else
i++
end select
loop
tree=left(tree,j-1)
output src cr
output tree cr cr
exit sub
 
'SUBROUTINES OF DEMOTREE:
=========================
 
writex:
=======
olv=lvl
if i>=bl
if v=0 and olv=0
tree="[]" : j=3
ret
endif
endif
if v<olv
gosub WriteRbr
endif
if olv
gosub WriteComma
endif
if v>olv
gosub WriteLbr
endif
gosub WriteDigits '3]]'
if i>=bl
v=0
gosub WriteRbr
endif
ret
 
ReadDigits:
===========
v=0
while i<=bl
select bs[i]
case 48 to 57 '1..9
v*=10 : v+=bs[i]-48 'digit
case else
exit while
end select
i++
wend
ret
'
WriteDigits:
============
vs=" "+str(v) : mid(tree,j,vs) : j+=len vs
ret
 
WriteLbr:
=========
while v>lvl
bt[j]=91 : j++ : lvl++
wend
ret
 
WriteRbr:
=========
while v<lvl
bt[j]=93 : j++ : lvl--
wend
ret
 
WriteComma:
===========
bt[j]=44 : j++ ','
ret
 
end sub
</syntaxhighlight>
 
=={{header|Perl}}==
===String Eval===
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict;
Line 1,220 ⟶ 1,757:
my $after = eval;
dd { after => $after };
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,238 ⟶ 1,775:
===Iterative===
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use 5.020_000; # Also turns on `strict`
use warnings;
use experimental qw<signatures>;
Line 1,261 ⟶ 1,798:
}
my @tests = ([],[1,2,4],[3,1,3,1],[1,2,3,1],[3,2,1,3],[3,3,3,1,1,3,3,3]);
say sprintf('%15s => ', join(' ', @{$_})), pp(to_tree_iterative(@{$_})) for @tests;</langsyntaxhighlight>
{{out}}
<pre>
Line 1,274 ⟶ 1,811:
=={{header|Phix}}==
I was thinking along the same lines but admit I had a little peek at the (recursive) python solution..
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #008080;">function</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">level</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">part</span>
Line 1,303 ⟶ 1,840:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v nests to %v\n or %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rpp</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,343 ⟶ 1,880:
</pre>
=== iterative ===
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #008080;">function</span> <span style="color: #000000;">nest</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">input</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">input</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
Line 1,366 ⟶ 1,903:
<span style="color: #008080;">return</span> <span style="color: #000000;">input</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</langsyntaxhighlight>-->
Same output (using nest instead of test)
 
Line 1,373 ⟶ 1,910:
===Python: Procedural===
====Python: Recursive====
<langsyntaxhighlight lang="python">def to_tree(x, index=0, depth=1):
so_far = []
while index < len(x):
Line 1,407 ⟶ 1,944:
nest = to_tree(flat)
print(f"{flat} NESTS TO: {nest}")
pnest(nest)</langsyntaxhighlight>
 
{{out}}
Line 1,447 ⟶ 1,984:
 
====Python: Iterative====
<langsyntaxhighlight lang="python">def to_tree(x: list) -> list:
nested = []
stack = [nested]
Line 1,461 ⟶ 1,998:
 
return nested
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,481 ⟶ 2,018:
 
<pre>Node (None|Int) :: ((None|Int), [Node])</pre>
<langsyntaxhighlight lang="python">'''Tree from nesting levels'''
 
from itertools import chain, repeat
Line 1,782 ⟶ 2,319:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>From: []
Line 1,918 ⟶ 2,455:
=={{header|Quackery}}==
 
<langsyntaxhighlight Quackerylang="quackery"> [ stack ] is prev ( --> s )
 
[ temp take
Line 1,950 ⟶ 2,487:
witheach
[ dup echo say " --> "
nesttree echo cr cr ]</langsyntaxhighlight>
 
{{out}}
Line 1,970 ⟶ 2,507:
===Iterative===
{{trans|Python}}
<syntaxhighlight lang="raku" perl6line>sub new_level ( @stack --> Nil ) {
my $e = [];
push @stack.tail, $e;
Line 1,988 ⟶ 2,525:
}
my @tests = (), (1, 2, 4), (3, 1, 3, 1), (1, 2, 3, 1), (3, 2, 1, 3), (3, 3, 3, 1, 1, 3, 3, 3);
say .Str.fmt( '%15s => ' ), .&to_tree_iterative for @tests;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,000 ⟶ 2,537:
===Recursive===
{{trans|Python}}
<syntaxhighlight lang="raku" perl6line>sub to_tree_recursive ( @list, $index is copy, $depth ) {
my @so_far = gather while $index <= @list.end {
my $t = @list[$index];
Line 2,024 ⟶ 2,561:
}
my @tests = (), (1, 2, 4), (3, 1, 3, 1), (1, 2, 3, 1), (3, 2, 1, 3), (3, 3, 3, 1, 1, 3, 3, 3);
say .Str.fmt( '%15s => ' ), to_tree_recursive( $_, 0, 1 ).[1] for @tests;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,037 ⟶ 2,574:
===String Eval===
{{trans|Perl}}
<syntaxhighlight lang="raku" perl6line>use MONKEY-SEE-NO-EVAL;
sub to_tree_string_eval ( @xs --> Array ) {
my @gap = [ |@xs, 0 ] Z- [ 0, |@xs ];
Line 2,049 ⟶ 2,586:
}
my @tests = (), (1, 2, 4), (3, 1, 3, 1), (1, 2, 3, 1), (3, 2, 1, 3), (3, 3, 3, 1, 1, 3, 3, 3);
say .Str.fmt( '%15s => ' ), .&to_tree_string_eval for @tests;</langsyntaxhighlight>
{{out}}
<pre>
Line 2,065 ⟶ 2,602:
{{libheader|Wren-seq}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./seq" for Stack
import "./fmt" for Fmt
 
var toTree = Fn.new { |list|
Line 2,098 ⟶ 2,635:
var nest = toTree.call(test)
Fmt.print("$24n => $n", test, nest)
}</langsyntaxhighlight>
 
{{out}}
Line 2,112 ⟶ 2,649:
===Recursive===
{{trans|Python}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var toTree // recursive
Line 2,146 ⟶ 2,683:
var n = toTree.call(test, 0, 1)
Fmt.print("$24n => $n", test, n[1])
}</langsyntaxhighlight>
 
{{out}}
<pre>
Same as iterative version.
</pre>
 
=={{header|XPL0}}==
A sentinel 0 is used to terminate the input arrays because XPL0 does not have built-in lists.
Note that [0] displays nothing.
<syntaxhighlight lang "XPL0">proc ShowTree(List);
int List, NestLevel, I;
[NestLevel:= 0;
for I:= 0 to -1>>1 do
[while List(I) < NestLevel do
[ChOut(0, ^]); NestLevel:= NestLevel-1];
if List(I) = 0 then [CrLf(0); return];
if I # 0 then Text(0, ", ");
while List(I) > NestLevel do
[ChOut(0, ^[); NestLevel:= NestLevel+1];
IntOut(0, NestLevel);
];
];
 
[ShowTree([0]);
ShowTree([1, 2, 4, 0]);
ShowTree([3, 1, 3, 1, 0]);
ShowTree([1, 2, 3, 1, 0]);
ShowTree([3, 2, 1, 3, 0]);
ShowTree([3, 3, 3, 1, 1, 3, 3, 3, 0]);
ShowTree([1, 2, 4, 2, 2, 1, 0]);
]</syntaxhighlight>
{{out}}
<pre>
 
[1, [2, [[4]]]]
[[[3]], 1, [[3]], 1]
[1, [2, [3]], 1]
[[[3], 2], 1, [[3]]]
[[[3, 3, 3]], 1, 1, [[3, 3, 3]]]
[1, [2, [[4]], 2, 2], 1]
</pre>
196

edits