Extend array with additional requirements

你。 提交于 2020-08-10 05:24:39

问题


I am new to PHP, but I do my best. Please be patient with me. :)

Yesterday I already asked a similar question, but today I have to extend it.

Initial Situation

In my school the graduates have to pick a topic for a thesis in the final year. Each student chooses a tutor from one subject area to help them.

Starting position

  • Each student must specify exactly three wishes, which are sorted in descending order of preference. Example: Stacy chooses Mr. Jobs in Design as her first wish, Carl also chooses Mr. Jobs as his first wish, but in usability. William selects Mr. Gates in Computer Science as his first choice, Charlott selects Mr. Gates in Biology as his first choice.
  • Each tutor may supervise a maximum of three students.
  • Each teacher can be selected in up to two subjects. So Mr Jobs could be chosen in design and usability, Mr Gates in computer science and biology, Mr Musk in physics and geography.

Example of possible elections:

Mr. Jobs -> Stacy (Design), Carl (Usability), Melody (Design)
Mr. Gates -> William (Computer Science), Eric (Biology), Charlott (Biology)
Mr. Musk -> Anthony (Physics), Sarah (Physics), Nelly (Geography)

Final Questions

  • How can I make sure that as many students as possible get their first wish? Of the remaining students, as many as possible should get the second wish, the rest the third wish. (done? do you have tipps?)
  • How can I extend the following script so that the different subjects of my colleagues are taken into account, but no one supervises more than 3 students?
  • How can I tell the script to also output whether the assignment is the first wish, second wish or third wish?

User Rustyjim helped me yesterday with the following script. Thanks again!

Best wishes, stay healthy!

Script so far

function shuffle_assoc($list) {
    if (!is_array($list)) return $list;
    $keys = array_keys($list);
    shuffle($keys);
    $random = array();
    foreach ($keys as $key) {
        $random[$key] = $list[$key];
    }
    return $random;
}
$preferencesOfStudents = [
    'students' => [
        'Stacy' => ['Mr Jobs','Mr Gates','Mr Musk'],
        'Carl' => ['Mr Jobs','Mr Gates','Mr Musk'],
        'Melody' => ['Mr Jobs','Mr Musk','Mr Gates'],
        'William' => ['Mr Musk','Mr Gates','Mr Jobs'],
        'Eric' => ['Mr Gates','Mr Jobs','Mr Musk'],
        'Charlott' => ['Mr Jobs','Mr Gates','Mr Musk'],
        'Anthony' => ['Mr Gates','Mr Musk','Mr Jobs'],
        'Sarah' => ['Mr Gates','Mr Jobs','Mr Musk'],
        'Nelly' => ['Mr Gates','Mr Musk','Mr Jobs']
    ]
];
// 1 = Jobs, 2 = Gates, 3 = Musk
$teachers = [
    'Mr Jobs' => [],
    'Mr Gates' => [],
    'Mr Musk' => []
];
$randomStudentsArray = shuffle_assoc($preferencesOfStudents['students']);
//print_r($randomStudentsArray);
foreach($randomStudentsArray as $name => $student){
    if(count($teachers[$student[0]]) < 3){
        $teachers[$student[0]][] = $name;
    } elseif(count($teachers[$student[1]]) < 3) {
        $teachers[$student[1]][] = $name;
    } else {
        $teachers[$student[2]][] = $name;
    }
}
print_r($teachers);

回答1:


EDIT: This works? Hope to help!

If there is a maximum of 2 specializations there is a problem though: not all students can be assigned sometimes.

But is tries as well as it can, and random, so if it does not give a nice output, just try again.

   <?php
function shuffle_assoc($list) {
    if (!is_array($list)) return $list;
    $keys = array_keys($list);
    shuffle($keys);
    $random = array();
    foreach ($keys as $key) {
        $random[$key] = $list[$key];
    }
    return $random;
}
function searchForId($id, $array) {
    foreach ($array as $key => $val) {
        if ($val['specializations'] === $id) {
            return $key;
        }
    }
    return null;
 }
$preferencesOfStudents = [
    'students' => [
        'Stacy' => ['Mr Jobs','Mr Gates','Mr Musk', 'Biology'],
        'Carl' => ['Mr Jobs','Mr Gates','Mr Musk', 'Design'],
        'Melody' => ['Mr Bezos','Mr Musk','Mr Gates', 'Usability'],
        'William' => ['Mr Musk','Mr Gates','Mr Jobs', 'Computer Science'],
        'Eric' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics'],
        'Charlott' => ['Mr Jobs','Mr Gates','Mr Musk', 'Geography'],
        'Anthony' => ['Mr Gates','Mr Musk','Mr Jobs', 'Geography'],
        'Sarah' => ['Mr Gates','Mr Jobs','Mr Musk', 'Design'],
        'Nelly' => ['Mr Gates','Mr Musk','Mr Jobs', 'Usability'],
        'Connor' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics'],
        'Frodo' => ['Mr Gates','Mr Musk','Mr Jobs', 'Computer Science'],
        'Achmed' => ['Mr Gates','Mr Jobs','Mr Musk', 'Computer Science']
    ]
];

$teachers = [
    'Mr Jobs' => [
        'students' => [],
        'specializations' => []
    ],
    'Mr Gates' => [
        'students' => [],
        'specializations' => []
    ],
    'Mr Musk' => [
        'students' => [],
        'specializations' => []
    ],
    'Mr Bezos' => [
        'students' => [],
        'specializations' => []
    ]
];
$unassigned = [];
$randomStudentsArray = shuffle_assoc($preferencesOfStudents['students']);
/*assign students to prefered spots randomly*/
foreach($randomStudentsArray as $name => $student){
    foreach ($teachers as $teacherName => $array) {
        if (in_array($student[3],$array['specializations'])) {
            $teachers[$teacherName]['students'][] = $name." (because of specialization) (".$student[3].")";
            $teachers[$teacherName]['specializations'][] = $student[3];
            break;
        }
    }
    if(count($teachers[$student[0]]['students']) < 5 && count($teachers[$student[0]]['specializations']) < 2){   
        $teachers[$student[0]]['students'][] = $name." (first choice) (".$student[3].")";
        $teachers[$student[0]]['specializations'][] = $student[3]; 
    } elseif(count($teachers[$student[1]]['students']) < 5 && count($teachers[$student[1]]['specializations']) < 2) {
        $teachers[$student[1]]['students'][] = $name." (second choice) (".$student[3].")";
        $teachers[$student[1]]['specializations'][] = $student[3];
    } elseif(count($teachers[$student[2]]['students']) < 5 && count($teachers[$student[2]]['specializations']) < 2)  {
        $teachers[$student[2]]['students'][] = $name." (third choice) (".$student[3].")";
        $teachers[$student[2]]['specializations'][] = $student[3];
    } else {
        $unassigned[$name] = $student;
    }
}
/*assign unassigned student to free spots*/
foreach($unassigned as $name => $student){
    foreach($teachers as $teacherName => $listOfStudents){
        if(count($listOfStudents['students']) < 5 && count($listOfStudents['specializations']) < 2){
            $teachers[$teacherName]['students'][] = $name." (none of prefered choices) (".$student[3].")";
            $teachers[$teacherName]['specializations'][] = $student[3];
        }
    }
}
print_r($teachers);

EDIT2:

<?php
function shuffle_assoc($list) {
    if (!is_array($list)) return $list;
    $keys = array_keys($list);
    shuffle($keys);
    $random = array();
    foreach ($keys as $key) {
        $random[$key] = $list[$key];
    }
    return $random;
}
function searchForId($id, $array) {
    foreach ($array as $key => $val) {
        if ($val['specializations'] === $id) {
            return $key;
        }
    }
    return null;
 }
$preferencesOfStudents = [
    'students' => [
        'Stacy' => ['Mr Jobs','Mr Gates','Mr Musk', 'Biology'],
        'Carl' => ['Mr Jobs','Mr Gates','Mr Musk', 'Design'],
        'Melody' => ['Mr Bezos','Mr Musk','Mr Gates', 'Usability'],
        'William' => ['Mr Musk','Mr Gates','Mr Jobs', 'Computer Science'],
        'Eric' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics'],
        'Charlott' => ['Mr Jobs','Mr Gates','Mr Musk', 'Geography'],
        'Anthony' => ['Mr Gates','Mr Musk','Mr Jobs', 'Geography'],
        'Sarah' => ['Mr Gates','Mr Jobs','Mr Musk', 'Design'],
        'Nelly' => ['Mr Gates','Mr Musk','Mr Jobs', 'Usability'],
        'Connor' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics'],
        'Frodo' => ['Mr Gates','Mr Musk','Mr Jobs', 'Computer Science'],
        'Achmed' => ['Mr Gates','Mr Jobs','Mr Musk', 'Computer Science']
    ]
];

$teachers = [
    'Mr Jobs' => [
        'students' => [],
        'specializations' => ['Biology', 'Design']
    ],
    'Mr Gates' => [
        'students' => [],
        'specializations' => ['Computer Science', 'Usability']
    ],
    'Mr Musk' => [
        'students' => [],
        'specializations' => ['Physics', 'Geography']
    ],
    'Mr Bezos' => [
        'students' => [],
        'specializations' => ['Usability', 'Biology']
    ]
];
$unassigned = [];
$randomStudentsArray = shuffle_assoc($preferencesOfStudents['students']);
/*assign students to prefered spots randomly*/
foreach($randomStudentsArray as $name => $student){
    if(count($teachers[$student[0]]['students']) < 5 && in_array($student[3],$teachers[$student[0]]['specializations'])){   
        $teachers[$student[0]]['students'][] = $name." (first choice) (".$student[3].")";
    } elseif(count($teachers[$student[1]]['students']) < 5 && in_array($student[3],$teachers[$student[1]]['specializations'])) {
        $teachers[$student[1]]['students'][] = $name." (second choice) (".$student[3].")";
    } elseif(count($teachers[$student[2]]['students']) < 5 && in_array($student[3],$teachers[$student[2]]['specializations']))  {
        $teachers[$student[2]]['students'][] = $name." (third choice) (".$student[3].")";
    } else {
        $unassigned[$name] = $student;
    }
}
/*assign unassigned student to free spots*/
foreach($unassigned as $name => $student){
    foreach($teachers as $teacherName => $listOfStudents){
        if(count($listOfStudents['students']) < 5 && count($listOfStudents['specializations']) < 2 && in_array($student[3],$teachers[$teacherName]['specializations'])){
            $teachers[$teacherName]['students'][] = $name." (none of prefered choices) (".$student[3].")";
        }
    }
}
print_r($teachers);

EDIT3:

<?php
function shuffle_assoc($list) {
    if (!is_array($list)) return $list;
    $keys = array_keys($list);
    shuffle($keys);
    $random = array();
    foreach ($keys as $key) {
        $random[$key] = $list[$key];
    }
    return $random;
}
function searchForId($id, $array) {
    foreach ($array as $key => $val) {
        if ($val['specializations'] === $id) {
            return $key;
        }
    }
    return null;
 }
$preferencesOfStudents = [
    'students' => [
        'Stacy' => ['Mr Jobs','Mr Gates','Mr Musk', 'Biology', 'Usability'],
        'Carl' => ['Mr Jobs','Mr Gates','Mr Musk', 'Design', 'Physics'],
        'Melody' => ['Mr Bezos','Mr Musk','Mr Gates', 'Usability', 'Physics'],
        'William' => ['Mr Musk','Mr Gates','Mr Jobs', 'Computer Science', 'Usability'],
        'Eric' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics', 'Design'],
        'Charlott' => ['Mr Bezos','Mr Gates','Mr Musk', 'Geography', 'Design'],
        'Anthony' => ['Mr Gates','Mr Musk','Mr Jobs', 'Geography', 'Computer Science'],
        'Sarah' => ['Mr Bezos','Mr Jobs','Mr Musk', 'Design', 'Physics'],
        'Nelly' => ['Mr Gates','Mr Musk','Mr Jobs', 'Usability', 'Design'],
        'Connor' => ['Mr Gates','Mr Bezos','Mr Musk', 'Physics', 'Usability'],
        'Frodo' => ['Mr Gates','Mr Musk','Mr Jobs', 'Computer Science', 'Geography'],
        'Achmed' => ['Mr Gates','Mr Jobs','Mr Musk', 'Computer Science', 'Geography'],
        'Charlie' => ['Mr Bezos','Mr Musk','Mr Gates', 'Usability', 'Physics'],
        'India' => ['Mr Musk','Mr Gates','Mr Jobs', 'Computer Science', 'Usability'],
        'Lima' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics', 'Design'],
        'Mike' => ['Mr Jobs','Mr Gates','Mr Musk', 'Geography', 'Design'],
        'Oscar' => ['Mr Gates','Mr Musk','Mr Jobs', 'Usability', 'Computer Science'],
        'Quentin' => ['Mr Gates','Mr Jobs','Mr Musk', 'Design', 'Physics'],
        'Sam' => ['Mr Gates','Mr Musk','Mr Jobs', 'Usability', 'Design'],
        'Victor' => ['Mr Gates','Mr Jobs','Mr Musk', 'Physics', 'Usability'],
        'Zach' => ['Mr Gates','Mr Musk','Mr Jobs', 'Computer Science', 'Geography'],
        'Arya' => ['Mr Gates','Mr Jobs','Mr Musk', 'Computer Science', 'Geography']
    ]
];

$teachers = [
    'Mr Jobs' => [
        'students' => [],
        'specializations' => ['Biology', 'Design']
    ],
    'Mr Gates' => [
        'students' => [],
        'specializations' => ['Computer Science', 'Usability']
    ],
    'Mr Musk' => [
        'students' => [],
        'specializations' => ['Physics', 'Geography']
    ],
    'Mr Bezos' => [
        'students' => [],
        'specializations' => ['Usability', 'Biology']
    ]
];
$unassigned = [];
$randomStudentsArray = shuffle_assoc($preferencesOfStudents['students']);
/*assign students to prefered spots randomly*/
foreach($randomStudentsArray as $name => $student){
    if(count($teachers[$student[0]]['students']) < 5 && (in_array($student[3],$teachers[$student[0]]['specializations']) || in_array($student[3],$teachers[$student[0]]['specializations']))){   
        $teachers[$student[0]]['students'][] = $name." (first choice) (".$student[3].")";
    } elseif(count($teachers[$student[1]]['students']) < 5 && (in_array($student[3],$teachers[$student[1]]['specializations']) || in_array($student[3],$teachers[$student[0]]['specializations']))) {
        $teachers[$student[1]]['students'][] = $name." (second choice) (".$student[3].")";
    } elseif(count($teachers[$student[2]]['students']) < 5 && (in_array($student[3],$teachers[$student[2]]['specializations']) || in_array($student[3],$teachers[$student[0]]['specializations'])))  {
        $teachers[$student[2]]['students'][] = $name." (third choice) (".$student[3].")";
    } else {
        $unassigned[$name] = $student;
    }
}
/*assign unassigned student to free spots*/
foreach($unassigned as $name => $student){
    foreach($teachers as $teacherName => $listOfStudents){
        if(count($listOfStudents['students']) < 5 && count($listOfStudents['specializations']) < 2 && ( in_array($student[3],$teachers[$teacherName]['specializations']) || in_array($student[4],$teachers[$teacherName]['specializations']) )){
            $teachers[$teacherName]['students'][] = $name." (none of prefered choices) (".$student[3].")";
        }
    }
}
print_r($teachers);


来源:https://stackoverflow.com/questions/63225518/extend-array-with-additional-requirements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!