42 lines
1.2 KiB
C#
42 lines
1.2 KiB
C#
|
using Sawmill;
|
||
|
|
||
|
namespace InnovEnergy.Lib.SrcGen.Trees;
|
||
|
|
||
|
using T = ForwardTree<String>;
|
||
|
|
||
|
public static class PrefixTree
|
||
|
{
|
||
|
public static Tree<String> Create(IEnumerable<String> strings, String root = "")
|
||
|
{
|
||
|
var children = strings.Select(s => new T(s)).ToList();
|
||
|
var tree = new T(root, children);
|
||
|
|
||
|
var forwardTree = tree
|
||
|
.Rewrite(GroupByPrefix)
|
||
|
.Rewrite(ConcatUnaryNodes);
|
||
|
|
||
|
return new Tree<String>(forwardTree);
|
||
|
}
|
||
|
|
||
|
private static T GroupByPrefix(T tree)
|
||
|
{
|
||
|
var newChildren = tree
|
||
|
.Children
|
||
|
.Where(s => s.Node.Length > 0)
|
||
|
.GroupBy(s => s.Node[..1], s => new T(s.Node[1..]))
|
||
|
.Select(g => GroupByPrefix(new T(g.Key, g.ToList())))
|
||
|
.ToList();
|
||
|
|
||
|
return newChildren.Count == 0
|
||
|
? tree // leaf
|
||
|
: new T(tree.Node, newChildren);
|
||
|
}
|
||
|
|
||
|
private static T ConcatUnaryNodes(ForwardTree<String> tree)
|
||
|
{
|
||
|
return tree.Children.Count == 1 && tree.Children[0] is var child
|
||
|
? new T(tree.Node + child.Node, child.Children)
|
||
|
: tree;
|
||
|
}
|
||
|
}
|