mirror of https://github.com/deavmi/niknaks
Compare commits
7 Commits
474d43c271
...
4b0f4a15b7
Author | SHA1 | Date |
---|---|---|
Tristan B. Velloza Kildaire | 4b0f4a15b7 | |
Tristan B. Velloza Kildaire | 45a6ca0f67 | |
Tristan B. Velloza Kildaire | ee9d0cee7e | |
Tristan B. Velloza Kildaire | 4dceaad585 | |
Tristan B. Velloza Kildaire | 457f876a95 | |
Tristan B. Velloza Kildaire | b1f2cb594b | |
Tristan B. Velloza Kildaire | 9d39cc3710 |
|
@ -247,4 +247,215 @@ unittest
|
||||||
// TODO: See why not auto detecting the array type
|
// TODO: See why not auto detecting the array type
|
||||||
filter!(int)(vals, predicateOf!(onlyEven), vals_got);
|
filter!(int)(vals, predicateOf!(onlyEven), vals_got);
|
||||||
assert(vals_got == vals_expected);
|
assert(vals_got == vals_expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts a subset of the elements of
|
||||||
|
* the given array to a given position
|
||||||
|
* either from the left or right.
|
||||||
|
*
|
||||||
|
* Optionally allowing the shrinking
|
||||||
|
* of the array after the process,
|
||||||
|
* otherwise the last element shifted's
|
||||||
|
* previous value will be set to the
|
||||||
|
* value specified.
|
||||||
|
*
|
||||||
|
* Params:
|
||||||
|
* array = the input array
|
||||||
|
* position = the position to shift
|
||||||
|
* onto
|
||||||
|
* rightwards = if `true` then shift
|
||||||
|
* elements into the position rightwards,
|
||||||
|
* else leftwards (which is also the default)
|
||||||
|
* shrink = if set to `true` then
|
||||||
|
* the array will be resized to exclude
|
||||||
|
* the now "empty" element
|
||||||
|
* filler = the value to place in
|
||||||
|
* the space where the last element
|
||||||
|
* shifted no longer occupies, by default
|
||||||
|
* this is `T.init`
|
||||||
|
* Returns: the shifted array
|
||||||
|
*/
|
||||||
|
public T[] shiftInto(T)(T[] array, size_t position, bool rightwards = false, bool shrink = false, T filler = T.init)
|
||||||
|
{
|
||||||
|
// Out of range
|
||||||
|
if(position >= array.length)
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if rightwards
|
||||||
|
if(rightwards)
|
||||||
|
{
|
||||||
|
// nothing further left than index 0
|
||||||
|
if(!position)
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = position; i > 0; i--)
|
||||||
|
{
|
||||||
|
array[i] = array[i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// no shrink, then fill with filler
|
||||||
|
if(!shrink)
|
||||||
|
{
|
||||||
|
array[0] = filler;
|
||||||
|
}
|
||||||
|
// chomp left-hand side
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array = array[1..$];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if leftwards
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// nothing furtherright
|
||||||
|
if(position == array.length-1)
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = position; i < array.length-1; i++)
|
||||||
|
{
|
||||||
|
array[i] = array[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// no shrink, then fill with filler
|
||||||
|
if(!shrink)
|
||||||
|
{
|
||||||
|
array[$-1] = filler;
|
||||||
|
}
|
||||||
|
// chomp right-hand side
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array = array[0..$-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rightwards shifting into
|
||||||
|
*
|
||||||
|
* See_Also: `shiftInto`
|
||||||
|
*/
|
||||||
|
public T[] shiftIntoRightwards(T)(T[] array, size_t position, bool shrink = false)
|
||||||
|
{
|
||||||
|
return shiftInto(array, position, true, shrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the rightwards shifting
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
int[] numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(1);
|
||||||
|
|
||||||
|
// should now be [0, 1, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [0, 1, 2]);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(0);
|
||||||
|
|
||||||
|
// should now be [1, 5, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 5, 2]);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(2);
|
||||||
|
|
||||||
|
// should now be [0, 1, 5]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [0, 1, 5]);
|
||||||
|
|
||||||
|
numbas = [1, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(1);
|
||||||
|
|
||||||
|
// should now be [0, 1]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [0, 1]);
|
||||||
|
|
||||||
|
numbas = [1, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(0);
|
||||||
|
|
||||||
|
// should now be [1, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 2]);
|
||||||
|
|
||||||
|
numbas = [];
|
||||||
|
numbas = numbas.shiftIntoRightwards(0);
|
||||||
|
|
||||||
|
// should now be []
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == []);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoRightwards(1, true);
|
||||||
|
|
||||||
|
// should now be [1, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leftwards shifting into
|
||||||
|
*
|
||||||
|
* See_Also: `shiftInto`
|
||||||
|
*/
|
||||||
|
public T[] shiftIntoLeftwards(T)(T[] array, size_t position, bool shrink = false)
|
||||||
|
{
|
||||||
|
return shiftInto(array, position, false, shrink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the leftwards shifting
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
int[] numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoLeftwards(1);
|
||||||
|
|
||||||
|
// should now be [1, 2, 0]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 2, 0]);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoLeftwards(0);
|
||||||
|
|
||||||
|
// should now be [5, 2, 0]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [5, 2, 0]);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoLeftwards(2);
|
||||||
|
|
||||||
|
// should now be [1, 5, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 5, 2]);
|
||||||
|
|
||||||
|
numbas = [];
|
||||||
|
numbas = numbas.shiftIntoLeftwards(0);
|
||||||
|
|
||||||
|
// should now be []
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == []);
|
||||||
|
|
||||||
|
numbas = [1, 5, 2];
|
||||||
|
numbas = numbas.shiftIntoLeftwards(1, true);
|
||||||
|
|
||||||
|
// should now be [1, 2]
|
||||||
|
writeln(numbas);
|
||||||
|
assert(numbas == [1, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T[] removeResize(T)(T[] array, size_t position)
|
||||||
|
{
|
||||||
|
return array.shiftInto(position, false, true);
|
||||||
}
|
}
|
|
@ -11,6 +11,8 @@ import std.datetime.stopwatch : StopWatch, AutoStart;
|
||||||
import core.thread : Thread;
|
import core.thread : Thread;
|
||||||
import core.sync.condition : Condition;
|
import core.sync.condition : Condition;
|
||||||
import std.functional : toDelegate;
|
import std.functional : toDelegate;
|
||||||
|
import std.string : format;
|
||||||
|
import niknaks.arrays : removeResize;
|
||||||
|
|
||||||
version(unittest)
|
version(unittest)
|
||||||
{
|
{
|
||||||
|
@ -599,181 +601,6 @@ unittest
|
||||||
destroy(map);
|
destroy(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given [0, 1, 5]
|
|
||||||
// and shift right at index 1
|
|
||||||
// then 0 moves into 1's place
|
|
||||||
// 0's position is then filled with T.init
|
|
||||||
|
|
||||||
public T[] shiftInto(T)(T[] array, size_t position, bool rightwards = false, bool shrink = false)
|
|
||||||
{
|
|
||||||
// Out of range
|
|
||||||
if(position >= array.length)
|
|
||||||
{
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if rightwards
|
|
||||||
if(rightwards)
|
|
||||||
{
|
|
||||||
// nothing further left than index 0
|
|
||||||
if(!position)
|
|
||||||
{
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = position; i > 0; i--)
|
|
||||||
{
|
|
||||||
array[i] = array[i-1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// no shrink, then fill with T.init
|
|
||||||
if(!shrink)
|
|
||||||
{
|
|
||||||
array[0] = T.init;
|
|
||||||
}
|
|
||||||
// chomp left-hand side
|
|
||||||
else
|
|
||||||
{
|
|
||||||
array = array[1..$];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if leftwards
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// nothing furtherright
|
|
||||||
if(position == array.length-1)
|
|
||||||
{
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = position; i < array.length-1; i++)
|
|
||||||
{
|
|
||||||
array[i] = array[i+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// no shrink, then fill with T.init
|
|
||||||
if(!shrink)
|
|
||||||
{
|
|
||||||
array[$-1] = T.init;
|
|
||||||
}
|
|
||||||
// chomp right-hand side
|
|
||||||
else
|
|
||||||
{
|
|
||||||
array = array[0..$-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T[] shiftIntoRightwards(T)(T[] array, size_t position, bool shrink = false)
|
|
||||||
{
|
|
||||||
return shiftInto(array, position, true, shrink);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T[] shiftIntoLeftwards(T)(T[] array, size_t position, bool shrink = false)
|
|
||||||
{
|
|
||||||
return shiftInto(array, position, false, shrink);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rightwards testung (no shrink)
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
int[] numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoRightwards(1);
|
|
||||||
|
|
||||||
// should now be [0, 1, 2]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [0, 1, 2]);
|
|
||||||
|
|
||||||
numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoRightwards(0);
|
|
||||||
|
|
||||||
// should now be [1, 5, 2]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [1, 5, 2]);
|
|
||||||
|
|
||||||
numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoRightwards(2);
|
|
||||||
|
|
||||||
// should now be [0, 1, 5]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [0, 1, 5]);
|
|
||||||
|
|
||||||
numbas = [1, 2];
|
|
||||||
numbas = numbas.shiftIntoRightwards(1);
|
|
||||||
|
|
||||||
// should now be [0, 1]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [0, 1]);
|
|
||||||
|
|
||||||
numbas = [1, 2];
|
|
||||||
numbas = numbas.shiftIntoRightwards(0);
|
|
||||||
|
|
||||||
// should now be [1, 2]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [1, 2]);
|
|
||||||
|
|
||||||
numbas = [];
|
|
||||||
numbas = numbas.shiftIntoRightwards(0);
|
|
||||||
|
|
||||||
// should now be []
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// leftwards testung (no shrink)
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
int[] numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoLeftwards(1);
|
|
||||||
|
|
||||||
// should now be [1, 2, 0]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [1, 2, 0]);
|
|
||||||
|
|
||||||
numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoLeftwards(0);
|
|
||||||
|
|
||||||
// should now be [5, 2, 0]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [5, 2, 0]);
|
|
||||||
|
|
||||||
numbas = [1, 5, 2];
|
|
||||||
numbas = numbas.shiftIntoLeftwards(2);
|
|
||||||
|
|
||||||
// should now be [1, 5, 2]
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == [1, 5, 2]);
|
|
||||||
|
|
||||||
numbas = [];
|
|
||||||
numbas = numbas.shiftIntoLeftwards(0);
|
|
||||||
|
|
||||||
// should now be []
|
|
||||||
writeln(numbas);
|
|
||||||
assert(numbas == []);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T[] removeResize(T)(T[] array, size_t position)
|
|
||||||
{
|
|
||||||
return array.shiftInto(position, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make delegate kak
|
|
||||||
// public interface InclusionStratergy(T)
|
|
||||||
// {
|
|
||||||
// public bool include(T item);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private class AlwaysStrat(T) : InclusionStratergy
|
|
||||||
// {
|
|
||||||
// public override bool include(T item)
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public template Always(T)
|
public template Always(T)
|
||||||
{
|
{
|
||||||
public bool Always(Tree!(T) treeNode)
|
public bool Always(Tree!(T) treeNode)
|
||||||
|
@ -795,18 +622,35 @@ public template Nothing(T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 template InclusionStratergy(T)
|
||||||
{
|
{
|
||||||
public alias InclusionStratergy = bool delegate(Tree!(T) item);
|
public alias InclusionStratergy = bool delegate(Tree!(T) item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called prior to visitation?
|
/**
|
||||||
|
* 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 template TouchStratergy(T)
|
||||||
{
|
{
|
||||||
public alias TouchStratergy = void delegate(Tree!(T) item);
|
public alias TouchStratergy = void delegate(Tree!(T) item);
|
||||||
}
|
}
|
||||||
|
|
||||||
import std.string : format;
|
|
||||||
|
|
||||||
// TODO: Technically this is a graph
|
// TODO: Technically this is a graph
|
||||||
public class Tree(T)
|
public class Tree(T)
|
||||||
|
|
Loading…
Reference in New Issue