Compare commits

...

41 Commits

Author SHA1 Message Date
Tristan B. Velloza Kildaire 852a068f78
Merge 7adea716c4 into b6106883da 2024-05-02 14:25:02 +00:00
Tristan B. Velloza Kildaire 7adea716c4 Merge branch 'master' into feature/tree 2024-05-02 16:24:44 +02:00
Tristan B. Velloza Kildaire b6106883da ConfigEntry
- Space fix
2024-05-02 08:32:38 +02:00
Tristan B. Velloza Kildaire c23d3dba62 Merge branch 'master' into feature/tree 2024-04-28 15:30:10 +02:00
Tristan B. Velloza Kildaire f8e45602f2 Merge branch 'master' into feature/tree 2024-04-28 15:05:18 +02:00
Tristan B. Velloza Kildaire ba4eb499ab Tree (unittests)
- Moved import
2024-04-27 17:16:31 +02:00
Tristan B. Velloza Kildaire 1caf6eaf10 Tree (unittests)
- Added docs
2024-04-27 17:13:25 +02:00
Tristan B. Velloza Kildaire bf0d9569c6 Merge branch 'master' into feature/tree 2024-04-27 16:51:01 +02:00
Tristan B. Velloza Kildaire a5f7e9fc95 VisitationTree
- Documented
2024-04-27 16:42:07 +02:00
Tristan B. Velloza Kildaire 926598086d VisitationTree
- Documented
2024-04-27 16:25:47 +02:00
Tristan B. Velloza Kildaire 943a16beb6 Merge branch 'master' into feature/tree 2024-04-27 15:49:48 +02:00
Tristan B. Velloza Kildaire 930fa1ace5 niknaks.arrays
- Added this
2024-04-27 15:46:28 +02:00
Tristan B. Velloza Kildaire 45a6ca0f67 niknaks.arrays
- Refactored
2024-04-27 15:43:58 +02:00
Tristan B. Velloza Kildaire ee9d0cee7e niknaks.arrays
- Updated unittestesd (test shrinking)
- Added docs
2024-04-27 15:43:20 +02:00
Tristan B. Velloza Kildaire 4dceaad585 niknaks.arrays
- Moved here

niknaks.containers

- Moved here
2024-04-27 15:39:36 +02:00
Tristan B. Velloza Kildaire 457f876a95 Containers
- Documented method
2024-04-27 15:38:10 +02:00
Tristan B. Velloza Kildaire b1f2cb594b InclusionStratergy
- Documented

TouchStratergy

- Documented
2024-04-27 15:27:31 +02:00
Tristan B. Velloza Kildaire 9d39cc3710 Containers
- Cleaned up
2024-04-27 15:22:57 +02:00
Tristan B. Velloza Kildaire 5b205019f6 Containers (unittests)
- Use new methods
2024-04-27 15:20:59 +02:00
Tristan B. Velloza Kildaire 38169bbebd Containers
- Added `shiftIntoLeftwards` and `shiftIntoRightwards`
2024-04-27 15:19:25 +02:00
Tristan B. Velloza Kildaire eeb1fd4a46 Merge branch 'master' into feature/tree 2024-04-27 15:17:13 +02:00
Tristan B. Velloza Kildaire d3eec6eba6 Tree
- Cleaned up
- Removed `getValue()`

Tree (unittests)

- Added test for `removeNode(Tree!(T))`
2024-04-26 18:30:28 +02:00
Tristan B. Velloza Kildaire 04c5373a69 Tree
- Added opIndex
2024-04-26 18:28:06 +02:00
Tristan B. Velloza Kildaire 450d811f52 Tree (unittests)
- Updated test for parametwerized opSlice
2024-04-26 18:25:17 +02:00
Tristan B. Velloza Kildaire 54b66ec3f1 Tree
- Added normal opSlice as well
2024-04-26 18:24:31 +02:00
Tristan B. Velloza Kildaire d7a830ffa9 Tree
- opSlice done
2024-04-26 18:22:31 +02:00
Tristan B. Velloza Kildaire 8dca2ebf73 Tree
- Reworking opSlicwe
2024-04-26 16:50:01 +02:00
Tristan B. Velloza Kildaire 4a431c43d1 TreeNode
- Added removal
- Added indexing support
2024-04-26 16:35:21 +02:00
Tristan B. Velloza Kildaire 11fd2f856e Methods
- Added leftwards shifting mechanism
2024-04-26 16:28:19 +02:00
Tristan B. Velloza Kildaire 41ebad0768 Methods
- Added rightward shifting mechanism
2024-04-26 16:05:10 +02:00
Tristan B. Velloza Kildaire 838ddbb9db Tree (unittests)
- Added missing assertions
2024-04-26 15:36:54 +02:00
Tristan B. Velloza Kildaire e44caf3643 VisitationTree (unittests)
- Added missing assertions
2024-04-26 15:35:29 +02:00
Tristan B. Velloza Kildaire ce78102af9 Tree
- Correct visitation stratergy
2024-04-23 16:02:40 +02:00
Tristan B. Velloza Kildaire 04edc241ad Tree
- Pass in, explcitly, the touch startergy
2024-04-23 15:52:02 +02:00
Tristan B. Velloza Kildaire 167c2b7c0d VisitationTree
- Working on a visitation tree implementation
2024-04-23 15:49:49 +02:00
Tristan B. Velloza Kildaire f49ecf1908 InclusionStratergy
- Now uses the `TreeNode!(T)` instead of the `T` itself
2024-04-22 22:14:28 +02:00
Tristan B. Velloza Kildaire d5b00c548e Tree
- Added ability to append

Tree (unittests)

- Updated unittests to test appending
2024-04-22 20:18:50 +02:00
Tristan B. Velloza Kildaire 4ecb57d4fa Tree
- Added a TODO
2024-04-22 20:14:26 +02:00
Tristan B. Velloza Kildaire 84f18407e8 Tree
- By default use the `always` strat
2024-04-22 17:03:30 +02:00
Tristan B. Velloza Kildaire 60028a34be Tree
- Added initial dfs
2024-04-22 17:02:24 +02:00
Tristan B. Velloza Kildaire 34d2b3031f Tree
- WIP
2024-04-13 14:56:54 +02:00
2 changed files with 393 additions and 1 deletions

View File

@ -345,7 +345,6 @@ public struct ConfigEntry
{
return numeric();
}
else static if(__traits(isSame, T, string[]))
{
return array();

View File

@ -11,12 +11,24 @@ import std.datetime.stopwatch : StopWatch, AutoStart;
import core.thread : Thread;
import core.sync.condition : Condition;
import std.functional : toDelegate;
import std.string : format;
import niknaks.arrays : removeResize;
version(unittest)
{
import std.stdio : writeln;
}
version(unittest)
{
import std.functional : toDelegate;
private void DebugTouch(T)(Tree!(T) node)
{
writeln("Touching tree node ", node);
}
}
/**
* Represents an entry of
* some value of type `V`
@ -597,4 +609,385 @@ unittest
// Destroy the map (such that it ends the sweeper
destroy(map);
}
public template Always(T)
{
public bool Always(Tree!(T) treeNode)
{
version(unittest)
{
import std.stdio : writeln;
writeln("Strat for: ", treeNode);
}
return true;
}
}
public template Nothing(T)
{
public void Nothing(Tree!(T) treeNode)
{
}
}
/**
* The inclusion stratergy which
* will be called upon the tree
* node prior to it being visited
* during a dfs operation.
*
* It is a predicate to determine
* whether or not the tree node
* in concern should be recursed
* upon.
*/
public template InclusionStratergy(T)
{
public alias InclusionStratergy = bool delegate(Tree!(T) item);
}
/**
* This is called on a tree node
* as part of the first action
* that takes place during the
* visitation of said node during
* a dfs operation.
*/
public template TouchStratergy(T)
{
public alias TouchStratergy = void delegate(Tree!(T) item);
}
// TODO: Technically this is a graph
public class Tree(T)
{
private T value;
private Tree!(T)[] children;
this(T value)
{
this.value = value;
}
this()
{
}
public void setValue(T value)
{
this.value = value;
}
public void appendNode(Tree!(T) node)
{
this.children ~= node;
}
public bool removeNode(Tree!(T) node)
{
bool found = false;
size_t idx;
for(size_t i = 0; i < this.children.length; i++)
{
found = this.children[i] == node;
if(found)
{
idx = i;
break;
}
}
if(found)
{
this.children = this.children.removeResize(idx);
return true;
}
return false;
}
// public T opIndex(size_t idx)
// {
// return idx < this.children.length ? this.children[idx].getValue() : T.init;
// }
private static bool isTreeNodeType(E)()
{
return __traits(isSame, E, Tree!(T));
}
private static bool isTreeValueType(E)()
{
return __traits(isSame, E, T);
}
public E[] opSlice(E)()
if(isTreeNodeType!(E) || isTreeValueType!(E))
{
// If the children as tree nodes is requested
static if(isTreeNodeType!(E))
{
return this.children;
}
// If the children as values themselves is requested
else static if(isTreeValueType!(E))
{
T[] slice;
foreach(Tree!(T) tnode; this.children)
{
slice ~= tnode.value;
}
return slice;
// import std.algorithm.iteration : map;
// return map!(getValue)(this.children)[];
}
}
public T[] opSlice()
{
return opSlice!(T)();
}
public E opIndex(E)(size_t idx)
if(isTreeNodeType!(E) || isTreeValueType!(E))
{
// If the cjild as a tree node is requested
static if(isTreeNodeType!(E))
{
return this.children[idx];
}
// If the child as a value itself is requested
else static if(isTreeValueType!(E))
{
return this.children[idx].value;
}
}
public T opIndex(size_t idx)
{
return opIndex!(T)(idx);
}
public T[] dfs
(
InclusionStratergy!(T) strat = toDelegate(&Always!(T)),
TouchStratergy!(T) touch = toDelegate(&Nothing!(T))
)
{
version(unittest)
{
writeln("dfs entry: ", this);
}
T[] collected;
scope(exit)
{
version(unittest)
{
writeln("leaving node ", this, " with collected ", collected);
}
}
// Touch
touch(this); // root[x]
foreach(Tree!(T) child; this.children) // subtree[x],
{
if(strat(child))
{
version(unittest)
{
writeln("dfs, strat good for child: ", child);
}
// Visit
collected ~= child.dfs(strat, touch);
}
else
{
version(unittest)
{
writeln("dfs, strat ignored for child: ", child);
}
}
}
// "Visit"
collected ~= this.value;
return collected;
}
public override string toString()
{
return format("TreeNode [val: %s]", this.value);
}
}
/**
* Test out usage of the tree
*/
unittest
{
Tree!(string) treeOfStrings = new Tree!(string)("Top");
Tree!(string) subtree_1 = new Tree!(string)("1");
Tree!(string) subtree_2 = new Tree!(string)("2");
Tree!(string) subtree_3 = new Tree!(string)("3");
treeOfStrings.appendNode(subtree_1);
treeOfStrings.appendNode(subtree_2);
treeOfStrings.appendNode(subtree_3);
InclusionStratergy!(string) strat = toDelegate(&Always!(string));
TouchStratergy!(string) touch = toDelegate(&DebugTouch!(string));
string[] result = treeOfStrings.dfs(strat, touch);
writeln("dfs: ", result);
assert(result[0] == "1");
assert(result[1] == "2");
assert(result[2] == "3");
assert(result[3] == "Top");
auto i = treeOfStrings.opSlice!(Tree!(string))();
writeln("Siblings: ", i);
assert(i[0] == subtree_1);
assert(i[1] == subtree_2);
assert(i[2] == subtree_3);
auto p = treeOfStrings.opSlice!(string)();
writeln("Siblings (vals): ", p);
assert(p == treeOfStrings[]);
assert(treeOfStrings.removeNode(subtree_1));
assert(!treeOfStrings.removeNode(subtree_1));
}
/**
* A kind-of a tree which has the ability
* to linearize all of its nodes which
* results in performing a depth first
* search resulting in the collection of
* all nodes into a single array with
* elements on the left hand side being
* the most leafiest (and left-to-right
* on the same depth are in said order).
*
* It also marks a node as visited on
* entry to it via the dfs call to it.
*
* When dfs is performed, a child node
* is only recursed upon if it has not
* yet been visited.
*
* With all this, it means a graph of
* relations can be flattened into an
* array.
*/
public class VisitationTree(T) : Tree!(T)
{
private bool visisted;
/**
* Constructs a new node
*
* Params:
* value = the value
*/
this(T value)
{
super(value);
}
/**
* Performs the linearization
*
* Returns: the linearized list
*/
public T[] linearize()
{
return dfs(toDelegate(&_shouldVisit), toDelegate(&_touch));
}
/**
* The inclusion startergy
*
* Params:
* tnode = the tree node
* Returns: `true` if not
* yet visited or incompatible
* node type
*/
private static bool _shouldVisit(Tree!(T) tnode)
{
VisitationTree!(T) vnode = cast(VisitationTree!(T))tnode;
return vnode && !vnode.isVisited();
}
/**
* The touching stratergy
*
* Only works on compatible
* tree nodes
*
* Params:
* tnode = the tree node
*/
private static void _touch(Tree!(T) tnode)
{
VisitationTree!(T) vnode = cast(VisitationTree!(T))tnode;
if(vnode)
{
vnode.mark();
}
}
/**
* Marks this node as
* visited
*/
private void mark()
{
this.visisted = true;
}
/**
* Checks this node has been
* visited
*
* Returns: `true` if visited,
* otherwise `false`
*/
private bool isVisited()
{
return this.visisted;
}
}
/**
* Tests out using the visitation tree
*/
unittest
{
VisitationTree!(string) root = new VisitationTree!(string)("root");
VisitationTree!(string) thing = new VisitationTree!(string)("subtree");
root.appendNode(thing);
thing.appendNode(root);
string[] linearized = root.linearize();
writeln(linearized);
assert(linearized[0] == "subtree");
assert(linearized[1] == "root");
}