public Instance(FileGenLayout layout, MannagerConfig mConfig)
 {
     this.mConfig             = mConfig;
     this.fileName            = layout.getFileName();
     this.problem             = layout.getProblem();
     this.workedSequence      = layout.getWorkedSequence();
     this.attributionSequence = layout.getAttributionSequence();
     this.morningShift        = layout.getMorningShift();
     this.afternoonShift      = layout.getAfternoonShift();
     this.nightShift          = layout.getNightShift();
     this.dayOff = layout.getDayOff();
 }
Beispiel #2
0
        public void SolvePart1()
        {
            // First lets parse the array input and add everything to the list
            for (int i = 0; i < puzzleInput.Length; i++)
            {
                // Break the line into a word array
                string[] wordArray = puzzleInput[i].Split(' ');

                // The first two element makes the date and time.
                // [1518-11-01 00:00]
                int month  = int.Parse(wordArray[0].Substring(6, 2));
                int day    = int.Parse(wordArray[0].Substring(9, 2));
                int hour   = int.Parse(wordArray[1].Substring(0, 2));
                int minute = int.Parse(wordArray[1].Substring(3, 2));

                // There is a cheeky gottcha in this where guards can start the shift on the day before
                // like this: [1518-11-01 23:58] Guard #99 begins shift
                // We can check for that by getting the hour component, and checking if it is differant from 0;
                if (hour != 0)
                {
                    day++;
                }

                // also it may not be nessasary but for sake of compleation we need to wrap the days in months
                // I did see a case where this will be required in my input, but the wrap around around for
                // the year is not required since every timestamp is from 1518, and there are no dates from month 12 in my input
                switch (month)
                {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    if (day > 31)
                    {
                        day = 1;
                        month++;
                    }
                    break;

                case 4:
                case 6:
                case 9:
                case 11:
                    if (day > 30)
                    {
                        day = 1;
                        month++;
                    }

                    break;

                case 2:
                    if (day > 28)
                    {
                        day = 1;
                        month++;
                    }
                    break;

                default:
                    break;
                }

                // now we have valid dates and times for things. the ways the problem is described we know that no only guard changes can happen
                // before midnight, and that we can safely assume that the guards only sleep between 00 and 59.
                // the important thing to know that will be in out dictionary of shifts is the date.
                // Referance to the nightshift we are lookin at:
                NightShift thisShift;

                string monthDayString = month.ToString().PadLeft(2, '0') + "-" + day.ToString().PadLeft(2, '0');

                // is this key her already?
                if (nightShifts.ContainsKey(monthDayString))
                {
                    thisShift = nightShifts[monthDayString];
                }
                // else make a new shift and add it.
                else
                {
                    thisShift = new NightShift(monthDayString);
                    nightShifts.Add(monthDayString, thisShift);
                }
                // now its time to add new information to the shift.
                // there are 3 possible things that can be added at this point (Guard, falls or wakes)
                // [1518-11-01 00:00] Guard #10 begins shift
                // [1518-11-01 00:05] falls asleep
                // [1518-11-01 00:25] wakes up
                switch (wordArray[2])
                {
                case "Guard":
                    // this tells us about the guard for this shift
                    thisShift.GuardID = wordArray[3];
                    // does this guard exist in our list of guards?
                    if (!allGuards.ContainsKey(wordArray[3]))
                    {
                        allGuards.Add(wordArray[3], new Guard(wordArray[3]));
                    }
                    break;

                case "falls":
                    thisShift.Sleeping[minute] = 1;
                    break;

                case "wakes":
                    thisShift.Sleeping[minute] = 0;
                    break;

                default:
                    break;
                }
            }

            // Now the entire list has been made and can be sorted
            var l   = nightShifts.OrderBy(key => key.Key);
            var dic = l.ToDictionary((keyItem) => keyItem.Key, (valueItem) => valueItem.Value);

            nightShifts = dic;


            Console.Clear();
            Console.WriteLine("Date\tID\tMinute");
            Console.WriteLine("\t\t000000000011111111112222222222333333333344444444445555555555");
            Console.WriteLine("\t\t012345678901234567890123456789012345678901234567890123456789");

            foreach (var item in nightShifts)
            {
                // this list is sorted, but that matters little for this operation:
                // we added awake and sleep info when we read the input list, but only the point where the guard falls asleep, or wakes up.
                // so now we need to padd out the stages in between

                // this is where we store what happened last minute.
                int lastMinute = 0;

                // now we iterate
                for (int i = 0; i < item.Value.Sleeping.Length; i++)
                {
                    // is this element blank(-1)?
                    if (item.Value.Sleeping[i] == -1)
                    {
                        // then write the status of the last minute
                        item.Value.Sleeping[i] = lastMinute;
                    }
                    // if this wasn't -1, then is is either 0(awake) or 1(sleeping).
                    else
                    {
                        // regardless of what is was, we don't want to update it, but we want to save this as the last thign
                        // that has happend
                        lastMinute = item.Value.Sleeping[i];
                    }
                }


                // now we print the cool graph because we like cool things
                // we also take the oppertunity to count the sleeping minutes of each guard since we are itterating anyway
                Console.Write("{0}\t{1}\t", item.Value.Date, item.Value.GuardID);
                int shiftSleeing = 0;
                for (int i = 0; i < item.Value.Sleeping.Length; i++)
                {
                    if (item.Value.Sleeping[i] == 0)
                    {
                        Console.Write(".");
                    }
                    else
                    {
                        Console.Write("#");
                        shiftSleeing++;
                        // PART2: we count sleep in this minute
                        allGuards[item.Value.GuardID].sleeps[i]++;
                    }
                }
                // add this sleep to the guards overall sleep.
                allGuards[item.Value.GuardID].sleepingHours = allGuards[item.Value.GuardID].sleepingHours + shiftSleeing;
                Console.Write("\n");
            }

            Console.WriteLine("There are {0} unique guards in this list", allGuards.Count);
            Console.ReadLine();
            int    sleepMax = 0;
            string guardID  = "";

            foreach (Guard g in allGuards.Values)
            {
                if (g.sleepingHours > sleepMax)
                {
                    sleepMax = g.sleepingHours;
                    guardID  = g.guardID;
                }
            }
            Console.WriteLine("{0} sleeps the most with a total of {1} minutes", guardID, sleepMax);
            Console.ReadLine();

            int[] sleepMinutes = new int[60];
            // now lets analyze ever minute where our guard sleeps, and count out when he sleeps most often
            for (int i = 0; i < sleepMinutes.Length; i++)
            {
                foreach (NightShift ns in nightShifts.Values)
                {
                    // is if the correct guard?
                    if (ns.GuardID == guardID)
                    {
                        sleepMinutes[i] = sleepMinutes[i] + ns.Sleeping[i];
                    }
                }
            }
            // now that sleep minutes contains a record of how often he sleeps for each minute we can find the max
            int maxSleeptMinute   = 0;
            int maxSleeptMinuteID = 0;

            for (int i = 0; i < sleepMinutes.Length; i++)
            {
                if (sleepMinutes[i] > maxSleeptMinute)
                {
                    maxSleeptMinute   = sleepMinutes[i];
                    maxSleeptMinuteID = i;
                }
            }
            Console.WriteLine("That Guard sleeps most often on minute {0}", maxSleeptMinuteID);
        }