//----==== PRIVATE ====----------------------------------------------------------------------

        private void AddToTopList(IMovieList sample)
        {
            if (_topLists != null)
            {
                if (!_topListFull)
                {
                    _topLists.Add(sample.Clone());

                    _topMin      = _topLists.Min(list => list.TotalEarnings);
                    _topListFull = _topLists.Count >= _topCount;
                }
                else
                {
                    // Is the sample greater than the top min?
                    // Don't add it if it's already in the list.

                    if (sample.TotalEarnings > _topMin &&
                        !_topLists.Any(list => list.GetHashCode() == sample.GetHashCode()))
                    {
                        // Remove the min and add a clone of the sample.

                        _topLists.Remove(_topLists.First(list => list.TotalEarnings == _topMin));
                        _topLists.Add(sample.Clone());

                        _topMin = _topLists.Min(list => list.TotalEarnings);
                    }
                }
            }
        }
        /// <summary>
        /// The recursive call to find the best of the sample.
        /// </summary>
        /// <param name="best">The BEST earnings so far.</param>
        /// <param name="movieToAdd">The movie to be added to the list.</param>
        /// <param name="sample">Current movie list</param>
        /// <param name="movies">Sending in a smaller set each time reduces the scan on the full movie list.</param>
        /// <param name="remainingBudget"></param>
        /// <returns></returns>
        private IMovieList ChooseBest(IMovieList best, IMovie movieToAdd, IMovieList sample, IEnumerable <IMovie> movies, decimal remainingBudget)
        {
            if (sample == null)
            {
                sample = _movieListPrototype.Clone();
            }

            if (sample.CanAdd(movieToAdd))
            {
                // Add the movie to the clone that was passed in.
                sample.Add(movieToAdd);

                TotalComparisons++;

                var sampleHashCode = sample.GetHashCode();

                var beenProcessed = _processedHashes.Contains(sampleHashCode);

                // DON'T PROCESS the sample:
                //		If the sample is already full
                //		Already been processed.

                if (_topLists != null && !beenProcessed)
                {
                    AddToTopList(sample);
                }
                else if (best.TotalEarnings < sample.TotalEarnings)
                {
                    best = sample.Clone();
                }

                if (!sample.IsFull && !beenProcessed)
                {
                    remainingBudget -= movieToAdd.Cost;

                    var availableMovies = AvailableMovies(movies, remainingBudget).ToList();

                    foreach (var movie in availableMovies)
                    {
                        // Cloning is now cheaper than adding and removing.
                        best = ChooseBest(best, movie, sample.Clone(), availableMovies, remainingBudget);

                        //best = ChooseBest(best, movie, sample, availableMovies, remainingBudget);
                    }

                    // When finished processing this sub-list, store the list in the saved hashes.

                    _processedHashes.Add(sampleHashCode);
                }

                //sample.Remove(movieToAdd);
            }

            return(best);
        }
 public int GetRankedMovieListCount(IMovieList movieList)
 {
     return(_bestListCounts[movieList.GetHashCode()]);
 }