function splitToPatterns($array) { $length = count($array); if ($length < 1) { return $array; } $pos = 0; $repeats = 1; $last_window = 1; // Scan from the start of the array, from the bigger window to smaller for ($win = floor($length / 2); $win > 0; $win--) { while (array_slice($array, $pos, $win) == array_slice($array, $pos + $win, $win)) { $last_window = $win; $pos += $win; $repeats++; } if ($repeats > 1) { break; } } // scan the rest of the array $next = splitToPatterns(array_slice($array, $pos + $last_window)); //return array_merge(Array(Array('number'=>$repeats, 'values'=>array_slice($array, $pos, $last_window))), $next); // this is for the case when larger pattern doesn't start from the beginning, like // 'one', 'two', 'one', 'two', 'three', 'four', 'one', 'two', 'three', 'four' // [ ] [ ] [ ] [ ] // so we shift by 1 element and check the rest $shift = splitToPatterns(array_slice($array, 1)); // Now check where we have less items (= more repeats) if (count($next) < count($shift) + 1) { return array_merge(array(array('number' => $repeats, 'values' => array_slice($array, $pos, $last_window))), $next); } return array_merge(array(array('number' => 1, 'values' => array_slice($array, 0, 1))), $shift); }
function splitToPatterns($array) { if (count($array) < 1) { return $array; } list($repeats, $start, $pattern) = findLongestPattern($array); $end = $start + count($pattern) * $repeats; return array_merge(splitToPatterns(array_slice($array, 0, $start)), array(array('number' => $repeats, 'values' => $pattern)), splitToPatterns(array_slice($array, $end))); }