Exemplo n.º 1
0
        private long CalculateScoreForVPair(bool[] lastTagsInBool, int lastSlideTagCount, Photo firstV, Photo secondV, bool[] firstVTagsInBool)
        {
            int score = 0;

            int interSize = 0;

            int commontagscount = 0;

            foreach (var tagindex in firstV.TagIndexes)
            {
                if (lastTagsInBool[tagindex])
                {
                    interSize++;
                }
            }
            foreach (var tagindex in secondV.TagIndexes)
            {
                if (firstVTagsInBool[tagindex])
                {
                    commontagscount++;
                    continue;
                    // not counting it again
                }
                if (lastTagsInBool[tagindex])
                {
                    interSize++;
                }
            }

            int totalTagsCount = firstV.TagIndexes.Length + secondV.TagIndexes.Length - commontagscount;

            score = Math.Min(Math.Min(interSize, totalTagsCount - interSize),
                             lastSlideTagCount - interSize);

            return(score);
        }
Exemplo n.º 2
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
            });
        }