예제 #1
0
        static FingerTree <Node <Node <T, M>, M>, M> AddDigits2 <T, M>(Measured <Node <T, M>, M> m,
                                                                       FingerTree <Node <Node <T, M>, M>, M> m1,
                                                                       Digit <Node <T, M>, M> x, Node <T, M> n1, Node <T, M> n2,
                                                                       Digit <Node <T, M>, M> y,
                                                                       FingerTree <Node <Node <T, M>, M>, M> m2)
        {
            var mk = new MakeTree <Node <T, M>, M>(m);

            return(x.Match(x1 => y.Match(y1 => Append2(m, m1, mk.Node2(x1.V, n1), mk.Node2(n2, y1.V), m2),
                                         y2 => Append2(m, m1, mk.Node3(x1.V, n1, n2), mk.Node2(y2.V1, y2.V2), m2),
                                         y3 => Append2(m, m1, mk.Node3(x1.V, n1, n2), mk.Node3(y3.V1, y3.V2, y3.V3), m2),
                                         y4 => Append3(m, m1, mk.Node3(x1.V, n1, n2), mk.Node2(y4.V1, y4.V2),
                                                       mk.Node2(y4.V3, y4.V4), m2)),
                           x2 => y.Match(y1 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node2(n2, y1.V), m2),
                                         y2 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node3(n2, y2.V1, y2.V2), m2),
                                         y3 => Append3(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node2(n2, y3.V1),
                                                       mk.Node2(y3.V2, y3.V3), m2),
                                         y4 => Append3(m, m1, mk.Node3(x2.V1, x2.V2, n1), mk.Node3(n2, y4.V1, y4.V2),
                                                       mk.Node2(y4.V3, y4.V4), m2)),
                           x3 => y.Match(y1 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y1.V), m2),
                                         y2 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(n1, n2),
                                                       mk.Node2(y2.V1, y2.V2), m2),
                                         y3 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y3.V1),
                                                       mk.Node2(y3.V2, y3.V3), m2),
                                         y4 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node3(n1, n2, y4.V1),
                                                       mk.Node3(y4.V2, y4.V3, y4.V4), m2)),
                           x4 => y.Match(y1 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, n1),
                                                       mk.Node2(n2, y1.V), m2),
                                         y2 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2),
                                                       mk.Node2(y2.V1, y2.V2), m2),
                                         y3 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2),
                                                       mk.Node3(y3.V1, y3.V2, y3.V3), m2),
                                         y4 => Append4(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, n1, n2),
                                                       mk.Node2(y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2))));
        }
예제 #2
0
        static FingerTree <Node <T, M>, M> AddDigits0 <T, M>(Measured <T, M> m, FingerTree <Node <T, M>, M> m1,
                                                             Digit <T, M> s1, Digit <T, M> p2, FingerTree <Node <T, M>, M> m2)
        {
            var mk = new MakeTree <T, M>(m);

            return(s1.Match(x1 => p2.Match(y1 => Append1(m, m1, mk.Node2(x1.V, y1.V), m2),
                                           y2 => Append1(m, m1, mk.Node3(x1.V, y2.V1, y2.V2), m2),
                                           y3 => Append2(m, m1, mk.Node2(x1.V, y3.V1), mk.Node2(y3.V2, y3.V3), m2),
                                           y4 => Append2(m, m1, mk.Node3(x1.V, y4.V1, y4.V2), mk.Node2(y4.V3, y4.V4), m2)),
                            x2 => p2.Match(y1 => Append1(m, m1, mk.Node3(x2.V1, x2.V2, y1.V), m2),
                                           y2 => Append2(m, m1, mk.Node2(x2.V1, x2.V2), mk.Node2(y2.V1, y2.V2), m2),
                                           y3 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, y3.V1), mk.Node2(y3.V2, y3.V3),
                                                         m2),
                                           y4 => Append2(m, m1, mk.Node3(x2.V1, x2.V2, y4.V1),
                                                         mk.Node3(y4.V2, y4.V3, y4.V4), m2)),
                            x3 => p2.Match(y1 => Append2(m, m1, mk.Node2(x3.V1, x3.V2), mk.Node2(x3.V3, y1.V), m2),
                                           y2 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(y2.V1, y2.V2), m2),
                                           y3 => Append2(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3),
                                                         mk.Node3(y3.V1, y3.V2, y3.V3), m2),
                                           y4 => Append3(m, m1, mk.Node3(x3.V1, x3.V2, x3.V3), mk.Node2(y4.V1, y4.V2),
                                                         mk.Node2(y4.V3, y4.V4), m2)),
                            x4 => p2.Match(y1 => Append2(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, y1.V), m2),
                                           y2 => Append2(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, y2.V1, y2.V2), m2),
                                           y3 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node2(x4.V4, y3.V1),
                                                         mk.Node2(y3.V2, y3.V3), m2),
                                           y4 => Append3(m, m1, mk.Node3(x4.V1, x4.V2, x4.V3), mk.Node3(x4.V4, y4.V1, y4.V2),
                                                         mk.Node2(y4.V3, y4.V4), m2))));
        }
예제 #3
0
        public Deep(Measured <T, M> measured, M size, Digit <T, M> prefix, FingerTree <Node <T, M>, M> middle,
                    Digit <T, M> suffix)
            : base(measured, size)
        {
            _mk = new MakeTree <T, M>(measured);

            _prefix = prefix;
            _middle = middle;
            _suffix = suffix;
        }
예제 #4
0
 protected Digit(Measured <T, M> m, M size)
 {
     Size = size;
     _m   = m;
     _mk  = new MakeTree <T, M>(m);
 }
예제 #5
0
 public Single(Measured <T, M> m, T item)
     : base(m, m.Measure(item))
 {
     _item = item;
     _mk   = new MakeTree <T, M>(m);
 }
예제 #6
0
        public override Split <T, FingerTree <T, M>, M> Split(MeasurePredicate <M> predicate, M acc)
        {
            var mk = new MakeTree <Node <T, M>, M>(Measured.Node);

            M prefixSize = Measured.Append(acc, _prefix.Size);

            if (predicate(prefixSize))
            {
                Split <T, Digit <T, M>, M> split = _prefix.Split(predicate, acc);

                FingerTree <T, M> leftTree = split.Left == null?_mk.Empty() : split.Left.ToTree();

                FingerTree <T, M> rightTree;
                if (split.Right != null)
                {
                    rightTree = _mk.Deep(split.Right, _middle, _suffix);
                }
                else
                {
                    rightTree = _middle.Match(e => _suffix.ToTree(),
                                              s => _mk.Deep(s.Item.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2),
                                                                                         x3 => _mk.Three(x3.V1, x3.V2, x3.V3)),
                                                            mk.Empty(), _suffix),
                                              d =>
                    {
                        var leftView = _middle.Left;
                        return(_mk.Deep(leftView.Head.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2),
                                                                            x3 => _mk.Three(x3.V1, x3.V2, x3.V3)),
                                        leftView.Tail, _suffix));
                    });
                }

                return(new Split <T, FingerTree <T, M>, M>(leftTree, split.Item, rightTree));
            }

            M middleSize = Measured.Append(prefixSize, _middle.Size);

            if (predicate(middleSize))
            {
                Split <Node <T, M>, FingerTree <Node <T, M>, M>, M> split = _middle.Split(predicate, prefixSize);

                Split <T, Digit <T, M>, M> splitMidLeft = split.Item
                                                          .Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2), x3 => _mk.Three(x3.V1, x3.V2, x3.V3))
                                                          .Split(predicate, Measured.Append(prefixSize, split.Left.Size));

                FingerTree <T, M> leftTree  = _mk.Deep(_prefix, split.Left, splitMidLeft.Left);
                FingerTree <T, M> rightTree = _mk.Deep(splitMidLeft.Right, split.Right, _suffix);

                return(new Split <T, FingerTree <T, M>, M>(leftTree, splitMidLeft.Item, rightTree));
            }

            Split <T, Digit <T, M>, M> splitSuffix = _suffix.Split(predicate, middleSize);
            FingerTree <T, M>          right       = splitSuffix.Right == null?_mk.Empty() : splitSuffix.Right.ToTree();

            FingerTree <T, M> left;

            if (splitSuffix.Left != null)
            {
                left = _mk.Deep(_prefix, _middle, splitSuffix.Left);
            }
            else
            {
                left = _middle.Match(e => _prefix.ToTree(),
                                     s => _mk.Deep(_prefix, mk.Empty(), s.Item.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2),
                                                                                                     x3 => _mk.Three(x3.V1, x3.V2, x3.V3))),
                                     d =>
                {
                    var rightView = _middle.Right;
                    return(_mk.Deep(_prefix, rightView.Tail, rightView.Head.Match <Digit <T, M> >(x2 => _mk.Two(x2.V1, x2.V2),
                                                                                                  x3 => _mk.Three(x3.V1, x3.V2, x3.V3))));
                });
            }

            return(new Split <T, FingerTree <T, M>, M>(left, splitSuffix.Item, right));
        }