Exemple #1
0
        protected ProblemOutput Solve2(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();
            Dictionary <string, List <Slide> > tagToImages = new Dictionary <string, List <Slide> >();

            // HashSet<string> tags = new HashSet<string>();
            foreach (var image in slides)
            {
                foreach (var tag in image.Tags)
                {
                    //  tags.Add(tag);
                    if (tagToImages.ContainsKey(tag))
                    {
                        tagToImages[tag].Add(image);
                    }
                    else
                    {
                        tagToImages.Add(tag, new List <Slide>()
                        {
                            image
                        });
                    }
                }
            }

            ProblemOutput res = new ProblemOutput();

            res.Slides = new List <Slide>();
            HashSet <int> takenPhotos = new HashSet <int>();

            int count     = 1;
            int index     = 1;
            int lastTaken = 0;

            var first = GetFirstSlide(takenPhotos, slides);

            res.Slides.Add(first);
            takenPhotos.Add(first.Images[0].Index);
            if (first.Images.Count == 2)
            {
                takenPhotos.Add(first.Images[1].Index);
            }

            while (count < input.Photos.Length && index < slides.Count)
            {
                count++;
                var   photo     = res.Slides[res.Slides.Count - 1];
                Slide nextSlide = GetNextSlide(tagToImages, takenPhotos, slides, photo);
                if (nextSlide == null)
                {
                    var randomSlide = GetFirstSlide(takenPhotos, slides);
                    if (randomSlide == null)
                    {
                        break;
                    }
                    takenPhotos.Add(randomSlide.Images[0].Index);
                    if (randomSlide.Images.Count == 2)
                    {
                        takenPhotos.Add(randomSlide.Images[1].Index);
                    }
                    res.Slides.Add(randomSlide);
                }
                else
                {
                    takenPhotos.Add(nextSlide.Images[0].Index);
                    if (nextSlide.Images.Count == 2)
                    {
                        takenPhotos.Add(nextSlide.Images[1].Index);
                    }
                    res.Slides.Add(nextSlide);
                }
            }

            return(res);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        protected override ProblemOutput Solve(ProblemInput input)
        {
            var allPhotos = input.Photos.ToArray();
            var totalTags = input.TagCount;

            var usedInASlideC = new ConcurrentDictionary <long, byte>();

            var   usedInASlide = new HashSet <long>();
            Slide lastSlide;

            ////for (int i = 0; i < allPhotos.Length; i++)
            ////{
            ////    var bestScore = -1;

            ////    for (int j = 0; j < allPhotos.Length; j++)
            ////    {
            ////        int currScore = -1;
            ////        if (visited.Contains(j))
            ////        {
            ////            continue;
            ////        }
            ////        currScore = CalclateScoreForCurrentSlide(lastSlide, allPhotos[i], allPhotos[j]);
            ////        if (bestScore < currScore)
            ////        {

            ////        }
            ////    }
            ////}

            // Build First Slide
            List <Slide> slides = new List <Slide>();

            if (!allPhotos.First().IsVertical)
            {
                lastSlide = new Slide(new List <Photo>()
                {
                    allPhotos.First()
                });
            }
            else
            {
                lastSlide = new Slide(new List <Photo>()
                {
                    allPhotos.First(), allPhotos.Skip(1).First(_ => _.IsVertical)
                });
            }

            slides.Add(lastSlide);
            foreach (var photo in lastSlide.Images)
            {
                usedInASlide.Add(photo.Index);
                usedInASlideC.TryAdd(photo.Index, 0);
            }

            var lastSlideTagsBool = new bool[input.TagCount];
            var pairTagsBool      = new bool[input.TagCount];

            while (usedInASlide.Count != allPhotos.Length)
            {
                Array.Clear(lastSlideTagsBool, 0, lastSlideTagsBool.Length);
                int lastSlideTagCount = 0;
                foreach (var tagIndex in lastSlide.TagsIndexes)
                {
                    lastSlideTagsBool[tagIndex] = true;
                    lastSlideTagCount++;
                }

                // build a slide
                long  bestScore  = -1;
                Slide slideToUse = null;

                Parallel.ForEach(Partitioner.Create(1, allPhotos.Length), range =>
                {
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        if (usedInASlideC.ContainsKey(i))
                        {
                            continue;
                        }

                        // Build a slide with this photo

                        var potentialSlide = new Slide(new List <Photo>()
                        {
                            allPhotos[i]
                        });

                        long ScoreIfUsed = CalculateScoreForNewSlide(allPhotos[i], lastSlideTagsBool, lastSlideTagCount);

                        if (ParallelHelper.InterlockedExchangeIfGreaterThan(ref bestScore, ScoreIfUsed))
                        {
                            // use this
                            //bestScore = ScoreIfUsed;
                            lock (slides)
                            {
                                slideToUse = potentialSlide;
                            }
                        }
                    }
                });

                //for (int i = 1; i < allPhotos.Length; i++)
                //{
                //    // Skip if already used
                //    if (usedInASlide.Contains(i))
                //    {
                //        continue;
                //    }

                //    // Build a slide with this photo

                //    var potentialSlide = new Slide(new List<Photo>() { allPhotos[i] });

                //    long ScoreIfUsed = CalculateScoreForNewSlide(allPhotos[i], lastSlideTagsBool, lastSlideTagCount);

                //    if (bestScore < ScoreIfUsed)
                //    {
                //        // use this
                //        slideToUse = potentialSlide;
                //        bestScore = ScoreIfUsed;
                //    }
                //}

                // if slideToUse is lonely V, find it a pair:
                if (slideToUse.Images.First().IsVertical)
                {
                    // Build Pair Bool
                    Array.Clear(pairTagsBool, 0, pairTagsBool.Length);
                    foreach (var tagindex in slideToUse.Images.First().TagIndexes)
                    {
                        pairTagsBool[tagindex] = true;
                    }

                    long   bestScoreForV = -1;
                    Photo  vPair         = null;
                    object lockpair      = new object();

                    Parallel.ForEach(Partitioner.Create(1, allPhotos.Length), range =>
                    {
                        for (int i = range.Item1; i < range.Item2; i++)
                        {
                            if (usedInASlideC.ContainsKey(i) || !allPhotos[i].IsVertical || i == slideToUse.Images.First().Index)
                            {
                                continue;
                            }

                            long scoreIfUsed = CalculateScoreForVPair(lastSlideTagsBool, lastSlideTagCount, slideToUse.Images.First(), allPhotos[i], pairTagsBool);

                            if (ParallelHelper.InterlockedExchangeIfGreaterThan(ref bestScoreForV, scoreIfUsed))
                            {
                                lock (lockpair)
                                {
                                    vPair = allPhotos[i];
                                }
                            }
                        }
                    });

                    //for (int i = 0; i < allPhotos.Length; i++)
                    //{
                    //    if (usedInASlide.Contains(i) || !allPhotos[i].IsVertical || i == slideToUse.Images.First().Index)
                    //    {
                    //        continue;
                    //    }

                    //    ////foreach (var tagIndex in allPhotos[i].TagIndexes)
                    //    ////{
                    //    ////    pairTagsBool[tagIndex] = true;
                    //    ////}
                    //    long scoreIfUsed = CalculateScoreForVPair(lastSlideTagsBool, lastSlideTagCount, slideToUse.Images.First(), allPhotos[i]);

                    //    if (bestScoreForV < scoreIfUsed)
                    //    {
                    //        vPair = allPhotos[i];
                    //        bestScoreForV = scoreIfUsed;
                    //    }
                    //}

                    if (vPair == null)
                    {
                        var vertsNotUsed = allPhotos.Where(p => p.IsVertical && !usedInASlide.Contains(p.Index)).ToArray();
                    }

                    slideToUse.Images.Add(vPair);
                }

                slides.Add(slideToUse);
                foreach (var photo in slideToUse.Images)
                {
                    usedInASlide.Add(photo.Index);
                    usedInASlideC.TryAdd(photo.Index, 0);
                }
                lastSlide = slideToUse;
            }
            return(new ProblemOutput()
            {
                Slides = slides
            });
        }