<commit_before><?php

namespace PivotLibre\Tideman;

use \InvalidArgumentException;
use \Exception;

use PivotLibre\Tideman\Agenda;
use PivotLibre\Tideman\Candidate;
use PivotLibre\Tideman\MarginList;
use PivotLibre\Tideman\CandidateSet;
use PivotLibre\Tideman\CandidateList;
use PivotLibre\Tideman\RankedPairsGraph;
use PivotLibre\Tideman\ListOfMarginLists;
use PivotLibre\Tideman\CandidateComparator;
use PivotLibre\Tideman\TieBreakingMarginComparator;

class RankedPairsCalculator
{
    private $tieBreakingMarginComparator;
    private $tieBreakingCandidateComparator;

    /**
     * Constructs a Ranked Pairs Calculator, verifying that the specified tie-breaking ballot contains no ties.
     * Retains a copy of the tie-breaking Ballot so that the caller may modify the parameterized Ballot without
     * affecting this class.
     * @param tieBreakingBallot
     */
    public function __construct(Ballot $tieBreakingBallot)
    {
        if ($tieBreakingBallot->containsTies()) {
            throw new InvalidArgumentException("Tie breaking ballot must not contain any ties. $tieBreakingBallot");
        } else {
            $myTieBreakingBallot = clone $tieBreakingBallot;
            $tieBreaker = new TotallyOrderedBallotMarginTieBreaker(new CandidateComparator($myTieBreakingBallot));
            $this->tieBreakingMarginComparator = new TieBreakingMarginComparator($tieBreaker);
            $this->tieBreakingCandidateComparator = new CandidateComparator($myTieBreakingBallot);
        }
    }

    /**
     * @param int number of winners to return.
     * @param NBallot the ballots from the electorate.
     * @return CandidateList in which the zeroth Candidate is the most preferred, the first Candidate is the second most
     * preferred, and so on until the last Candidate who is the least preferred. Ties are broken according to the Ballot
     * provided to the constructor.
     */
    public function calculate(int $numWinners, NBallot ...$nBallots) : CandidateList
    {
        $agenda = new Agenda(...$nBallots);
        $candidatesInOrder = [];
        while (sizeof($candidatesInOrder) < $numWinners) {
            $winnersOfTheRound = $this->getOneRoundOfWinners($agenda, ...$nBallots)->toArray();
            array_push($candidatesInOrder, ...$winnersOfTheRound);
            $agenda->removeCandidates(...$winnersOfTheRound);
        }
        $winners = new CandidateList(...$candidatesInOrder);
        return $winners;
    }<commit_msg>Tweak<commit_after><?php

namespace PivotLibre\Tideman;

use \InvalidArgumentException;
use \Exception;

use PivotLibre\Tideman\Agenda;
use PivotLibre\Tideman\Candidate;
use PivotLibre\Tideman\MarginList;
use PivotLibre\Tideman\CandidateSet;
use PivotLibre\Tideman\CandidateList;
use PivotLibre\Tideman\RankedPairsGraph;
use PivotLibre\Tideman\ListOfMarginLists;
use PivotLibre\Tideman\CandidateComparator;
use PivotLibre\Tideman\TieBreakingMarginComparator;

class RankedPairsCalculator
{
    private $tieBreakingMarginComparator;
    private $tieBreakingCandidateComparator;

    /**
     * Constructs a Ranked Pairs Calculator, verifying that the specified tie-breaking ballot contains no ties.
     * Retains a copy of the tie-breaking Ballot so that the caller may modify the parameterized Ballot without
     * affecting this class.
     * @param tieBreakingBallot
     */
    public function __construct(Ballot $tieBreakingBallot)
    {
        if ($tieBreakingBallot->containsTies()) {
            throw new InvalidArgumentException("Tie breaking ballot must not contain any ties. $tieBreakingBallot");
        } else {
            $myTieBreakingBallot = clone $tieBreakingBallot;
            $tieBreaker = new TotallyOrderedBallotMarginTieBreaker(new CandidateComparator($myTieBreakingBallot));
            $this->tieBreakingMarginComparator = new TieBreakingMarginComparator($tieBreaker);
            $this->tieBreakingCandidateComparator = new CandidateComparator($myTieBreakingBallot);
        }
    }

    /**
     * @param int number of winners to return.
     * @param NBallot the ballots from the electorate.
     * @return CandidateList in which the zeroth Candidate is the most preferred, the first Candidate is the second most
     * preferred, and so on until the last Candidate who is the least preferred. Ties are broken according to the Ballot
     * provided to the constructor.
     */
    public function calculate(int $numWinners, NBallot ...$nBallots) : CandidateList
    {
        $agenda = new Agenda(...$nBallots);
        $candidatesInOrder = [];
        while (sizeof($candidatesInOrder) < $numWinners) {
            $winnersOfTheRound = $this->getOneRoundOfWinners($agenda, ...$nBallots);
            array_push($candidatesInOrder, ...$winnersOfTheRound);
            $agenda->removeCandidates(...$winnersOfTheRound);
        }
        $winners = new CandidateList(...$candidatesInOrder);
        return $winners;
    }
{'fraction_non_alphanumeric': 0.08446700507614213, 'fraction_numerical': 0.0, 'mean_word_length': 3.561111111111111, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '98248', 'n_tokens_mistral': 1497, 'n_tokens_neox': 1459, 'n_words': 358}