private static void InitializeEdges(CircularLinkedList <Vertex> lav) { // Create a dummy incident edge into the first node from a dummy vertex collinear with // the first line segment. This removes special casing for the first bisector computation. CircularLinkedListNode <Vertex> firstNode = lav.First; Debug.Assert(firstNode != null); Debug.Assert(firstNode.Next != null); Vector2D firstEdgeDirection = firstNode.Next.Value.Position - firstNode.Value.Position; Vertex prefixVertex = new Vertex(firstNode.Value.Position - firstEdgeDirection); firstNode.Value.inEdge = new Edge(prefixVertex, firstNode.Value); // Create a dummy indicent edge from the last node to a dummy vertex collinear with the last // line segment. This removes special casing for the last bisector computation. CircularLinkedListNode <Vertex> lastNode = lav.Last; Debug.Assert(lastNode != null); Debug.Assert(lastNode.Previous != null); Vector2D lastEdgeDirection = lastNode.Value.Position - lastNode.Previous.Value.Position; Vertex suffixVertex = new Vertex(lastNode.Value.Position + lastEdgeDirection); lastNode.Value.outEdge = new Edge(lastNode.Value, suffixVertex); // Create edges between successive pairs of the list lav.ForEachPair(delegate(Vertex va, Vertex vb) { va.outEdge = new Edge(va, vb); vb.inEdge = va.outEdge; }); }
// Returns true if the specified convex vertex is an ear tip private static bool IsEarTip(Vector3[] a_rMeshVertices, int a_iEarTipConvexVertexIndex, CircularLinkedList <int> a_rContourVertexIndexesList, LinkedList <int> a_rReflexVertexIndexesList) { CircularLinkedListNode <int> rContourVertexNode = a_rContourVertexIndexesList.Find(a_iEarTipConvexVertexIndex); int iPreviousContourVertexIndex = rContourVertexNode.Previous.Value; int iNextContourVertexIndex = rContourVertexNode.Next.Value; // Retrieve previous (i-1) / current (i) / next (i+1) vertices to form the triangle < Vi-1, Vi, Vi+1 > Vector3 f3ConvexContourVertex = a_rMeshVertices[a_iEarTipConvexVertexIndex]; Vector3 f3PreviousContourVertex = a_rMeshVertices[iPreviousContourVertexIndex]; Vector3 f3NextContourVertex = a_rMeshVertices[iNextContourVertexIndex]; // Look for an inner point into the triangle formed by the 3 vertices // Only need to look over the reflex vertices. for (LinkedListNode <int> rReflexIndexNode = a_rReflexVertexIndexesList.First; rReflexIndexNode != null; rReflexIndexNode = rReflexIndexNode.Next) { // Retrieve the reflex vertex int iReflexContourVertexIndex = rReflexIndexNode.Value; // Is the point inside the triangle? // (Exclude the triangle points themselves) Vector3 f3ReflexContourVertex = a_rMeshVertices[iReflexContourVertexIndex]; if (f3ReflexContourVertex != f3PreviousContourVertex && f3ReflexContourVertex != f3ConvexContourVertex && f3ReflexContourVertex != f3NextContourVertex) { if (Uni2DMathUtils.IsPointInsideTriangle(f3PreviousContourVertex, f3ConvexContourVertex, f3NextContourVertex, f3ReflexContourVertex) == true) { // Point is inside triangle: not an ear tip return(false); } } } // No point inside the triangle: ear tip found! return(true); }
/// <summary> /// Adds the specified item before the specified existing node in the list. /// </summary> /// <param name="a_rNode">Existing node before which new item will be inserted</param> /// <param name="a_rItem">New item to be inserted</param> /// <exception cref="ArgumentNullException"><paramref name="a_rNode"/> is NULL</exception> /// <exception cref="InvalidOperationException"><paramref name="node"/> doesn't belongs to list</exception> public void AddBefore(CircularLinkedListNode <T> a_rNode, T a_rItem) { if (a_rNode == null) { throw new ArgumentNullException("node"); } // ensuring the supplied node belongs to this list bool bNodeBelongsToList = this.FindNode(a_rNode); if (bNodeBelongsToList == false) { throw new InvalidOperationException("Node doesn't belongs to this list"); } CircularLinkedListNode <T> oNewNode = new CircularLinkedListNode <T>(a_rItem); a_rNode.Previous.Next = oNewNode; oNewNode.Previous = a_rNode.Previous; oNewNode.Next = a_rNode; a_rNode.Previous = oNewNode; // if the node adding is head node, then repointing head node if (a_rNode == m_rFirstNode) { m_rFirstNode = oNewNode; } ++m_iCountNode; }
/// <summary> /// Appends a specified value to the end of the list and returns the list node /// that was created to house it. /// </summary> /// <remarks> /// Complexity: O(1) /// </remarks> /// <param name="value">Value to be added to this list.</param> /// <returns>A new CircularLinkedListNode instance belonging to this list containing the appended value.</returns> public CircularLinkedListNode <T> Append(T value) { CircularLinkedListNode <T> newNode = new CircularLinkedListNode <T>(value); Append(newNode); return(newNode); }
private TVertex NextVertex(TVertex vertex) { // TODO: Temporary and horribly inefficient! CircularLinkedListNode <TVertex> node = vertices.Find(vertex); return(node.Next.Value); }
private void EnqueueOppIntersection(CircularLinkedListNode <Vertex> node, Point2D position) { double distanceToSupportingLine = DistanceToSupportingLine(node, position); // TODO: Refactor SplitEvent intersection = new SplitEvent(position, node); queueDictionary.Enqueue(distanceToSupportingLine, intersection); }
private bool Append(CircularLinkedListNode <T> node) { if ((null == node) || (null != node.m_List)) { //-- Node is null or already belongs to another list return(false); } //-- Set self as list node.m_List = this; if (0 == m_Count) { //-- One-node list; trivial m_First = node; m_First.m_Next = m_First; m_First.m_Previous = m_First; } else { //-- Append the node to the tail node.m_Previous = m_First.Previous; m_First.m_Previous.m_Next = node; //-- Prepend the node to the head node.m_Next = m_First; m_First.m_Previous = node; } ++m_Count; return(true); }
/// <summary> /// Removes the root node from the specified internal tree and shuffles /// the resulting sub-trees back into this heap. /// </summary> /// <remarks> /// Complexity: O(log n) /// </remarks> /// <param name="tree">Iterater to the tree who's root we want to remove.</param> private void RemoveRootNode(LinkedListNode <BinomialTree <T> > tree) { //-- Remove the tree from this heap m_Trees.Remove(tree); //-- Rejig the heap if (0 < tree.Value.Root.Children.Count) { //-- Add that tree's sub-trees into a spearate heap BinomialHeap <T> temp = new BinomialHeap <T>(); CircularLinkedListNode <BinomialTreeNode <T> > childIter = tree.Value.Root.Children.First; do { //-- Orphan the child childIter.Value.m_Parent = null; //-- Add the children of the top node as separate trees in the temp // heap from smallest to largest order. temp.m_Trees.AddLast(new BinomialTree <T>(childIter.Value)); childIter = childIter.Next; }while(tree.Value.Root.Children.First != childIter); //-- Merge the resulting sub-trees back into this heap Union(temp); } }
void AddFirstItem(T a_rItem) { m_rFirstNode = new CircularLinkedListNode <T>(a_rItem); m_rLastNode = m_rFirstNode; m_rFirstNode.Next = m_rLastNode; m_rFirstNode.Previous = m_rLastNode; }
/// <summary> /// Determines whether the edges around the supplied vertex are ordered /// geometrically in the plane. /// </summary> /// <param name="vertex"></param> /// <returns></returns> private static bool IsOrdered(TVertex vertex) { if (vertex.Degree <= 2) { return(true); } CircularLinkedList <double> angles = new CircularLinkedList <double>(); foreach (Half h in vertex.HalfEdges) { double bearing = Bearing(h); angles.AddLast(bearing); } double min = angles.Min(); CircularLinkedListNode <double> node = angles.Find(min); CircularLinkedListNode <double> end = node; // Check that advancing from this minima they are sorted do { if (node.Value >= node.Next.Value) { return(false); } node = node.Next; }while (node != end.Previous); return(true); }
/// <summary> /// Re-order the half-edges around vertex such that they /// are spatially sorted /// </summary> /// <param name="vertex"></param> private static void Order(TVertex vertex) { // Put the half-edges into order according to bearing SortedDictionary <double, Half> outEdges = new SortedDictionary <double, Half>(); foreach (Half h in vertex.HalfEdges) { double bearing = Bearing(h); outEdges.Add(bearing, h); } // Copy into a circular linked-list for convenience CircularLinkedList <Half> outEdgesCycle = new CircularLinkedList <Half>(outEdges.Values); // Iterate around the list, correcting pointers as we go CircularLinkedListNode <Half> node = outEdgesCycle.First; do { Half previousInEdge = node.Previous.Value.pair; Half currentOutEdge = node.Value; Half currentInEdge = currentOutEdge.pair; Half nextOutEdge = node.Next.Value; previousInEdge.next = currentOutEdge; currentOutEdge.previous = previousInEdge; currentInEdge.next = nextOutEdge; nextOutEdge.previous = currentInEdge; node = node.Next; }while (node != outEdgesCycle.Last.Next); Debug.Assert(IsOrdered(vertex)); }
// Builds indexes lists of reflex and convex vertex private static void BuildReflexConvexVertexIndexesLists(Vector3[] a_rContourVerticesArray, CircularLinkedList <int> a_rContourVertexIndexesList, out LinkedList <int> a_rReflexVertexIndexesList, out LinkedList <int> a_rConvexVertexIndexesList) { LinkedList <int> oReflexVertexIndexesList = new LinkedList <int>( ); LinkedList <int> oConvexVertexIndexesList = new LinkedList <int>( ); // Iterate contour vertices CircularLinkedListNode <int> rContourNode = a_rContourVertexIndexesList.First; do { int iContourVertexIndex = rContourNode.Value; Vector3 f3ContourVertex = a_rContourVerticesArray[iContourVertexIndex]; Vector3 f3PreviousContourVertex = a_rContourVerticesArray[rContourNode.Previous.Value]; Vector3 f3NextContourVertex = a_rContourVerticesArray[rContourNode.Next.Value]; // Sorting reflex / convex vertices // Reflex vertex forms a triangle with an angle >= 180° if (IsReflexVertex(f3ContourVertex, f3PreviousContourVertex, f3NextContourVertex) == true) { oReflexVertexIndexesList.AddLast(iContourVertexIndex); } else // angle < 180° => Convex vertex { oConvexVertexIndexesList.AddLast(iContourVertexIndex); } rContourNode = rContourNode.Next; }while(rContourNode != a_rContourVertexIndexesList.First); // Transmit results a_rReflexVertexIndexesList = oReflexVertexIndexesList; a_rConvexVertexIndexesList = oConvexVertexIndexesList; }
private static double DistanceToSupportingLine(CircularLinkedListNode <Vertex> node, Point2D position) { // Take the outEdge for all except the last point Edge edge = node.Value.outEdge ?? node.Value.inEdge; Debug.Assert(edge != null); Line2D supportingLine = new Line2D(edge.source.Bisector.Source, edge.target.Bisector.Source); double distanceToSupportingLine = Math.Abs(supportingLine.DistanceTo(position)); return(distanceToSupportingLine); }
/// <summary> /// Adds the new item before the specified existing item in the list. /// </summary> /// <param name="a_rExistingItem">Existing item before which new item will be added</param> /// <param name="a_rNewItem">New item to be added to the list</param> /// <exception cref="ArgumentException"><paramref name="existingItem"/> doesn't exist in the list</exception> public void AddBefore(T a_rExistingItem, T a_rNewItem) { // finding a node for the existing item CircularLinkedListNode <T> rNode = this.Find(a_rExistingItem); if (rNode == null) { throw new ArgumentException("existingItem doesn't exist in the list"); } this.AddBefore(rNode, a_rNewItem); }
/// <summary> /// Removes the first occurance of the supplied item /// </summary> /// <param name="a_rItem">Item to be removed</param> /// <returns>TRUE if removed, else FALSE</returns> public bool Remove(T a_rItem) { // finding the first occurance of this item CircularLinkedListNode <T> rNodeToRemove = this.Find(a_rItem); if (rNodeToRemove != null) { return(this.RemoveNode(rNodeToRemove)); } return(false); }
public override object Task2() { const int turns = 10000000; const int maxVal = 1000000; Dictionary <int, CircularLinkedListNode <int> > lookupTable = new Dictionary <int, CircularLinkedListNode <int> >(); CircularLinkedList <int> cups = new CircularLinkedList <int>(); foreach (int i in ParseInput()) { cups.AddLast(i); lookupTable[cups.Last.Value] = cups.Last; } for (int i = 10; i <= maxVal; i++) { cups.AddLast(i); lookupTable[cups.Last.Value] = cups.Last; } CircularLinkedListNode <int> current = cups.First; CircularLinkedListNode <int>[] pickedUpCups = new CircularLinkedListNode <int> [3]; for (int _ = 0; _ < turns; _++) { for (int i = 0; i < pickedUpCups.Length; i++) { pickedUpCups[i] = current.Next; cups.Remove(pickedUpCups[i]); } CircularLinkedListNode <int> destNode = lookupTable[current.Value == 1 ? maxVal : current.Value - 1]; while (Array.IndexOf(pickedUpCups, destNode) != -1) { destNode = lookupTable[destNode.Value == 1 ? maxVal : destNode.Value - 1]; } for (int i = pickedUpCups.Length - 1; i >= 0; i--) { cups.AddAfter(destNode, pickedUpCups[i]); } current = current.Next; } CircularLinkedListNode <int> one = lookupTable[1]; return((ulong)one.Next.Value * (ulong)one.Next.Next.Value == 5403610688); }
/// <summary> /// Gets a reverse enumerator /// </summary> /// <returns></returns> public IEnumerator <T> GetReverseEnumerator() { CircularLinkedListNode <T> rCurrent = m_rLastNode; if (rCurrent != null) { do { yield return(rCurrent.Value); rCurrent = rCurrent.Previous; } while (rCurrent != m_rLastNode); } }
/// <summary> /// Gets a forward enumerator /// </summary> /// <returns></returns> public IEnumerator <T> GetEnumerator() { CircularLinkedListNode <T> rCurrent = m_rFirstNode; if (rCurrent != null) { do { yield return(rCurrent.Value); rCurrent = rCurrent.Next; } while (rCurrent != m_rFirstNode); } }
CircularLinkedListNode <T> FindFirstNodeWithValue(CircularLinkedListNode <T> a_rNode, T a_rValueToCompare) { CircularLinkedListNode <T> rResult = null; if (m_rComparer.Equals(a_rNode.Value, a_rValueToCompare)) { rResult = a_rNode; } else if (rResult == null && a_rNode.Next != m_rFirstNode) { rResult = FindFirstNodeWithValue(a_rNode.Next, a_rValueToCompare); } return(rResult); }
public void Iterate() { int sum = elf0.Value + elf1.Value; int decades = Math.DivRem(sum, 10, out int remainder); if (decades > 0) { recipes.Add(decades); } recipes.Add(remainder); elf0 = recipes.GetNext(elf0, elf0.Value + 1); elf1 = recipes.GetNext(elf1, elf1.Value + 1); }
bool FindNode(CircularLinkedListNode <T> a_rNode) { CircularLinkedListNode <T> rNode = m_rFirstNode; do { if (rNode == a_rNode) { return(true); } rNode = rNode.Next; }while(rNode != m_rFirstNode); return(false); }
/// <summary> /// Determine if the edge beginning at start has a larger x value /// than vertex.X at a y-value of vertex.Y /// </summary> /// <param name="startNode">The start of an edge</param> /// <param name="vertexNode">The test vertex</param> /// <returns></returns> private static int LargerXAtVertexY(CircularLinkedListNode <TVertex> startNode, CircularLinkedListNode <TVertex> vertexNode) { CircularLinkedListNode <TVertex> endNode = startNode.Next; Point2D start = startNode.Value.Position; Point2D end = endNode.Value.Position; Point2D point = vertexNode.Value.Position; if (start.Y == end.Y) { return(Math.Min(start.X, end.X).CompareTo(point.X)); } Line2D line = new Line2D(start, end); return(CompareYProjection(point, line)); }
private bool MatchesSequence(CircularLinkedListNode <int> start, int[] sequence) { var current = start; for (int i = 0; i < sequence.Length; i++) { if (sequence[i] != current.Value) { return(false); } current = current.Next; } return(true); }
public override void ModifyLav(AngularBisectorNetwork network) { Debug.Assert(nodeA.List == nodeB.List); CircularLinkedList <Vertex> lav = nodeA.List; Vertex vA = nodeA.Value; Vertex vB = nodeB.Value; // * Create a new Vertex V with the coordinates of the intersection I Vertex v = new Vertex(this.Position); // * insert the new vertex into the LAV. That means connect it with the predecessor // of Va and the successor of Vb in the LAV CircularLinkedListNode <Vertex> nodeV = new CircularLinkedListNode <Vertex>(v); lav.AddAfter(nodeA, nodeV); lav.Remove(nodeA); lav.Remove(nodeB); // * link the new node V with the appropriate edges ea and eb (pointed to by vertices // Va and Vb // TODO: This needs some work for start and end nodes. What should happen? v.inEdge = vA.inEdge; v.outEdge = vB.outEdge; // f. for the new node V, created from I, compute: // * the new angle bisector b between the line segments ea and eb, and // TODO: This bisector sometimes needs to be revered! But under what circumstances? Direction2D bisector = AngularBisector(nodeV.Value.inEdge, nodeV.Value.outEdge); // Determine whether the triangle A B V has an acute or obtuse angle at V // this is used to determine the direction of the bisector Triangle2D triangle = new Triangle2D(vA.Position, vB.Position, v.Position); if (triangle.AngleC > (Math.PI / 2.0)) { bisector = -bisector; } nodeV.Value.Bisector = new Ray2D(nodeV.Value.Bisector.Source, bisector); // * the intersections of this bisector with the bisectors starting from the neighbour vertices in // the LAV in the same way as in the step 1c // * store the nearer intersection (if it exists) in the priority queue network.EnqueueNearestBisectorIntersection(lav, nodeV); }
/// <summary> /// Adds item to the last /// </summary> /// <param name="a_rItem">Item to be added</param> public void AddFirst(T a_rItem) { if (m_rFirstNode == null) { this.AddFirstItem(a_rItem); } else { CircularLinkedListNode <T> oNewNode = new CircularLinkedListNode <T>(a_rItem); m_rFirstNode.Previous = oNewNode; oNewNode.Previous = m_rLastNode; oNewNode.Next = m_rFirstNode; m_rLastNode.Next = oNewNode; m_rFirstNode = oNewNode; } ++m_iCountNode; }
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (restart == true) { restart = false; snake.Clear(); Snake snakehead; snakehead = new Snake(0, 0, 30, 30, 30, 4); snake.AddNodeToFront(snakehead); snake.Head.data.X = 0; snake.Head.data.Y = 0; score = 0; label1.Text = "Score: 0"; currentDirection = direction.right; CircularLinkedListNode <Snake> runner1 = snake.Head; for (int i = snake.Count - 1; i > 0; i--) { snake.Remove(runner1.data); runner1 = runner1.next; } timer1.Enabled = true; } if (e.KeyCode == Keys.Left && currentDirection != direction.right) { currentDirection = direction.left; } if (e.KeyCode == Keys.Right && currentDirection != direction.left) { currentDirection = direction.right; } if (e.KeyCode == Keys.Up && currentDirection != direction.down) { currentDirection = direction.up; } if (e.KeyCode == Keys.Down && currentDirection != direction.up) { currentDirection = direction.down; } CircularLinkedListNode <Snake> runner = snake.Head; for (int i = snake.Count - 1; i > 0; i--) { runner.data.Direction = runner.prev.data.Direction; runner = runner.next; } }
private void PlayOneRound(CircularLinkedList <int> linkedList, CircularLinkedListNode <int> f, int maxValue) { CircularLinkedListNode <int> dest = FindDestinationCup2(f, maxValue); var currentNode = f; var firstCupToSwap = f.Next; var lastCupToSwap = f.Next.Next.Next; var t = dest.Next; f.Next = lastCupToSwap.Next; f.Next.Previous = f; dest.Next = firstCupToSwap; firstCupToSwap.Previous = dest; lastCupToSwap.Next = t; t.Previous = lastCupToSwap; }
/// <summary> /// Add a new item to the end of the list /// </summary> /// <param name="a_rItem">Item to be added</param> public void AddLast(T a_rItem) { // if head is null, then this will be the first item if (m_rFirstNode == null) { this.AddFirstItem(a_rItem); } else { CircularLinkedListNode <T> oNewNode = new CircularLinkedListNode <T>(a_rItem); m_rLastNode.Next = oNewNode; oNewNode.Next = m_rFirstNode; oNewNode.Previous = m_rLastNode; m_rLastNode = oNewNode; m_rFirstNode.Previous = m_rLastNode; } ++m_iCountNode; }
public void CopyTo(T[] a_rArray, int a_iArrayIndex) { if (a_rArray == null) { throw new ArgumentNullException("array"); } if (a_iArrayIndex < 0 || a_iArrayIndex > a_rArray.Length) { throw new ArgumentOutOfRangeException("arrayIndex"); } CircularLinkedListNode <T> rNode = this.m_rFirstNode; do { a_rArray[a_iArrayIndex++] = rNode.Value; rNode = rNode.Next; } while (rNode != m_rFirstNode); }
/// <summary> /// Gets the item at the current index /// </summary> /// <param name="a_iIndex">Zero-based index</param> /// <exception cref="ArgumentOutOfRangeException">index is out of range</exception> public CircularLinkedListNode <T> this[int a_iIndex] { get { if (a_iIndex >= m_iCountNode || a_iIndex < 0) { throw new ArgumentOutOfRangeException("index"); } else { CircularLinkedListNode <T> rNode = this.m_rFirstNode; for (int i = 0; i < a_iIndex; i++) { rNode = rNode.Next; } return(rNode); } } }