private void Run(List <int> input, int moves) { int highest = input.Max(); cupArray = new CupNode[input.Count]; InitLinkedList(input); lookup = cupArray.ToDictionary(x => x.Value, y => y); var currentNode = lookup[input[0]]; for (int i = 0; i < moves; i++) { var cutpoint = currentNode.Next; currentNode.Next = currentNode.Next.Next.Next.Next; var destination = GetDestination(currentNode.Value, cutpoint, highest); var insertionPoint = lookup[destination]; CupNode insertionPointNext = insertionPoint.Next; CupNode tail = cutpoint.Next.Next; tail.Next = insertionPointNext; insertionPoint.Next = cutpoint; currentNode = currentNode.Next; } }
void Moves(Dictionary <int, CupNode> cupNodes, int moves) { CupNode currentCup = cupNodes.First().Value; for (int r = 0; r < moves; ++r) { (CupNode beginPickUpNode, CupNode middlePickUpNode, CupNode endPickUpNode) = currentCup.PickUp(); HashSet <int> pickUpValues = new HashSet <int>() { beginPickUpNode.value, middlePickUpNode.value, endPickUpNode.value }; int dest = currentCup.value - 1 > 0 ? currentCup.value - 1 : cupNodes.Count; while (pickUpValues.Contains(dest)) { --dest; if (dest == 0) { dest = cupNodes.Count; } } CupNode destCupNode = cupNodes[dest]; CupNode afterDestCupNode = destCupNode.nextNode; destCupNode.nextNode = beginPickUpNode; endPickUpNode.nextNode = afterDestCupNode; currentCup = currentCup.nextNode; } }
string Part1() { List <int> tempCups = new List <int>(cups); Dictionary <int, CupNode> cupNodes = new Dictionary <int, CupNode>(); CupNode prevNode = null; for (int i = tempCups.Count - 1; i >= 0; --i) { CupNode newNode = new CupNode(tempCups[i]) { nextNode = prevNode }; cupNodes[tempCups[i]] = newNode; prevNode = newNode; } cupNodes = cupNodes.Reverse().ToDictionary(x => x.Key, x => x.Value); cupNodes.Last().Value.nextNode = cupNodes.First().Value; Moves(cupNodes, 100); string res = string.Empty; CupNode currentNode = cupNodes[1].nextNode; while (currentNode.value != 1) { res += currentNode.value.ToString(); currentNode = currentNode.nextNode; } return(res); }
/* private List<int> Moves(List<int> tempCups) * { * int currentCup = tempCups[0]; * List<int> pickUpCups = tempCups.GetRange(1, 3); * int startIndex = 4; * List<int> remainingCups = tempCups.GetRange(startIndex, tempCups.Count - startIndex); * * int destination = currentCup - 1; * int destIndex = -1; * * while (destination > 0) * { * if (remainingCups.Contains(destination)) * { * destIndex = tempCups.IndexOf(destination); * break; * } * --destination; * } * destination = destination == 0 ? remainingCups.Max() : destination; * destIndex = destIndex == -1 ? tempCups.IndexOf(destination) : destIndex; * remainingCups.RemoveRange(0, remainingCups.IndexOf(destination) + 1); * * List<int> result = new List<int>(tempCups.GetRange(startIndex, destIndex - startIndex + 1)); * result.AddRange(pickUpCups); * result.AddRange(remainingCups); * result.Add(currentCup); * * return result; * }*/ string Part2() { List <int> tempCups = new List <int>(cups); tempCups.AddRange(Enumerable.Range(10, 1_000_000 - tempCups.Count)); Dictionary <int, CupNode> cupNodes = new Dictionary <int, CupNode>(); CupNode prevNode = null; for (int i = tempCups.Count - 1; i >= 0; --i) { CupNode newNode = new CupNode(tempCups[i]) { nextNode = prevNode }; cupNodes[tempCups[i]] = newNode; prevNode = newNode; } cupNodes = cupNodes.Reverse().ToDictionary(x => x.Key, x => x.Value); cupNodes.Last().Value.nextNode = cupNodes.First().Value; Moves(cupNodes, 10_000_000); long first = cupNodes[1].nextNode.value; long second = cupNodes[1].nextNode.nextNode.value; return((first * second).ToString()); }
void PlayRounds(CupNode current, long numRounds, long maxNodeId, Dictionary <long, CupNode> cupDict) { for (int i = 0; i < numRounds; i++) { /// remove the next node and set the currents next to 4 nodes down var removeNode = current.Next; current.Next = removeNode.Next.Next.Next; removeNode.Next.Next.Next = null; var destId = current.Id - 1; CupNode dest = null; while (dest == null) { if (destId == 0) { destId = maxNodeId; } if (removeNode.Id == destId || removeNode.Next.Id == destId || removeNode.Next.Next.Id == destId) { destId--; continue; } dest = cupDict[destId]; } removeNode.Next.Next.Next = dest.Next; dest.Next = removeNode; current = current.Next; } }
internal (CupNode beginPickUpNode, CupNode middlePickUpNode, CupNode endPickUpNode) PickUp() { CupNode begin = nextNode; CupNode middle = begin.nextNode; CupNode end = middle.nextNode; nextNode = end.nextNode; end.nextNode = null; return(begin, middle, end); }
public void Part1() { var numMoves = 100; var input = Input; var match = regInput.Match(input); CupNode current = null; CupNode start = null; CupNode printNode = null; Dictionary <long, CupNode> cupDict = new Dictionary <long, CupNode>(); long maxNodeId = -1; for (int i = 0; i < match.Groups[1].Captures.Count; i++) { CupNode newNode = new CupNode(long.Parse(match.Groups[1].Captures[i].Value)); maxNodeId = Math.Max(maxNodeId, newNode.Id); cupDict[newNode.Id] = newNode; if (i != 0) { current.Next = newNode; } else { start = newNode; } current = newNode; } current.Next = start; current = start; Console.Write($"\r\nInitial Order of cups: ({current.Id})"); printNode = current.Next; while (printNode != current) { Console.Write(printNode.Id); printNode = printNode.Next; } PlayRounds(current, numMoves, maxNodeId, cupDict); while (current.Id != 1) { current = current.Next; } Console.Write("\r\nFinal Order of cups after 1: "); printNode = current.Next; while (printNode != current) { Console.Write(printNode.Id); printNode = printNode.Next; } }
public void Part2() { var numMoves = 10000000; var input = Input; var match = regInput.Match(input); CupNode current = null; CupNode start = null; CupNode node1 = null; long maxNodeId = -1; Dictionary <long, CupNode> cupDict = new Dictionary <long, CupNode>(); for (int i = 0; i < match.Groups[1].Captures.Count; i++) { CupNode newNode = new CupNode(long.Parse(match.Groups[1].Captures[i].Value)); maxNodeId = Math.Max(maxNodeId, newNode.Id); cupDict[newNode.Id] = newNode; if (newNode.Id == 1) { node1 = newNode; } if (i != 0) { current.Next = newNode; } else { start = newNode; } current = newNode; } for (long i = maxNodeId + 1; i <= 1000000; i++) { CupNode newNode = new CupNode(i); current.Next = newNode; current = newNode; cupDict[newNode.Id] = newNode; } maxNodeId = current.Id; current.Next = start; current = start; PlayRounds(current, numMoves, maxNodeId, cupDict); var val1 = node1.Next.Id; var val2 = node1.Next.Next.Id; Console.WriteLine($"Values after 1 are: {val1} and {val2} for a product of {val1 * val2}."); }
private void InitLinkedList(List <int> input) { cupArray[0] = new CupNode(input[1]); CupNode prev = cupArray[0]; for (int i = 0; i < input.Count; i++) { var crabNode = new CupNode(input[i]); cupArray[i] = crabNode; prev.Next = crabNode; prev = crabNode; } prev.Next = cupArray[0]; }
private int GetDestination(int start, CupNode cuttingPoint, int highestId) { int dest = start == 1 ? highestId : start - 1; List <int> picks = new List <int> { cuttingPoint.Value, cuttingPoint.Next.Value, cuttingPoint.Next.Next.Value }; while (picks.Contains(dest)) { dest--; if (dest <= 0) { dest = highestId; } } return(dest); }