public async Task <Prediction> PredictAsync(Guid sequenceId, Models.TrafficLight trafficLight)
        {
            var observations = (await storage.FindObservationAsync(sequenceId)).ToArray();

            if (observations.Any(x => x.TrafficLight.Equals(trafficLight)))
            {
                Throws.DuplicateObservation();
            }

            var predictedDigits = timePredictor.Predict(trafficLight, observations);

            var decrementedDigits = observations.Length == 0
                ? predictedDigits
                : predictedDigits.Select(x => x - observations.Length);

            var faultySections = expert.IdentifyBrokenSections(trafficLight, decrementedDigits.ToArray(), observations);

            await storage.SaveObservationAsync(sequenceId, trafficLight, decrementedDigits);

            var starts = predictedDigits
                         .Select(x => x.ToNumber())
                         .ToArray();

            var missings = faultySections.ToBitString();

            return(new Prediction(starts, missings));
        }
示例#2
0
        private void Validate(Models.TrafficLight trafficLight, Observation[] previous)
        {
            if (previous.Length == 0 && trafficLight.Color == Color.Red)
            {
                Throws.NotEnoughData();
            }

            if (previous.Length > 0 && previous.Last().TrafficLight.Color == Color.Red)
            {
                Throws.RedShouldBeTheLast();
            }
        }
示例#3
0
        public TrafficLightDigits GetSectionsThatWasTurnedOff(Models.TrafficLight trafficLight, Observation[] observations)
        {
            // all sections are true
            var current = new TrafficLightDigits(88);

            foreach (var o in observations)
            {
                // all sections are false
                if (current.Equals(TrafficLightDigits.Default))
                {
                    return(current);
                }

                current = JoinBrokenSections(o.TrafficLight.Digits, current);
            }

            return(JoinBrokenSections(trafficLight.Digits, current));
        }
示例#4
0
        public IEnumerable <TrafficLightDigits> Predict(Models.TrafficLight trafficLight, Observation[] previousObservations)
        {
            if (trafficLight.Color == Color.Red)
            {
                yield return(new TrafficLightDigits(0));

                yield break;
            }

            var sectionsThatWasTurnedOff = expert.GetSectionsThatWasTurnedOff(trafficLight, previousObservations);

            if (AreAllSectionsServiceable(sectionsThatWasTurnedOff))
            {
                yield return(trafficLight.Digits);

                yield break;
            }

            var digit = trafficLight.Digits;

            var hightLevel = Digits
                             .Where(x => x.MaybeEquals(digit.High));

            if (AreAllSectionsServiceable(sectionsThatWasTurnedOff.Low))
            {
                foreach (var high in hightLevel)
                {
                    yield return(new TrafficLightDigits(high, digit.Low));
                }

                yield break;
            }

            var lowLevel = Digits.Where(x => x.MaybeEquals(digit.Low)).ToArray();

            foreach (var high in hightLevel)
            {
                for (var i = 0; i < lowLevel.Length; i++)
                {
                    yield return(new TrafficLightDigits(high, lowLevel[i]));
                }
            }
        }
示例#5
0
        public TrafficLightDigits[] Predict(Models.TrafficLight trafficLight, Observation[] previous)
        {
            Validate(trafficLight, previous);

            var predictedDigits = predictor
                                  .Predict(trafficLight, previous)
                                  .ToArray();

            var solutions = predictedDigits;

            if (previous.Length == 0)
            {
                return(predictedDigits);
            }

            if (IsSolutionFound(solutions))
            {
                solutions[0] += previous.Length;

                if (!previous[0].PredictedDigits.Contains(solutions[0]))
                {
                    Throws.NoSolutionFound();
                }

                return(solutions);
            }

            for (var i = previous.Length - 1; i >= 0; i--)
            {
                var prev        = previous[i];
                var incremented = IncrementAllDigits(solutions);

                solutions = prev.PredictedDigits.Intersect(incremented).ToArray();

                if (solutions.Length == 0)
                {
                    Throws.NoSolutionFound();
                }
            }

            return(solutions);
        }
示例#6
0
        public TrafficLightDigits IdentifyBrokenSections(Models.TrafficLight currentTrafficLight, TrafficLightDigits[] currentPredictedDigits, Observation[] previousObservations)
        {
            var current = IdentifyBrokenSectionsInternal(currentTrafficLight.Digits, currentPredictedDigits);

            var digits = currentPredictedDigits;

            for (var i = previousObservations.Length - 1; i >= 0; i--)
            {
                for (var j = 0; j < digits.Length; j++)
                {
                    digits[j]++;
                }

                var observation        = previousObservations[i];
                var trafficLightDigits = observation.TrafficLight.Digits;

                current = Join(current, IdentifyBrokenSectionsInternal(trafficLightDigits, digits));

                current = JoinBrokenSections(observation.TrafficLight.Digits, current);
            }

            return(JoinBrokenSections(currentTrafficLight.Digits, current));
        }