Пример #1
0
        private static Node GetExpressionTree(string expression)
        {
            Stack <Node> expressionStack = new Stack <Node>();

            foreach (char c in expression)
            {
                if (char.IsDigit(c))
                {
                    expressionStack.Push(new LiteralNode((int)char.GetNumericValue(c)));
                }
                else
                {
                    Node a = expressionStack.Pop();
                    Node b = expressionStack.Pop();

                    if (c == ',')
                    {
                        var groupNode = new PairNode(b, a);
                        groupNode.Left.Parent  = groupNode;
                        groupNode.Right.Parent = groupNode;

                        expressionStack.Push(groupNode);
                    }
                }
            }

            return(expressionStack.Pop());
        }
Пример #2
0
        // Changes the value of the item stored in the pairing heap.
        // pos is any Position returned by insert.
        // newVal is the new value, which must be smaller
        //    than the currently stored value.
        // Throws ArgumentException if pos is null.
        // Throws IllegalValueException if new value is larger than old.
        public void DecreaseKey(IPriorityQueuePosition <AnyType> pos, AnyType newVal)
        {
            if (pos == null)
            {
                throw new ArgumentException("null Position passed to decreaseKey");
            }

            PairNode p = (PairNode)pos;

            if (p.element.CompareTo(newVal) < 0)
            {
                throw new IllegalValueException("newVal/oldval: " + newVal + " /" + p.element);
            }
            p.element = newVal;
            if (p != root)
            {
                if (p.nextSibling != null)
                {
                    p.nextSibling.prev = p.prev;
                }
                if (p.prev.leftChild == p)
                {
                    p.prev.leftChild = p.nextSibling;
                }
                else
                {
                    p.prev.nextSibling = p.nextSibling;
                }

                p.nextSibling = null;
                root          = CompareAndLink(root, p);
            }
        }
Пример #3
0
        public static void StartB()
        {
            var lines = File
                        //.ReadAllLines("Content\\Day18_Test2.txt")
                        .ReadAllLines("Content\\Day18.txt")
            ;

            var trees = lines
                        .Select(GetExpression)
                        .Select(GetExpressionTree)
                        .ToList();

            var largestMagnitude = 0;

            foreach (var t1 in trees)
            {
                foreach (var t2 in trees)
                {
                    var leftTree  = t1.Clone(null);
                    var rightTree = t2.Clone(null);

                    if (leftTree == rightTree)
                    {
                        continue;
                    }

                    var tree = new PairNode(leftTree, rightTree);
                    tree.Left.Parent  = tree;
                    tree.Right.Parent = tree;

                    (Node, bool)expandedTree = (tree, false);
                    do
                    {
                        expandedTree = ApplySnailfishLogic(expandedTree.Item1);
                    } while (expandedTree.Item2);

                    (Node, bool)magnitudeTree = (expandedTree.Item1, false);
                    do
                    {
                        magnitudeTree = CalculateMagnitude(magnitudeTree.Item1);
                    } while (magnitudeTree.Item2);

                    var finalTree = magnitudeTree.Item1;

                    var magnitude = ((LiteralNode)finalTree).Value;

                    if (magnitude > largestMagnitude)
                    {
                        largestMagnitude = magnitude;
                    }
                }
            }

            Logger.Info($"Day 18B: {largestMagnitude}");
        }
Пример #4
0
            public override Node Clone(Node parent)
            {
                var pairNode = new PairNode(null, null)
                {
                    Parent = parent
                };

                pairNode.Left  = Left.Clone(pairNode);
                pairNode.Right = Right.Clone(pairNode);

                return(pairNode);
            }
Пример #5
0
        private PairNode[] DoubleIfFull(PairNode[] array, int index)
        {
            if (index == array.Length)
            {
                PairNode[] oldArray = array;

                array = new PairNode[index * 2];
                for (int i = 0; i < index; i++)
                {
                    array[i] = oldArray[i];
                }
            }
            return(array);
        }
Пример #6
0
        // Insert into the priority queue, and return an IPriorityQueuePosition
        // that can be used by decreaseKey.
        // Duplicates are allowed.
        // x is the item to insert.
        // returns the node containing the newly inserted item.
        public IPriorityQueuePosition <AnyType> Insert(AnyType x)
        {
            PairNode newNode = new PairNode(x);

            if (root == null)
            {
                root = newNode;
            }
            else
            {
                root = CompareAndLink(root, newNode);
            }

            theSize++;
            return(newNode);
        }
Пример #7
0
 public void FindPathCoroutine(BaseChar player, BaseChar target)
 {
     if (!execute)
     {
         Ready(player.transform.position, target.transform.position);
         StartCoroutine(IEStep(player));
     }
     else
     {
         PairNode pairNode = new PairNode();
         pairNode.player = player;
         pairNode.target = target;
         if (orderlist.Contains(pairNode))
         {
         }
     }
 }
Пример #8
0
        /**
         * Internal method that implements two-pass merging.
         * @param firstSibling the root of the conglomerate;
         *     assumed not null.
         */



        private PairNode CombineSiblings(PairNode firstSibling)
        {
            if (firstSibling.nextSibling == null)
            {
                return(firstSibling);
            }

            // Store the subtrees in an array
            int numSiblings = 0;

            for ( ; firstSibling != null; numSiblings++)
            {
                treeArray = DoubleIfFull(treeArray, numSiblings);
                treeArray[numSiblings]        = firstSibling;
                firstSibling.prev.nextSibling = null;  // break links
                firstSibling = firstSibling.nextSibling;
            }
            treeArray = DoubleIfFull(treeArray, numSiblings);
            treeArray[numSiblings] = null;

            // Combine subtrees two at a time, going left to right
            int i = 0;

            for ( ; i + 1 < numSiblings; i += 2)
            {
                treeArray[i] = CompareAndLink(treeArray[i], treeArray[i + 1]);
            }

            int j = i - 2;

            // j has the result of last compareAndLink.
            // If an odd number of trees, get the last one.
            if (j == numSiblings - 3)
            {
                treeArray[j] = CompareAndLink(treeArray[j], treeArray[j + 2]);
            }

            // Now go right to left, merging last tree with
            // next to last. The result becomes the new last.
            for ( ; j >= 2; j -= 2)
            {
                treeArray[j - 2] = CompareAndLink(treeArray[j - 2], treeArray[j]);
            }

            return(treeArray[0]);
        }
Пример #9
0
        public static void StartA()
        {
            var lines = File.ReadAllLines("Content\\Day18.txt");
            var trees = new Queue <Node>();

            foreach (var line in lines)
            {
                var expression = GetExpression(line);
                var tree       = GetExpressionTree(expression);

                trees.Enqueue(tree);
            }

            var currentTree = trees.Dequeue();

            while (trees.Count > 0)
            {
                var tree = new PairNode(currentTree, trees.Dequeue());
                tree.Left.Parent  = tree;
                tree.Right.Parent = tree;

                (Node, bool)expandedTree = (tree, false);
                do
                {
                    expandedTree = ApplySnailfishLogic(expandedTree.Item1);
                } while (expandedTree.Item2);

                currentTree = expandedTree.Item1;
            }

            (Node, bool)magnitudeTree = (currentTree, false);
            do
            {
                magnitudeTree = CalculateMagnitude(magnitudeTree.Item1);
            } while (magnitudeTree.Item2);

            var finalTree = magnitudeTree.Item1;

            int answer = ((LiteralNode)finalTree).Value;

            Logger.Info($"Day 18A: {answer}");
        }
Пример #10
0
    private AstNode Term(LexemeSet stopSet)
    {
        logger.LogDebug($"Term: {currentLexeme} [{stopSet}]");
        var res       = Factor(stopSet + LexemeType.MulOp);
        var currentOp = currentLexeme.Value;

        logger.LogDebug($"first factor: {res}");
        while (currentLexeme.Type == LexemeType.MulOp)
        {
            logger.LogDebug($"Term: {currentLexeme} [{stopSet}]");
            NextLexeme();
            var nextFactor = Factor(stopSet + LexemeType.MulOp);
            logger.LogDebug($"next factor: {nextFactor}");
            res = new PairNode()
            {
                Left = res, Right = nextFactor, Operator = currentOp.ToString()
            };
        }

        return(res);
    }
Пример #11
0
        private static (Node, bool) FindLiteralToSplit(Node node)
        {
            if (node is PairNode g)
            {
                var newLeft = FindLiteralToSplit(g.Left);
                g.Left = newLeft.Item1;

                if (newLeft.Item2)
                {
                    return(node, true);
                }

                var newRight = FindLiteralToSplit(g.Right);
                g.Right = newRight.Item1;

                if (newRight.Item2)
                {
                    return(node, true);
                }
            }
            else if (node is LiteralNode l && l.Value >= 10)
            {
                int left  = (int)Math.Floor(l.Value / 2f);
                int right = (int)Math.Ceiling(l.Value / 2f);

                var groupNode = new PairNode(
                    new LiteralNode(left),
                    new LiteralNode(right)
                    );

                groupNode.Parent       = node.Parent;
                groupNode.Left.Parent  = groupNode;
                groupNode.Right.Parent = groupNode;

                return(groupNode, true);
            }

            return(node, false);
        }
Пример #12
0
        // Internal method that is the basic operation to maintain order.
        // Links first and second together to satisfy heap order.
        // first is root of tree 1, which may not be null.
        //    first.nextSibling MUST be null on entry.
        // second is root of tree 2, which may be null.
        // returns result of the tree merge.
        private PairNode CompareAndLink(PairNode first, PairNode second)
        {
            if (second == null)
            {
                return(first);
            }

            if (second.element.CompareTo(first.element) < 0)
            {
                // Attach first as leftmost child of second
                second.prev       = first.prev;
                first.prev        = second;
                first.nextSibling = second.leftChild;
                if (first.nextSibling != null)
                {
                    first.nextSibling.prev = first;
                }
                second.leftChild = first;
                return(second);
            }
            else
            {
                // Attach second as leftmost child of first
                second.prev       = first;
                first.nextSibling = second.nextSibling;
                if (first.nextSibling != null)
                {
                    first.nextSibling.prev = first;
                }
                second.nextSibling = first.leftChild;
                if (second.nextSibling != null)
                {
                    second.nextSibling.prev = second;
                }
                first.leftChild = second;
                return(first);
            }
        }