protected override ProblemOutput Solve(ProblemInput input) { var dictionary = input.Photos.GroupBy(photo => photo.IsVertical).ToDictionary(photos => photos.Key); IEnumerable <Photo> vertical = dictionary.ContainsKey(true) ? dictionary[true] : (IEnumerable <Photo>)Array.Empty <Photo>(); IEnumerable <Photo> horizontal = dictionary.ContainsKey(false) ? dictionary[false] : (IEnumerable <Photo>)Array.Empty <Photo>(); var slides = horizontal.Select(photo => new Slide(new List <Photo> { photo })) .Concat(VerticalUnifier.GetUnified(vertical.ToList(), NumbersGenerator)).ToList(); ProblemOutput res = new ProblemOutput(); res.Slides = new List <Slide>(); HashSet <int> notPaired = new HashSet <int>(Enumerable.Range(0, slides.Count)); //List<int> notPairedList = new List<int>(input.Photos.Select(x => x.Index).ToList()); var last = NumbersGenerator.Next(slides.Count); notPaired.Remove(last); res.Slides.Add(slides[last]); bool[] lastTags = new bool[input.TagCount]; for (int i = 0; i < slides.Count - 1; i++) { long bestScore = 0; int pairId = 0; foreach (var tagIndex in slides[last].TagsIndexes) { lastTags[tagIndex] = true; } for (int j = 0; j < 10; j++) { int nextId = this.NumbersGenerator.Next(0, slides.Count); while (!notPaired.Contains(nextId) || nextId == last) { nextId = this.NumbersGenerator.Next(0, slides.Count); } long myScore = Calcutaor.CalculatePhotosScore(slides[last], slides[nextId]); if (bestScore < myScore || pairId == 0) { bestScore = myScore; pairId = nextId; } } last = pairId; Array.Clear(lastTags, 0, lastTags.Length); notPaired.Remove(pairId); res.Slides.Add(slides[pairId]); } return(res); // TODO: add consideration for (1) vertical slides, (2) order between pairs. }
private Slide GetNextSlide(Dictionary <string, List <Slide> > tagToImages, HashSet <int> takenPhotos, List <Slide> input, Slide firstPhoto) { int maxScore = 0; int threshold = 4; Slide nex = null; foreach (var tag in firstPhoto.Tags) { if (tagToImages[tag].Count == 1) { continue; } foreach (var optionalImage in tagToImages[tag]) { bool isTaken = false; if (optionalImage.Images.Count == 1) { isTaken = takenPhotos.Contains(optionalImage.Images[0].Index); } else { isTaken = takenPhotos.Contains(optionalImage.Images[0].Index) || takenPhotos.Contains(optionalImage.Images[1].Index); } if (!isTaken) { var score = Calcutaor.CalculatePhotosScore(firstPhoto, optionalImage); if (score >= maxScore) { maxScore = score; nex = optionalImage; if (maxScore > threshold) { return(nex); } } } } } return(nex); }