Beispiel #1
0
 public void AppendCup(Cup root, Cup other)
 {
     other.Prev = this;
     other.Next = this.Next;
     this.Next  = other;
     root.Prev  = other;
 }
Beispiel #2
0
        public Cup LocateDestination(long value, Cup three, Cup[] cups)
        {
            Cup threeNext     = three.Next;
            Cup threeNextNext = threeNext.Next;

            long target = value;
            Cup  destination;

            while (target >= 1 && (target == three.Value || target == threeNext.Value || target == threeNextNext.Value))
            {
                target--;
            }
            if (target >= 1)
            {
                destination = cups[target];
            }
            else
            {
                // find maximum value in the ring
                long maxValue = cups.Length - 1;
                while (maxValue == three.Value || maxValue == threeNext.Value || maxValue == threeNextNext.Value)
                {
                    maxValue--;
                }
                destination = cups[maxValue];
            }

            return(destination);
        }
Beispiel #3
0
        private void Round()
        {
            var destination = _currentCup.Value;

            do
            {
                destination--;

                if (destination < _lowestValue)
                {
                    destination = _highestValue;
                }
            } while (destination == _currentCup.Next.Value ||
                     destination == _currentCup.Next.Next.Value ||
                     destination == _currentCup.Next.Next.Next.Value);

            var destinationCup = _cups[destination];

            var lastOfThree     = _currentCup.Next.Next.Next;
            var currentNext     = _currentCup.Next;
            var destinationNext = destinationCup.Next;

            _currentCup.Next    = lastOfThree.Next;
            destinationCup.Next = currentNext;
            lastOfThree.Next    = destinationNext;

            _currentCup = _currentCup.Next;
        }
Beispiel #4
0
        public void Move(int loops, int highest)
        {
            for (int i = 0; i < loops; i++)
            {
                Cup current  = last.Next;
                Cup first    = current.Next;
                Cup second   = first.Next;
                Cup third    = second.Next;
                int destiNum = (current.Data - 1);
                while (destiNum == first.Data || destiNum == second.Data ||
                       destiNum == third.Data || destiNum == 0)
                {
                    if (destiNum == 0)
                    {
                        destiNum = highest;
                        continue;
                    }
                    destiNum--;
                }
                Cup destination = Find(destiNum);

                last             = last.Next;
                current.Next     = third.Next;
                third.Next       = destination.Next;
                destination.Next = first;
            }
        }
        private static void RunSimulation(Cup current, int moves, Dictionary <int, Cup> map, int max)
        {
            for (int i = 0; i < moves; i++)
            {
                //pickup 3
                var pickupStart  = current.Next;
                var pickupEnd    = pickupStart.Next.Next;
                var pickUpValues = new HashSet <int>
                {
                    pickupStart.Value,
                    pickupStart.Next.Value,
                    pickupStart.Next.Next.Value
                };
                current.Next = pickupEnd.Next;
                //find destination cup
                var cupNextValue = current.Value;
                do
                {
                    cupNextValue--;
                    cupNextValue = cupNextValue == 0 ? max : cupNextValue;
                }while (pickUpValues.Contains(cupNextValue));

                var destination = map[cupNextValue];
                //insert picked up
                var tempNext = destination.Next;
                destination.Next = pickupStart;
                pickupEnd.Next   = tempNext;
                //select new current
                current = current.Next;
            }
        }
Beispiel #6
0
        public void Insert3(Cup firstOfThree)
        {
            Cup lastOfThree = firstOfThree.Next.Next;

            lastOfThree.Next  = this.Next;
            this.Next.Prev    = lastOfThree;
            this.Next         = firstOfThree;
            firstOfThree.Prev = this;
        }
        static void PrintClockwiseOf(Cup start)
        {
            var current = start.Next;

            do
            {
                Console.Write(current.Value);
                current = current.Next;
            } while (current != start);
            Console.Write(Environment.NewLine);
        }
Beispiel #8
0
        public Cup RemoveNext3()
        {
            Cup firstOfThree = this.Next;
            Cup lastOfThree  = firstOfThree.Next.Next;

            // point around the three
            lastOfThree.Next.Prev = this;
            this.Next             = lastOfThree.Next;

            return(firstOfThree);
        }
Beispiel #9
0
        public Cup Move(Cup[] cups)
        {
            // assumption: 'this' is the current cup
            Cup three       = RemoveNext3();
            Cup destination = LocateDestination(this.Value - 1, three, cups);

            destination.Insert3(three);

            // return is the new current cup
            return(this.Next);
        }
Beispiel #10
0
        public void Print()
        {
            Cup current = Find(1).Next;

            do
            {
                Console.Write(current.Data);
                current = current.Next;
            } while (current.Data != 1);
            Console.WriteLine();
        }
Beispiel #11
0
        // Second attempt to calculate part 2 faster.
        private static Cup MoveCupsFaster(List <int> originalCups, int numberOfMoves)
        {
            Dictionary <int, Cup> cups = new Dictionary <int, Cup>();
            Cup previousCup            = null;

            foreach (int cupValue in originalCups)
            {
                Cup cup = new Cup {
                    Value = cupValue
                };
                cups.Add(cupValue, cup);
                if (previousCup != null)
                {
                    cup.Previous     = previousCup;
                    previousCup.Next = cup;
                }
                previousCup = cup;
            }
            Cup firstCup = cups[originalCups.First()];

            firstCup.Previous = previousCup;
            previousCup.Next  = firstCup;

            Cup currentCup = firstCup;
            int minValue   = originalCups.Min();
            int maxValue   = originalCups.Max();

            for (int moves = 1; moves <= numberOfMoves; moves++)
            {
                Cup nextCup = currentCup.Next;
                currentCup.Next          = currentCup.Next.Next.Next.Next;
                currentCup.Next.Previous = currentCup;
                int destinationValue = currentCup.Value;
                do
                {
                    destinationValue--;
                    if (destinationValue < minValue)
                    {
                        destinationValue = maxValue;
                    }
                }while (destinationValue == nextCup.Value || destinationValue == nextCup.Next.Value || destinationValue == nextCup.Next.Next.Value);
                Cup destinationCup      = cups[destinationValue];
                Cup afterDestinationCup = destinationCup.Next;
                destinationCup.Next          = nextCup;
                nextCup.Previous             = destinationCup;
                afterDestinationCup.Previous = nextCup.Next.Next;
                nextCup.Next.Next.Next       = afterDestinationCup;
                currentCup = currentCup.Next;
            }

            return(cups[1]);
        }
Beispiel #12
0
        static void Main(string[] args)
        {
            //string puzzleInput = "389125467"; // TEST
            string puzzleInput = "562893147";

            int[] input = new int[9];
            for (int i = 0; i < puzzleInput.Length; i++)
            {
                input[i] = int.Parse(puzzleInput.Substring(i, 1));
            }


            CircleOfCups cups = new CircleOfCups();

            for (int i = 0; i < input.Length; i++)
            {
                cups.AddLast(input[i]);
            }

            cups.Move(100, 9);
            Console.WriteLine("Part 1: ");
            cups.Print();



            CircleOfCups cups2 = new CircleOfCups();

            for (int i = 0; i < input.Length; i++)
            {
                cups2.AddLast(input[i]);
            }
            for (int i = 10; i <= 1000000; i++)
            {
                cups2.AddLast(i);
            }
            cups2.Move(10000000, 1000000);


            Cup  one    = cups2.Find(1);
            long num1   = one.Next.Data;
            long num2   = one.Next.Next.Data;
            long result = num1 * num2;

            Console.WriteLine("Part 2: ");
            Console.WriteLine(result);
        }
Beispiel #13
0
        private static (Cup, Cup, Dictionary <int, Cup>) BuildCups(string input, int extras = 0)
        {
            var map   = new Dictionary <int, Cup>();
            var chars = input.ToCharArray();
            var start = new Cup {
                Value = int.Parse(chars[0].ToString())
            };

            map.Add(start.Value, start);
            var current = start;
            Cup oneCup  = null;

            for (int i = 1; i < chars.Length; i++)
            {
                var cup = new Cup {
                    Value = int.Parse(chars[i].ToString())
                };
                map.Add(cup.Value, cup);

                if (cup.Value == 1)
                {
                    oneCup = cup;
                }
                current.Next = cup;
                current      = cup;
            }

            var value = 10;

            for (int i = 0; i < extras; i++)
            {
                var cup = new Cup {
                    Value = value
                };
                map.Add(cup.Value, cup);
                current.Next = cup;
                current      = cup;
                value++;
            }
            //link end -> start
            current.Next = start;

            //reset current to start to begin
            current = start;
            return(current, oneCup, map);
        }
Beispiel #14
0
        public void AddLast(int data)
        {
            Cup newNode = new Cup(data);

            map.Add(data, newNode);
            if (last == null)
            {
                last      = newNode;
                last.Next = newNode;
                return;
            }

            Cup oldLast = last;

            newNode.Next = last.Next;
            oldLast.Next = newNode;
            last         = newNode;
        }
Beispiel #15
0
        public long Generate()
        {
            var rounds = 10000000;

            //Print(0);

            _currentCup = _cups.First().Value;
            for (var i = 0; i < rounds; i++)
            {
                Round();

                //Print(i);
            }

            var  cupOne = _cups[1];
            long result = (long)cupOne.Next.Value * (long)cupOne.Next.Next.Value;

            return(result);
        }
Beispiel #16
0
        public void Part1()
        {
            Cup root = new Cup(input[0]);
            Cup prev = root;

            Cup[] cups = new Cup[input.Length + 1];
            cups[root.Value] = root;

            for (int i = 1; i < input.Length; i++)
            {
                Cup cup = new Cup(input[i]);
                cups[cup.Value] = cup;
                prev.AppendCup(root, cup);
                prev = cup;
            }

            Cup currentCup = root;

            for (int i = 0; i < 100; i++)
            {
                currentCup = currentCup.Move(cups);
            }

            currentCup = cups[1].Next;


            long rslt = 0;

            while (currentCup.Value != 1)
            {
                rslt      *= 10;
                rslt      += currentCup.Value;
                currentCup = currentCup.Next;
            }

            Console.WriteLine("Part1: {0}", rslt);
        }
Beispiel #17
0
        static async Task Main(string[] args)
        {
            var lines = await File.ReadAllLinesAsync("input.txt");

            var cups = lines[0].Select(l => int.Parse(l.ToString())).ToList();

            //var part1 = MoveCups(cups, 100);

            //Console.WriteLine($"The current cup order is: {string.Join("", part1)}");

            Cup cupOne = MoveCupsFaster(cups, 100);

            Console.Write($"The current cup order is: ");

            Cup currentCup = cupOne.Next;

            while (currentCup != cupOne)
            {
                Console.Write(currentCup.Value);
                currentCup = currentCup.Next;
            }
            Console.WriteLine();

            for (int count = cups.Max() + 1; count <= 1000000; count++)
            {
                cups.Add(count);
            }

            //var part2 = MoveCups(cups, 10000000);

            //Console.WriteLine($"The current cup order is: {string.Join("", part2)}");

            cupOne = MoveCupsFaster(cups, 10000000);

            Console.WriteLine($"The part 2 product is: { ((long)cupOne.Next.Value) * ((long)cupOne.Next.Next.Value) }");
        }
Beispiel #18
0
 public Cup(int data)
 {
     this.Data = data;
     this.Next = null;
 }
Beispiel #19
0
        private static void RunCupSim(int numberOfTurns,
                                      Cup currentCup,
                                      Dictionary <int, Cup> cups,
                                      bool partTwo)
        {
            var currentTurn = numberOfTurns;

            while (currentTurn > 0)
            {
                currentTurn--;

                // Get first and last cups we'll move
                // 3 cups to right of current
                var firstCup = currentCup.Next;
                var lastCup  = currentCup.Next.Next.Next;

                // Remove from the circle
                currentCup.Next = lastCup.Next;
                firstCup.Prev   = null;
                lastCup.Next    = null;

                var destinationLabel = currentCup.Label - 1;

                var labelsToMove = new[]
                {
                    firstCup.Label,
                    firstCup.Next.Label,
                    lastCup.Label
                };

                while (true)
                {
                    if (destinationLabel < 1)
                    {
                        destinationLabel = partTwo
                                               ? 1_000_000
                                               : cups.Keys.Max();
                    }

                    if (labelsToMove.Contains(destinationLabel))
                    {
                        destinationLabel--;
                    }
                    else
                    {
                        break;
                    }
                }

                // Get destination
                var destinationCup = cups[destinationLabel];

                // Place the 3 cups after the destination
                var destinationNext = destinationCup.Next;

                destinationCup.Next = firstCup;
                firstCup.Prev       = destinationCup;

                destinationNext.Prev = lastCup;
                lastCup.Next         = destinationNext;

                // Select next current cup
                currentCup = currentCup.Next;
            }
        }
Beispiel #20
0
        public void Part2()
        {
            Cup root = new Cup(input[0]);
            Cup prev = root;

            Cup[] cups = new Cup[1_000_001];
Beispiel #21
0
        static void SolvePart1()
        {
            string                 _input = File.ReadAllText("Input.txt");
            List <string>          data   = _input.Split('\n').ToList();
            string                 s      = data[0];
            Dictionary <long, Cup> cups   = new Dictionary <long, Cup>();
            int index = 0;
            Cup prev = null, curr = null, first = null, begin = null;

            foreach (char c in s)
            {
                curr = new Cup {
                    value = int.Parse(c.ToString())
                };
                if (curr.value == 1)
                {
                    first = curr;
                }
                if (prev != null)
                {
                    prev.next = curr;
                }
                else
                {
                    begin = curr;
                }
                cups.Add(curr.value, curr);
                prev = curr;
                index++;
            }
            curr.next = begin;
            var cur = cups.First().Value;

            var dest = cur.value == 1 ? 9 : cur.value - 1;
            int goal = 100;

            for (int i = 0; i < goal; i++)
            {
                HashSet <Cup> moves = new HashSet <Cup>();
                moves = new HashSet <Cup> {
                    cur.next, cur.next.next, cur.next.next.next
                };
                cur.next = cur.next.next.next.next;
                //var tmp = new int[1] { cups[0] };
                //cups = tmp.Concat(cups[4..]).ToArray();
                while (moves.Any(c => c.value == dest))
                {
                    dest = dest == 1 ? 9 : dest - 1;
                }
                //var destIndex = Array.IndexOf(cups, dest);
                //s = s.Insert(s.IndexOf(dest.ToString()) + 1, moves);
                //cups = cups[0..destIndex].Concat(moves).Concat(cups[destIndex..]).ToArray();
                var destCup = cups[dest];
                var n       = destCup.next;
                destCup.next = moves.First();
                moves.Last().next = n;


                //s = ShiftString(s);
                //cups = ShiftArray(cups);
                //cur = int.Parse(s[0].ToString());
                cur  = cur.next;
                dest = cur.value == 1 ? 9 : cur.value - 1;
            }
            //while (cups[0] != 1)
            //{
            //    cups = ShiftArray(cups);
            //}
            //var firstCup = Array.IndexOf(cups, 1);
            Console.WriteLine("Final Output is " + first.next.value + first.next.next.value + first.next.next.next.value
                              + first.next.next.next.next.value + first.next.next.next.next.next.value + first.next.next.next.next.next.next.value
                              + first.next.next.next.next.next.next.next.value + first.next.next.next.next.next.next.next.next.value);
            //string _input = File.ReadAllText("Input.txt");
            //List<string> data = _input.Split('\n').ToList();
            //string s = data[0];
            //int[] cups = new int[9];
            //int index = 0;
            //foreach (char c in s)
            //{
            //    cups[index] = int.Parse(c.ToString());
            //    index++;
            //}
            //var cur = cups.First();
            //var dest = cur == 1 ? 9 : cur - 1;
            //int goal = 100;
            //index = 0;
            //for (int i = 0; i < goal; i++)
            //{
            //    string origS = s;
            //    string moves = "";
            //    for (int x = 0; x < 3; x++)
            //    {
            //        moves += s[index + 1];
            //        s = s.Remove(index + 1, 1);
            //    }
            //    while (!s.Contains(dest.ToString()))
            //    {
            //        dest = dest == 1 ? 9 : dest - 1;
            //    }
            //    s = s.Insert(s.IndexOf(dest.ToString()) + 1, moves);
            //    s = ShiftString(s);
            //    cur = int.Parse(s[0].ToString());
            //    dest = cur == 1 ? 9 : cur - 1;
            //}
            //while (s[0] != '1')
            //{
            //    s = ShiftString(s);
            //}
            //Console.WriteLine("Final Output is " + s[1..]);
        }