public ActionResult Full(int id, bool official)
        {
            var contest = this.Data.Contests.GetById(id);

            if (contest == null)
            {
                throw new HttpException((int)HttpStatusCode.NotFound, Resource.Contest_not_found);
            }

            var model = new ContestFullResultsViewModel
                {
                    Id = contest.Id,
                    Name = contest.Name,
                    Problems = contest.Problems.AsQueryable().Where(pr => !pr.IsDeleted).Select(ContestProblemViewModel.FromProblem).OrderBy(x => x.Name),
                    Results = this.Data.Participants.All()
                        .Where(participant => participant.ContestId == contest.Id && participant.IsOfficial == official)
                        .Select(participant => new ParticipantFullResultViewModel
                        {
                            ParticipantName = participant.User.UserName,
                            ProblemResults = participant.Contest.Problems
                                .Where(x => !x.IsDeleted)
                                .Select(problem =>
                                    new ProblemFullResultViewModel
                                    {
                                        Id = problem.Id,
                                        ProblemName = problem.Name,
                                        MaximumPoints = problem.MaximumPoints,
                                        BestSubmission = problem.Submissions.AsQueryable()
                                                            .Where(submission => submission.ParticipantId == participant.Id && !submission.IsDeleted)
                                                            .OrderByDescending(z => z.Points).ThenByDescending(z => z.Id)
                                                            .Select(SubmissionFullResultsViewModel.FromSubmission)
                                                            .FirstOrDefault(),
                                    })
                                    .OrderBy(res => res.ProblemName)
                        })
                        .ToList()
                        .OrderByDescending(x => x.Total).ThenBy(x => x.ParticipantName)
                };

            this.ViewBag.IsOfficial = official;

            return this.View(model);
        }
        public ActionResult Stats(ContestFullResultsViewModel viewModel)
        {
            var maxResult = this.Data.Contests.All().FirstOrDefault(c => c.Id == viewModel.Id).Problems.Sum(p => p.MaximumPoints);
            var participantsCount = viewModel.Results.Count();
            var statsModel = new ContestStatsViewModel();
            statsModel.MinResultsCount = viewModel.Results.Count(r => r.Total == 0);
            statsModel.MinResultsPercent = (double)statsModel.MinResultsCount / participantsCount;
            statsModel.MaxResultsCount = viewModel.Results.Count(r => r.Total == maxResult);
            statsModel.MaxResultsPercent = (double)statsModel.MaxResultsCount / participantsCount;
            statsModel.AverageResult = (double)viewModel.Results.Sum(r => r.Total) / participantsCount;

            int fromPoints = 0;
            int toPoints = 0;
            foreach (var problem in viewModel.Problems)
            {
                var maxResultsForProblem = viewModel.Results.Count(r => r.ProblemResults.Any(pr => pr.ProblemName == problem.Name && pr.BestSubmission != null && pr.BestSubmission.Points == pr.MaximumPoints));
                var maxResultsForProblemPercent = (double)maxResultsForProblem / participantsCount;
                statsModel.StatsByProblem.Add(new ContestProblemStatsViewModel
                    {
                        Name = problem.Name,
                        MaxResultsCount = maxResultsForProblem,
                        MaxResultsPercent = maxResultsForProblemPercent,
                        MaxPossiblePoints = problem.MaximumPoints
                    });

                if (toPoints == 0)
                {
                    toPoints = problem.MaximumPoints;
                }
                else
                {
                    toPoints += problem.MaximumPoints;
                }

                var participantsInPointsRange = viewModel.Results.Count(r => r.Total >= fromPoints && r.Total <= toPoints);
                var participantsInPointsRangePercent = (double)participantsInPointsRange / participantsCount;

                statsModel.StatsByPointsRange.Add(new ContestPointsRangeViewModel
                    {
                        PointsFrom = fromPoints,
                        PointsTo = toPoints,
                        Participants = participantsInPointsRange,
                        PercentOfAllParticipants = participantsInPointsRangePercent
                    });

                fromPoints = toPoints + 1;
            }

            return this.PartialView("_StatsPartial", statsModel);
        }