Пример #1
0
        /// <summary>
        /// print what the circle looks like right now
        /// </summary>
        /// <param name="player">The player who just made a turn</param>
        /// <param name="firstMarble">The first marble in the circle.</param>
        /// <param name="currentMarble">The current active marble</param>
        private static void printCircle(Player player, Marble firstMarble, Marble currentMarble)
        {
            if (player == null)
            {
                Console.Write("[---] ");
            }
            else
            {
                Console.Write($"[{player.Number:000}] ");
            }

            var printingMarble = firstMarble;

            do
            {
                if (printingMarble == currentMarble)
                {
                    Console.Write($"({printingMarble.Score})");
                }
                else
                {
                    Console.Write($" {printingMarble.Score} ");
                }

                printingMarble = printingMarble.Next;
            } while (printingMarble != firstMarble);

            Console.WriteLine(String.Empty);
        }
Пример #2
0
 /// <summary>
 /// Inserts a marble longo the next position
 /// </summary>
 /// <param name="marble"></param>
 public void Insert(Marble marble)
 {
     Next.Previous   = marble;
     marble.Next     = Next;
     marble.Previous = this;
     Next            = marble;
 }
Пример #3
0
        internal void InsertCW(Marble newMarble)
        {
            var oldCw = CW;

            this.CW       = newMarble;
            newMarble.CCW = this;

            oldCw.CCW    = newMarble;
            newMarble.CW = oldCw;
        }
Пример #4
0
        /// <summary>
        /// Return the marble a certain number of marbles previous to this one
        /// </summary>
        /// <param name="currentMarble">The marble to count back from</param>
        /// <param name="thisManyBack">The number of marbles to count back</param>
        /// <returns>The marble</returns>
        private static Marble GetMarblesBack(Marble currentMarble, long thisManyBack)
        {
            Marble ret = currentMarble;

            for (long i = 0; i < thisManyBack; i++)
            {
                ret = ret.Previous;
            }

            return(ret);
        }
Пример #5
0
        /// <summary>
        /// Play the game
        /// </summary>
        /// <param name="playerCount">The number of players playing</param>
        /// <param name="lastMarble">How many marbles</param>
        /// <param name="printMoves">flag to say ig it should print each move or not</param>
        /// <returns>The highest score of any of the players once the game has completed</returns>
        public static (long player, long score) PlayGame(long playerCount, long lastMarble, bool printMoves = false)
        {
            //let's start with marble 0; it's a single marble circle.
            var  currentMarble = new Marble(0);
            var  firstMarble   = currentMarble;
            var  players       = CreatePlayers(playerCount);
            long currentPlayer = 0;

            if (printMoves)
            {
                printCircle(null, firstMarble, currentMarble);
            }

            //for each marble, in order
            for (long marbleNumber = 1; marbleNumber <= lastMarble; marbleNumber++)
            {
                //get the next marble
                var nextMarble = new Marble(marbleNumber);
                if (nextMarble.IsScoringMarble)
                {
                    //do the scoring logic
                    players[currentPlayer].OwnedMarbles.Add(nextMarble);
                    nextMarble    = GetMarblesBack(currentMarble, 7);
                    currentMarble = nextMarble.Next;
                    nextMarble    = nextMarble.Previous.RemoveNext();
                    players[currentPlayer].OwnedMarbles.Add(nextMarble);
                }
                else
                {
                    currentMarble.Next.Insert(nextMarble);
                    currentMarble = nextMarble;
                }

                if (printMoves)
                {
                    printCircle(players[currentPlayer], firstMarble, currentMarble);
                }

                //find the next player
                currentPlayer = GetNextPlayerIndex(currentPlayer, playerCount);
            }

            //game over, who's got the highest score?
            var highscore = players.Max(x => x.OwnedMarbles.Sum(y => y.Score));
            var winner    = players.First(x => x.MarbleScore == highscore).Number;

            return(winner, highscore);
        }
Пример #6
0
        static void Main(string[] args)
        {
            using (var sr = new StreamReader("input.txt"))
            {
                var input           = sr.ReadToEnd();
                var regex           = new Regex(@"(?<numberOfPlayers>\d+) .* worth (?<lastMarbleValue>\d+)");
                var match           = regex.Match(input);
                int numberOfPlayers = int.Parse(match.Groups["numberOfPlayers"].Value);
                int lastMarbleValue = int.Parse(match.Groups["lastMarbleValue"].Value);

                var players = new List <Player>();
                for (int i = 1; i <= numberOfPlayers; i++)
                {
                    players.Add(new Player(i));
                }

                var marbles           = new LinkedList <Marble>();
                var firstMarble       = new Marble(0);
                var currentMarbleNode = marbles.AddFirst(firstMarble);

                for (int currentMarbleNumber = 1; currentMarbleNumber <= lastMarbleValue; currentMarbleNumber++)
                {
                    if (currentMarbleNumber % 23 == 0)
                    {
                        var playerGettingPoints = players.ElementAt(currentMarbleNumber % numberOfPlayers);
                        var marbleToDelete      = GoBack7(marbles, currentMarbleNode);

                        playerGettingPoints.NumberOfPoints += currentMarbleNumber + marbleToDelete.Value.Value;
                        currentMarbleNode = marbleToDelete.Next ?? marbles.First;
                        marbles.Remove(marbleToDelete);
                    }
                    else
                    {
                        var marbleToInsertAfter = currentMarbleNode.Next ?? marbles.First;
                        currentMarbleNode = marbles.AddAfter(marbleToInsertAfter, new Marble(currentMarbleNumber));
                    }
                }

                //Excercise 1
                Console.WriteLine($"Excercise 1 - max score: {players.Max(x => x.NumberOfPoints)}");

                for (int currentMarbleNumber = lastMarbleValue + 1; currentMarbleNumber <= lastMarbleValue * 100; currentMarbleNumber++)
                {
                    if (currentMarbleNumber % 23 == 0)
                    {
                        var playerGettingPoints = players.ElementAt(currentMarbleNumber % numberOfPlayers);
                        var marbleToDelete      = GoBack7(marbles, currentMarbleNode);

                        playerGettingPoints.NumberOfPoints += currentMarbleNumber + marbleToDelete.Value.Value;
                        currentMarbleNode = marbleToDelete.Next ?? marbles.First;
                        marbles.Remove(marbleToDelete);
                    }
                    else
                    {
                        var marbleToInsertAfter = currentMarbleNode.Next ?? marbles.First;
                        currentMarbleNode = marbles.AddAfter(marbleToInsertAfter, new Marble(currentMarbleNumber));
                    }
                }

                //Excercise 2
                Console.WriteLine($"Excercise 2 - max score: {players.Max(x => x.NumberOfPoints)}");
            }
        }
Пример #7
0
        public static long A(int numPlayers, int maxMarble)
        {
            long[] scores        = new long[numPlayers];
            int    currentPlayer = 0;

            //first marble
            Marble current = new Marble(0);

            current.CW  = current;
            current.CCW = current;

            // the rest of the marbles
            for (int marble = 1; marble <= maxMarble; marble++)
            {
                var newMarble = new Marble(marble);
                if (marble % 23 == 0)
                {
                    scores[currentPlayer] += marble;

                    var toRemove = current.CCW.CCW.CCW.CCW.CCW.CCW.CCW;
                    toRemove.CW.CCW        = toRemove.CCW;
                    toRemove.CCW.CW        = toRemove.CW;
                    scores[currentPlayer] += toRemove.Value;

                    current = toRemove.CW;
                }
                else
                {
                    current.CW.InsertCW(newMarble);
                    current = newMarble;
                }

                currentPlayer = (currentPlayer + 1) % numPlayers;

                if (false)
                {
                    //Debug output, compare to example on webpage
                    var initial = current;
                    while (initial.Value != 0)
                    {
                        initial = initial.CW;
                    }
                    Console.Write($"[{(currentPlayer == 0 ? numPlayers : currentPlayer),2}]");
                    do
                    {
                        if (initial.Value == current.Value)
                        {
                            Console.Write($"({initial.Value,2})");
                        }
                        else
                        {
                            Console.Write($" {initial.Value,2} ");
                        }
                        initial = initial.CW;
                    } while (initial.Value != 0);
                    Console.WriteLine("");
                }
            }

            return(scores.Max());
        }
Пример #8
0
        static void Main(string[] args)
        {
            int playerNumber    = 455;
            int lastMarbleValue = 7122300;
            var marblesInCircle = new LinkedList <Marble>();

            marblesInCircle.AddFirst(new Marble(0));
            marblesInCircle.AddLast(new Marble(1));

            var playerScores = new Dictionary <int, long>();

            for (int i = 0; i < playerNumber; i++)
            {
                playerScores[i] = 0;
            }

            bool gameEnd    = false;
            int  roundCount = 2;
            LinkedListNode <Marble> currentMarble = marblesInCircle.Last;

            var sw = Stopwatch.StartNew();

            while (!gameEnd)
            {
                // point score
                if (roundCount % 23 == 0)
                {
                    var additionalMarbleToTake = GetNthCounterClockwiseElement(currentMarble, 7);

                    if (additionalMarbleToTake.Next != null)
                    {
                        currentMarble = additionalMarbleToTake.Next;
                    }
                    else
                    {
                        currentMarble = marblesInCircle.First;
                    }

                    marblesInCircle.Remove(additionalMarbleToTake);

                    int currentPlayerIndex = roundCount % playerNumber;
                    playerScores[currentPlayerIndex] += additionalMarbleToTake.Value.Value + roundCount;
                }
                else // standard placing
                {
                    var newMarbleToAdd = new Marble(roundCount);

                    if (currentMarble.Next == null)
                    {
                        currentMarble = marblesInCircle.AddAfter(marblesInCircle.First, newMarbleToAdd);
                    }
                    else
                    {
                        currentMarble = marblesInCircle.AddAfter(currentMarble.Next, newMarbleToAdd);
                    }
                }

                if (roundCount == lastMarbleValue)
                {
                    gameEnd = true;
                }

                roundCount++;
            }
            sw.Stop();

            var playerWithMaxPoint = playerScores.Aggregate((l, r) => l.Value > r.Value ? l : r);

            Console.WriteLine($"Winner: player {playerWithMaxPoint.Key} with value {playerWithMaxPoint.Value}");
            Console.WriteLine($"Time: {sw.ElapsedMilliseconds} ms");
            Console.ReadKey();
        }
Пример #9
0
 public Marble(long score)
 {
     Score = score;
     //default next and previous to self. a circle of one.
     Next = Previous = this;
 }