| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <?php
- namespace App\Services;
- class DifficultyDistributionService
- {
- public function calculateDistribution(int $category, int $totalQuestions): array
- {
- switch ($category) {
- case 0:
- $mediumPercentage = 90; // 0-0.1
- $lowPercentage = 0;
- $highPercentage = 10; // 0.1-0.25
- break;
- case 1:
- $mediumPercentage = 90; // 0-0.25
- $lowPercentage = 0;
- $highPercentage = 10;
- break;
- case 2:
- $mediumPercentage = 50; // 0.25-0.5
- $lowPercentage = 25; // <0.25
- $highPercentage = 25; // >0.5
- break;
- case 3:
- $mediumPercentage = 50; // 0.5-0.75
- $lowPercentage = 25; // <0.5
- $highPercentage = 25; // >0.75
- break;
- case 4:
- $mediumPercentage = 50; // 0.75-1
- $lowPercentage = 25; // <0.75
- $highPercentage = 25; // >0.75
- break;
- default:
- $lowPercentage = 25;
- $mediumPercentage = 50;
- $highPercentage = 25;
- }
- $lowCount = (int) round($totalQuestions * $lowPercentage / 100);
- $mediumCount = (int) round($totalQuestions * $mediumPercentage / 100);
- $highCount = $totalQuestions - $lowCount - $mediumCount;
- return [
- 'low' => [
- 'percentage' => $lowPercentage,
- 'count' => $lowCount,
- 'label' => '低级难度'
- ],
- 'medium' => [
- 'percentage' => $mediumPercentage,
- 'count' => $mediumCount,
- 'label' => '基准难度'
- ],
- 'high' => [
- 'percentage' => $highPercentage,
- 'count' => $highCount,
- 'label' => '拔高难度'
- ]
- ];
- }
- public function getRanges(int $category): array
- {
- switch ($category) {
- case 0:
- return [
- 'primary' => ['min' => 0.0, 'max' => 0.1, 'percentage' => 90],
- 'secondary' => ['min' => 0.1, 'max' => 0.25, 'percentage' => 10],
- 'description' => '0基础型:0-0.1占比90%,0.1-0.25占比10%'
- ];
- case 1:
- return [
- 'primary' => ['min' => 0.0, 'max' => 0.25, 'percentage' => 90],
- 'secondary' => ['min' => 0.25, 'max' => 1.0, 'percentage' => 10],
- 'description' => '基础型:0-0.25占比90%,0.25-1占比10%'
- ];
- case 2:
- return [
- 'primary' => ['min' => 0.25, 'max' => 0.5, 'percentage' => 50],
- 'low' => ['min' => 0.0, 'max' => 0.25, 'percentage' => 25],
- 'high' => ['min' => 0.5, 'max' => 1.0, 'percentage' => 25],
- 'description' => '进阶型:0.25-0.5占比50%,<0.25占比25%,>0.5占比25%'
- ];
- case 3:
- return [
- 'primary' => ['min' => 0.5, 'max' => 0.75, 'percentage' => 50],
- 'low' => ['min' => 0.0, 'max' => 0.5, 'percentage' => 25],
- 'high' => ['min' => 0.75, 'max' => 1.0, 'percentage' => 25],
- 'description' => '中等型:0.5-0.75占比50%,<0.5占比25%,>0.75占比25%'
- ];
- case 4:
- return [
- 'primary' => ['min' => 0.75, 'max' => 1.0, 'percentage' => 50],
- 'secondary' => ['min' => 0.0, 'max' => 0.75, 'percentage' => 50],
- 'description' => '拔高型:0.75-1占比50%,其他占比50%'
- ];
- default:
- return [
- 'primary' => ['min' => 0.0, 'max' => 1.0, 'percentage' => 100],
- 'description' => '默认:全难度范围'
- ];
- }
- }
- public function groupQuestionsByDifficultyRange(array $questions, int $category): array
- {
- $buckets = [
- 'primary_low' => [],
- 'primary_medium' => [],
- 'primary_high' => [],
- 'secondary' => [],
- 'other' => []
- ];
- foreach ($questions as $question) {
- $difficulty = (float) ($question['difficulty'] ?? 0);
- $rangeKey = $this->classifyQuestionByDifficulty($difficulty, $category);
- $buckets[$rangeKey][] = $question;
- }
- return $buckets;
- }
- public function classifyQuestionByDifficulty(float $difficulty, int $category): string
- {
- switch ($category) {
- case 0:
- if ($difficulty >= 0 && $difficulty <= 0.1) {
- return 'primary_medium';
- }
- if ($difficulty > 0.1 && $difficulty <= 0.25) {
- return 'secondary';
- }
- return 'other';
- case 1:
- if ($difficulty >= 0 && $difficulty <= 0.25) {
- return 'primary_medium';
- }
- return 'secondary';
- case 2:
- if ($difficulty >= 0.25 && $difficulty <= 0.5) {
- return 'primary_medium';
- }
- if ($difficulty < 0.25) {
- return 'primary_low';
- }
- return 'primary_high';
- case 3:
- if ($difficulty >= 0.5 && $difficulty <= 0.75) {
- return 'primary_medium';
- }
- if ($difficulty < 0.5) {
- return 'primary_low';
- }
- return 'primary_high';
- case 4:
- if ($difficulty >= 0.75 && $difficulty <= 1.0) {
- return 'primary_medium';
- }
- return 'secondary';
- default:
- return 'other';
- }
- }
- public function mapDifficultyLevelToRangeKey(string $level, int $category): string
- {
- switch ($category) {
- case 0:
- return match($level) {
- 'low' => 'secondary',
- 'medium' => 'primary_medium',
- 'high' => 'secondary',
- default => 'secondary'
- };
- case 1:
- return match($level) {
- 'low' => 'secondary',
- 'medium' => 'primary_medium',
- 'high' => 'secondary',
- default => 'secondary'
- };
- case 2:
- return match($level) {
- 'low' => 'primary_low',
- 'medium' => 'primary_medium',
- 'high' => 'primary_high',
- default => 'other'
- };
- case 3:
- return match($level) {
- 'low' => 'primary_low',
- 'medium' => 'primary_medium',
- 'high' => 'primary_high',
- default => 'other'
- };
- case 4:
- return match($level) {
- 'low' => 'secondary',
- 'medium' => 'primary_medium',
- 'high' => 'secondary',
- default => 'secondary'
- };
- default:
- return 'other';
- }
- }
- public function getSupplementOrder(int $category): array
- {
- return match ($category) {
- 0, 1, 4 => ['secondary', 'other'],
- 2, 3 => ['primary_medium', 'primary_low', 'primary_high', 'other'],
- default => ['other']
- };
- }
- }
|