<?php
class Cup
{
const MAX_CAPACITY = 2000;
private $filling;
private $capacity;
public function __construct(int $capacity)
{
if ($capacity < 0 || $capacity > self::MAX_CAPACITY) {
throw new InvalidArgumentException();
}
$this->filling = 0;
$this->capacity = $capacity;
}
public function filling()
{
return $this->filling;
}
public function fill(int $value)
{
if ($value < 0 || $value + $this->filling > $this->capacity) {
throw new InvalidArgumentException();
}
$this->filling += $value;
}
public function release(int $value)
{
if ($value < 0 || $value > $this->filling) {
throw new InvalidArgumentException();
}
$this->filling -= $value;
}
public function isEmpty()
{
return $this->filling === 0;
}
public function quantityForMaximumFilling()
{
return $this->capacity - $this->filling;
}
}
class CupService
{
public function pourFromOneCupToAnother(Cup $firstCup, Cup $secondCup)
{
if ($firstCup->isEmpty()) {
return false;
}
if ($secondCup->quantityForMaximumFilling() === 0) {
return false;
}
$fillValue = $firstCup->filling() > $secondCup->quantityForMaximumFilling() ?
$secondCup->quantityForMaximumFilling() :
$firstCup->filling();
$firstCup->release($fillValue);
$secondCup->fill($fillValue);
return true;
}
}
class CupGame
{
/**
* @var Cup[]
*/
private $cups = [];
public function play(
int $numberOfCups,
int $cupCapacity,
array $numberOfCupToResultCapacity ) {
if (count($initialFilling) !== $numberOfCups) { throw new InvalidArgumentException();
}
foreach ($numberOfCupToResultCapacity as $numberOfCupToCapacityElement) {
if ($numberOfCupToCapacityElement > $numberOfCups) {
throw new InvalidArgumentException();
}
}
$cupService = new CupService();
$this->initializationCups($cupCapacity, $initialFilling);
do {
$wasPourFromOneCupToAnother = false;
foreach ($this->cups as $numberOfCup => $cup) {
$numberOfNextCup = $numberOfCup + 1;
if (isset($this->cups[$numberOfNextCup])) { if ($cupService->pourFromOneCupToAnother($cup, $this->cups[$numberOfNextCup])) {
$wasPourFromOneCupToAnother = true;
}
}
}
} while ($wasPourFromOneCupToAnother);
$result = [];
foreach ($numberOfCupToResultCapacity as $numberOfCupToCapacityElement) {
$result[] = $this->cups[$numberOfCupToCapacityElement]->filling();
}
return $result;
}
private function initializationCups
(int
$cupCapacity, array $initialFilling) {
foreach ($initialFilling as $index => $initialFillingElement) {
$cup = new Cup($cupCapacity);
$cup->fill($initialFillingElement);
$this->cups[$index + 1] = $cup;
}
}
}
$inputData = [];
$f = fopen('php://stdin', 'r'); $iterator = 0;
while ($line = fgets($f)) {
if ($iterator < 2) {
} else {
$inputData[] = trim($line); }
$iterator++;
}
$game = new CupGame;
$result = $game->play(
$inputData[0][0],
$inputData[0][1],
$inputData[1],
);
foreach ($result as $resultElement)
{
echo $resultElement . "\r\n";
}