Пример #1
0
 /**
  * Numbering of black runs: j
  * Count of black runs in a row: k
  * Row size (amount of cells): n
  * left most starting position of run j: rjs
  * right most ending position of run j: rje
  * length of black run: LB
  *
  * @param null $rowNumber
  * @param null $colNumber
  * @return array
  */
 private function initRunRangeFor($rowNumber = null, $colNumber = null)
 {
     if (!($rowNumber == null xor $colNumber == null)) {
         throw new \RuntimeException('specify either row OR col number and not both');
     }
     $r = array();
     $labels = $colNumber != null ? $this->labels->getLabelsForColumn($colNumber) : $this->labels->getLabelsForRow($rowNumber);
     if (empty($labels)) {
         return $r;
     }
     $n = $colNumber != null ? $this->labels->getSizeY() : $this->labels->getSizeX();
     $k = count($labels);
     $r[1]['s'] = 0;
     for ($j = 2; $j <= $k; $j++) {
         $r[$j]['s'] = 0;
         for ($i = 1; $i <= $j - 1; $i++) {
             $LB = $labels[$i - 1];
             $r[$j]['s'] += $LB + 1;
         }
     }
     for ($j = 1; $j <= $k - 1; $j++) {
         $r[$j]['e'] = $n - 1;
         for ($i = $j + 1; $i <= $k; $i++) {
             $LB = $labels[$i - 1];
             $r[$j]['e'] -= $LB + 1;
         }
     }
     $r[$k]['e'] = $n - 1;
     return $r;
 }
Пример #2
0
 /**
  * @param Label $labels
  * @param array $fieldOverride option to inject a pre-defined state, only useful for unittests
  * @param RunRange\RunRange|null $runRangeOverride  option to inject a pre-defined state, only useful for unittests
  * @return array
  */
 public function solve(\Nonogram\Label\Label $labels, array $fieldOverride = array(), RunRange $runRangeOverride = null)
 {
     $timeStart = microtime(true);
     $this->init($labels, $fieldOverride, $runRangeOverride);
     if ($labels->hasHiddenCounts()) {
         return $this->field;
     }
     $iterations = 0;
     do {
         $updateCounter = 0;
         //iterate over all rows
         foreach ($this->field as $rowNum => &$row) {
             if (!empty($this->finishedRows) && in_array($rowNum, $this->finishedRows)) {
                 continue;
             }
             $blackRuns = $this->labels->getLabelsForRow($rowNum + 1);
             $r =& $this->runRanges->getRangesForRow($rowNum + 1);
             foreach ($this->rules as $rule) {
                 if ($rule::RESULT_LINE_SOLVED === $rule->apply($row, $blackRuns, $r)) {
                     $this->finishedRows[] = $rowNum;
                 }
                 $updateCounter += $this->processUpdateCounter($rule);
             }
         }
         if (count($this->field) === 1) {
             return $this->field;
         }
         //iterate over all columns
         for ($colNum = 0; $colNum < $this->labels->getSizeX(); $colNum++) {
             if (!empty($this->finishedCols) && in_array($colNum, $this->finishedCols)) {
                 continue;
             }
             //compose a new sequence of the column
             $sequence = array();
             for ($rowNum = 0; $rowNum < $this->labels->getSizeY(); $rowNum++) {
                 $sequence[$rowNum] =& $this->field[$rowNum][$colNum];
             }
             $blackRuns = $this->labels->getLabelsForColumn($colNum + 1);
             $r =& $this->runRanges->getRangesForColumn($colNum + 1);
             foreach ($this->rules as $rule) {
                 if ($rule::RESULT_LINE_SOLVED === $rule->apply($sequence, $blackRuns, $r)) {
                     $this->finishedCols[] = $colNum;
                 }
                 $updateCounter += $this->processUpdateCounter($rule);
             }
         }
         $iterations++;
     } while ($updateCounter > 0);
     $this->lastSolvingTime = microtime(true) - $timeStart;
     $this->solvingStatistics['Iterations'] = $iterations;
     $this->solvingStatistics['Solving time'] = $this->lastSolvingTime;
     return $this->field;
 }
Пример #3
0
 /**
  * Returns the number of columns (horizontal size)
  *
  * required for drawing the field
  */
 public function getSizeX()
 {
     return $this->labels->getSizeX();
 }