private IEnumerable <TeamScoreModel> GetSingleScore()
        {
            var prob = new ScoreboardCellModel[Problems.Length];

            foreach (var pp in Score ?? Enumerable.Empty <ScoreCache>())
            {
                var p = Problems.FirstOrDefault(a => a.ProblemId == pp.ProblemId);
                if (p == null)
                {
                    continue;
                }
                var pid = p.Rank - 1;

                prob[pid] = new ScoreboardCellModel
                {
                    PendingCount   = pp.PendingRestricted,
                    IsFirstToSolve = pp.FirstToSolve,
                    JudgedCount    = pp.SubmissionRestricted,
                    SolveTime      = pp.IsCorrectRestricted ? (int)pp.SolveTimeRestricted / 60 : default(int?),
                };
            }

            yield return(new TeamScoreModel
            {
                TeamId = Team.TeamId,
                TeamName = Team.TeamName,
                Affiliation = Affiliation.FormalName,
                AffiliationId = Affiliation.ExternalId,
                Category = Category.Name,
                CategoryColor = Category.Color,
                Points = Rank?.PointsRestricted ?? 0,
                Penalty = Rank?.TotalTimeRestricted ?? 0,
                ShowRank = true,
                Problems = prob,
            });
        }
        private IEnumerable <TeamScoreModel> GetViewModel(
            bool ispublic,
            IEnumerable <ScoreboardOriginalModel> src,
            ScoreboardProblemStatisticsModel[] stat)
        {
            int rank         = 0;
            int last_rank    = 0;
            int last_point   = int.MinValue;
            int last_penalty = int.MinValue;
            var cats         = new Dictionary <int, TeamCategory>();

            if (ispublic)
            {
                src = src.OrderByDescending(a => a.Rank.PointsPublic)
                      .ThenBy(a => a.Rank.TotalTimePublic);
            }
            else
            {
                src = src.OrderByDescending(a => a.Rank.PointsRestricted)
                      .ThenBy(a => a.Rank.TotalTimeRestricted);
            }

            foreach (var item in src)
            {
                int    catid   = item.Team.CategoryId;
                string catName = null;
                if (!cats.Keys.Contains(catid))
                {
                    cats.Add(catid, cats2[catid]);
                    catName = cats2[catid].Name;
                }

                int point   = ispublic ? item.Rank.PointsPublic : item.Rank.PointsRestricted;
                int penalty = ispublic ? item.Rank.TotalTimePublic : item.Rank.TotalTimeRestricted;
                rank++;
                if (last_point != point || last_penalty != penalty)
                {
                    last_rank = rank;
                }
                last_point   = point;
                last_penalty = penalty;

                var prob = new ScoreboardCellModel[Problems.Length];

                foreach (var pp in item.Score ?? Enumerable.Empty <ScoreCache>())
                {
                    var p = Problems.FirstOrDefault(a => a.ProblemId == pp.ProblemId);
                    if (p == null)
                    {
                        continue;
                    }
                    var pid = p.Rank - 1;

                    if (ispublic)
                    {
                        prob[pid] = new ScoreboardCellModel
                        {
                            PendingCount   = pp.PendingPublic,
                            IsFirstToSolve = pp.FirstToSolve,
                            JudgedCount    = pp.SubmissionPublic,
                            SolveTime      = pp.IsCorrectPublic ? (int)pp.SolveTimePublic / 60 : default(int?),
                        };
                    }
                    else
                    {
                        prob[pid] = new ScoreboardCellModel
                        {
                            PendingCount   = pp.PendingRestricted,
                            IsFirstToSolve = pp.FirstToSolve,
                            JudgedCount    = pp.SubmissionRestricted,
                            SolveTime      = pp.IsCorrectRestricted ? (int)pp.SolveTimeRestricted / 60 : default(int?),
                        };
                    }

                    if (prob[pid].SolveTime.HasValue)
                    {
                        stat[pid].FirstSolve = Math.Min(stat[pid].FirstSolve ?? int.MaxValue, prob[pid].SolveTime.Value);
                        stat[pid].Accepted++;
                        stat[pid].Rejected += prob[pid].JudgedCount - 1;
                        stat[pid].Pending  += prob[pid].PendingCount;
                    }
                    else
                    {
                        stat[pid].Rejected += prob[pid].JudgedCount;
                        stat[pid].Pending  += prob[pid].PendingCount;
                    }
                }

                yield return(new TeamScoreModel
                {
                    TeamId = item.Team.TeamId,
                    TeamName = item.Team.TeamName,
                    Affiliation = item.Affil.FormalName,
                    AffiliationId = item.Affil.ExternalId,
                    Category = catName,
                    CategoryColor = cats[catid].Color,
                    Points = point,
                    Penalty = penalty,
                    Rank = last_rank,
                    ShowRank = last_rank == rank,
                    Problems = prob,
                });
            }
        }