Example #1
0
        // Some serious sub-optimal linq abuse going on here
        protected override int GetAnswer(string input)
        {
            var events        = ParseInput(input);
            var orderedEvents = events.OrderBy(e => e.Month)
                                .ThenBy(e => e.Day)
                                .ThenBy(e => e.Hour)
                                .ThenBy(e => e.Minute)
                                .ToArray();

            var guardInfos     = new Dictionary <int, GuardInfo>();
            var currentGuardId = 0;

            for (var i = 0; i < orderedEvents.Length - 1; i++)
            {
                var evnt = orderedEvents[i];

                switch (evnt.EventType)
                {
                case EventType.BeginShift:

                    currentGuardId = evnt.GuardId.Value;

                    if (!guardInfos.ContainsKey(currentGuardId))
                    {
                        guardInfos[currentGuardId] = new GuardInfo {
                            GuardId = currentGuardId
                        }
                    }
                    ;
                    break;

                case EventType.WakeUp:
                    // Nothing to do, only care about FallAsleep -> Wakeup Transitions
                    // Guards appear to always wake up before next guard shift
                    break;

                case EventType.FallAsleep:
                    var wakeUpEvent = orderedEvents[i + 1];
                    if (wakeUpEvent.EventType != EventType.WakeUp)
                    {
                        throw new Exception("Your assumption that a wake up event always follows fall asleep is wrong.");
                    }

                    for (var m = evnt.Minute; m < wakeUpEvent.Minute; m++)
                    {
                        guardInfos[currentGuardId].MinuteSleepCounter[m]++;
                        guardInfos[currentGuardId].TotalMinutesSlept++;
                    }

                    break;
                }
            }

            var max = guardInfos.Values.Select(gd => gd.TotalMinutesSlept).Max();
            var gi  = guardInfos.Values.First(gd => gd.TotalMinutesSlept == max);

            return(gi.Answer);
        }
Example #2
0
        public static Dictionary <int, GuardInfo> ParseGuards(List <Line> lines)
        {
            if (lines == null)
            {
                throw new ArgumentNullException(nameof(lines));
            }
            if (lines.Count == 0)
            {
                throw new ArgumentException("Value cannot be an empty collection.", nameof(lines));
            }

            var       guards       = new Dictionary <int, GuardInfo>();
            GuardInfo currentGuard = null;

            foreach (var line in lines)
            {
                if (line._kind == Line.Kind.BeginShift)
                {
                    if (!guards.ContainsKey(line._guardId))
                    {
                        guards.Add(line._guardId,
                                   new GuardInfo {
                            GuardId = line._guardId, Sleeps = new List <GuardInfo.SleepTime>()
                        });
                    }

                    currentGuard = guards[line._guardId];
                }
                else if (line._kind == Line.Kind.FallAsleep)
                {
                    currentGuard.Sleeps.Add(new GuardInfo.SleepTime {
                        Start = line._timestamp.Minute
                    });
                }
                else if (line._kind == Line.Kind.WakeUp)
                {
                    currentGuard.Sleeps.Last().End = line._timestamp.Minute;
                }
            }

            return(guards);
        }
Example #3
0
        public static (int Minute, int SleepCount) FindMinuteWithMaxSleep(this GuardInfo guard)
        {
            var sleepCountPerMinute = new int[60];

            for (var i = 0; i < guard.Sleeps.Count; i++)
            {
                var s = guard.Sleeps[i];
                for (var minute = s.Start; minute < s.End; minute++)
                {
                    sleepCountPerMinute[minute]++;
                }
            }

            var biggestIndex = 0;

            for (var i = 0; i < 60; i++)
            {
                if (sleepCountPerMinute[i] > sleepCountPerMinute[biggestIndex])
                {
                    biggestIndex = i;
                }
            }

            return(biggestIndex, sleepCountPerMinute[biggestIndex]);
Example #4
0
        static void Main(string[] args)
        {
            //sort input by date and time
            Regex           logRegex   = new Regex(@"\[1518-(\d\d)-(\d\d) (\d\d):(\d\d)\] (.*)");
            MatchCollection logEntries = logRegex.Matches(System.IO.File.ReadAllText("input.txt"));

            LogEntry[] entries = new LogEntry[logEntries.Count];
            for (int i = 0; i < logEntries.Count; i++)
            {
                //parse to get relevant info
                entries[i] = new LogEntry(int.Parse(logEntries[i].Groups[1].Value),
                                          int.Parse(logEntries[i].Groups[2].Value),
                                          int.Parse(logEntries[i].Groups[3].Value),
                                          int.Parse(logEntries[i].Groups[4].Value),
                                          logEntries[i].Groups[5].Value);
            }
            Array.Sort(entries);
            //read the log
            int guardID = 0, previousMinute = 0;
            Dictionary <int, GuardInfo> guards = new Dictionary <int, GuardInfo>();
            GuardInfo current, sleepiest = new GuardInfo
            {
                id    = 0,
                slept = 0,
                map   = new int[60]
            };

            //count minutes slept by each guard
            //and create a minute map to identify the most sleepy minute later
            foreach (LogEntry entry in entries)
            {
                if (entry.action.StartsWith('G')) //guard begins shift
                {
                    guardID = int.Parse(entry.action.Replace("Guard #", "").Split(" ")[0]);
                }
                else if (entry.action.StartsWith('f')) //guard falls asleep
                {
                    previousMinute = entry.minute;
                }
                else //guard wakes up
                {
                    if (guards.ContainsKey(guardID))
                    {
                        current = guards[guardID];
                    }
                    else
                    {
                        current = new GuardInfo
                        {
                            id    = guardID,
                            slept = 0,
                            map   = new int[60]
                        };
                        guards.Add(guardID, current);
                    }
                    current.slept += (entry.minute - previousMinute);
                    for (int i = previousMinute; i < entry.minute; i++)
                    {
                        current.map[i]++;
                    }
                    guards[guardID] = current;
                    if (current.slept > sleepiest.slept)
                    {
                        sleepiest = current;
                    }
                }
            }
            Console.WriteLine("Sleepiest guard is " + sleepiest.id);
            int maxSleepCount = sleepiest.map.Max();

            Console.WriteLine("Sleepiest minute is " + Array.IndexOf(sleepiest.map, maxSleepCount));
            Console.WriteLine("First answer: " + sleepiest.id * Array.IndexOf(sleepiest.map, maxSleepCount));
            //find absolute sleepiest minute and corresponding guard (second *)
            foreach (GuardInfo g in guards.Values)
            {
                if (g.map.Max() > maxSleepCount)
                {
                    sleepiest     = g;
                    maxSleepCount = g.map.Max();
                }
            }
            Console.WriteLine("Sleepiest guard is " + sleepiest.id);
            Console.WriteLine("Sleepiest minute is " + Array.IndexOf(sleepiest.map, maxSleepCount));
            Console.WriteLine("Second answer: " + sleepiest.id * Array.IndexOf(sleepiest.map, maxSleepCount));
            Console.Read();
        }
Example #5
0
        public static void Run(List <string> inputs)
        {
            GuardState       lastState  = GuardState.Off;
            GuardInfo        lastGuard  = null;
            int              lastMinute = 0;
            List <InputData> inputDatas = new List <InputData>();
            List <GuardInfo> Guards     = new List <GuardInfo>();

            foreach (var input in inputs)
            {
                inputDatas.Add(new InputData(input));
            }

            foreach (var data in inputDatas.OrderBy(i => i.Time))
            {
                var currentMinute = data.Time.Minute;
                if (data.Action == "Guard")
                {
                    if (lastState == GuardState.Sleep) // if last guard was sleeping, finish his shift sleeping
                    {
                        lastGuard.Sleep(lastMinute, MinutesInHour);
                    }

                    lastGuard = Guards.FirstOrDefault(g => g.GuardNum == data.GuardNum);
                    if (lastGuard == null)
                    {
                        lastGuard = new GuardInfo(data.GuardNum);
                        Guards.Add(lastGuard);
                    }
                    lastState = GuardState.Off;
                }
                else if (data.Action == "wakes")
                {
                    if (lastState == GuardState.Sleep)
                    {
                        lastGuard.Sleep(lastMinute, currentMinute);
                    }
                    lastState = GuardState.On;
                }
                else
                {
                    lastState = GuardState.Sleep;
                }

                lastMinute = currentMinute;
            }

            //part 1
            var lazyGuard =
                Guards.Aggregate((guard1, guard2) => guard1.GetSleepTime() > guard2.GetSleepTime() ? guard1 : guard2);

            var sleepTime = lazyGuard.GetHighestSleptHour();
            var answer1   = lastGuard.GuardNum * sleepTime;

            //part 2

            var mostFrequentlySleepingGuard =
                Guards.Aggregate(
                    (guard1, guard2) => guard1.GetMostSleptTime() > guard2.GetMostSleptTime() ? guard1 : guard2);
            var answer2 = mostFrequentlySleepingGuard.GetHighestSleptHour() * mostFrequentlySleepingGuard.GuardNum;
        }