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)); }
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(); } }
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)); }
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])); } } }
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); }
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)); }