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()); }
// 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); } }
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}"); }
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); }
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); }
// 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); }
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)) { } } }
/** * 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]); }
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}"); }
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); }
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); }
// 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); } }