algos/irving.js
//otherwise, stop loop when everyone has one pair
otherwise, stop loop when everyone has one pair
otherwise stop loop when everyone has one pair
function removeCycle(reducedPreference) {
  let reducedPref = cloneDeep(reducedPreference);
  let impossibleMatchCondition = false;
  let cycleEntered = true;
  while (!impossibleMatchCondition && cycleEntered) {
    cycleEntered = false;
    let noSecondPrefFound;
    for (const person in reducedPref) {
      noSecondPrefFound = false;
      if (reducedPref[person].length <= 1) continue;
      cycleEntered = true;
      const p = [person];
      const q = [reducedPref[person][1]];
      while (true) {
        const currentQ = q[q.length - 1];
        const currentQPrefList = reducedPref[currentQ];
        const currentQLastPref = currentQPrefList[currentQPrefList.length - 1];
        if (reducedPref[currentQLastPref][1] === undefined) {
          impossibleMatchCondition = true;
          break;
        }
        const currentQLastPrefsSecondPref = reducedPref[currentQLastPref][1];
        if (p.includes(currentQLastPref)) {
          p.push(currentQLastPref);
          break;
        } else p.push(currentQLastPref);
        if (q.includes(currentQLastPrefsSecondPref)) break;
        else q.push(currentQLastPrefsSecondPref);
      }
      if (!impossibleMatchCondition)
        q.forEach((person, idx) => {
          const personsLastPref = p[idx + 1];
          const personPrefList = reducedPref[person];
          const lastPrefsPrefList = reducedPref[personsLastPref];
          personPrefList.splice(personPrefList.indexOf(personsLastPref), 1);
          lastPrefsPrefList.splice(lastPrefsPrefList.indexOf(person), 1);
          if (!personPrefList.length || !lastPrefsPrefList.length) impossibleMatchCondition = true;
        });
      break;
    }
  }
  return impossibleMatchCondition ? false : reducedPref;
}
function removeCycle ( reducedPreference ) { let reducedPref = cloneDeep ( reducedPreference ) ; let impossibleMatchCondition = false ; let cycleEntered = true ; while ( ! impossibleMatchCondition && cycleEntered ) { cycleEntered = false ; let noSecondPrefFound ; for ( const person in reducedPref ) { noSecondPrefFound = false ; if ( reducedPref [ person ] . length <= 1 ) continue ; cycleEntered = true ; const p = [ person ] ; const q = [ reducedPref [ person ] [ 1 ] ] ; while ( true ) { const currentQ = q [ q . length - 1 ] ; const currentQPrefList = reducedPref [ currentQ ] ; const currentQLastPref = currentQPrefList [ currentQPrefList . length - 1 ] ; if ( reducedPref [ currentQLastPref ] [ 1 ] === undefined ) { impossibleMatchCondition = true ; break ; } const currentQLastPrefsSecondPref = reducedPref [ currentQLastPref ] [ 1 ] ; if ( p . includes ( currentQLastPref ) ) { p . push ( currentQLastPref ) ; break ; } else p . push ( currentQLastPref ) ; if ( q . includes ( currentQLastPrefsSecondPref ) ) break ; else q . push ( currentQLastPrefsSecondPref ) ; } if ( ! impossibleMatchCondition ) q . forEach ( ( person , idx ) => { const personsLastPref = p [ idx + 1 ] ; const personPrefList = reducedPref [ person ] ; const lastPrefsPrefList = reducedPref [ personsLastPref ] ; personPrefList . splice ( personPrefList . indexOf ( personsLastPref ) , 1 ) ; lastPrefsPrefList . splice ( lastPrefsPrefList . indexOf ( person ) , 1 ) ; if ( ! personPrefList . length || ! lastPrefsPrefList . length ) impossibleMatchCondition = true ; } ) ; break ; } } return impossibleMatchCondition ? false : reducedPref ; }
otherwise, stop loop when everyone has one pair
otherwise stop loop when everyone has one pair
//if all pref lists have been cut down to 1 person //then cycleEntered will remain false and loop will exit //if we hit a loop, we need to start from the top of the table //e.g. if we just looked at person 1, but person 1 still has //multiple preferences, then we need to examine his list again