3v4l.org

run code in 300+ PHP versions simultaneously
<?php/** * Тестовое задание для кандидатов на должность PHP-разработчика * * Файл представляет собой шаблон для выполнения тестового задания. Все объявленные * методы должны быть реализованы непосредственно здесь. Создание дополнительных * собственных методов допускается. * * Код должен соотвестсовать стандартам кодирования Zend Framework (http://framework.zend.com/manual/ru/coding-standard.html) * и работать без генерации предупреждений при включенном режиме error_reporting=E_ALL. * * После выполнения всех задач файл должен быть переименован в следующий формат: * <Date>-<LastName>.php * * Например, 20131216-Ivanov.php * * ВНИМАНИЕ! * - На выполнение задания вы не должны тратить более двух-трех дней. * - Файл должен содержать только класс. */class PetrosoftCandidate{ const DIRECTION_TOP = 'top'; const DIRECTION_BOTTOM = 'bottom'; const DIRECTION_LEFT = 'left'; const DIRECTION_RIGHT = 'right'; /** * Задание 1 * * Во входной строке переставить слова в обратном порядке. Например строка * «one two three four» должна быть преобразована в «four three two one». * * @param string $str Входная строка * @return string Строка с переставленными словами */ public function task1($str) { return implode(' ', array_reverse(explode(' ', $str))); } /** * Задание 2 * * В неупорядоченном массиве целых положительных чисел определить положение * и длину наиболее длинной группы, представляющей собой перестановку элементов * отрезка натурального ряда чисел. * * Элементы массива * 6, 8, 5, 7, 18, 21, 20, 16, 19, 17 * * В нем перестановками являются * 6, 8, 5, 7 * и * 18, 21, 20, 16, 19, 17 * * Вторая группа является наибольшей. Индекс первого элемента второй группы равен 4, * длина группы равна 6. Метод должен вернуть * * array(4, 6) * * @param array $list Входной массив * @throws Exception * @return array Массив из двух * элементов. Первый — индекс первого элемента * самой длинной группы, второй — ее длина. */ public function task2($list) { if (!$list) { // для пустого входного массива невозможно рассчитать ответ throw new Exception("Illegal argument: list is empty"); } /* Пусть длина исходного массива N. Будем последовательно искать в нём перестановки длины N, N-1, N-2 и т.д. */ $listLength = count($list); for ($swapLength = $listLength; $swapLength > 0; $swapLength -= 1) { // ищем перестановки длины $swapLength, перебирая подмассивы for ($offset = 0; $offset <= $listLength - $swapLength; ++$offset) { $candidate = array_slice($list, $offset, $swapLength); if ($this->isSwap($candidate)) { // перестановка найдена! return array($offset, $swapLength); } } } } /** * @param $list array * @return bool является ли массив перестановкой */ private function isSwap($list) { sort($list); $previousValue = $list[0] - 1; // начальное значение этой переменной задаём сами foreach ($list as $value) { if ($value != ($previousValue + 1)) { return false; } $previousValue = $value; } return true; } /** * Задание 3 * * Элементы, расположенные на периметре прямоугольной матрицы, отсортировать по часовой * стрелке в порядке возрастания, начиная с элемента, расположенного в верхнем левом * углу матрицы. * * Например, для входной матрицы: * 1 2 3 4 * 5 6 7 8 * 9 0 1 2 * * Должен быть возвращен результат: * 0 1 1 2 * 9 6 7 2 * 8 5 4 3 * * @param array $matrix Прямоугольная матрица * @throws Exception * @return array Матрица с отсортированными по периметру элементами */ public function task3($matrix) { if (count($matrix) == 0 || count($matrix[0]) == 0) { throw new \Exception('Illegal argument: matrix is empty'); } $perimeter = array(); $cellsOnPerimeter = count($matrix[0]) * 2 + count($matrix) * 2 - 4; // количество клеток на периметре $helperMatrix = $this->createHelperMatrix($matrix); $cell = array('row' => 0, 'column' => 0); $counter = 0; do { // собираем числа с периметра $perimeter []= $matrix[$cell['row']][$cell['column']]; $cell = $this->iterateMatrixClockwise($cell, $helperMatrix); $counter += 1; } while ($counter < $cellsOnPerimeter); sort($perimeter); // сбрасываем вспомогательную матрицу перед новой итерацией $helperMatrix = $this->createHelperMatrix($matrix); $cell = array('row' => 0, 'column' => 0); $counter = 0; do { // возвращаем отсортированные числа на периметр $matrix[$cell['row']][$cell['column']] = $perimeter[$counter]; $cell = $this->iterateMatrixClockwise($cell, $helperMatrix); $counter += 1; } while ($counter < $cellsOnPerimeter); return $matrix; } /** * @param $direction string направление движения (константа класса) * @param $cell array * @param $helperMatrix array вспомогательная матрица для отслеживания уже посещённых клеток * @return mixed Если по указанному направлению можно перейти, то возвращается новая клетка, иначе false */ private function tryDirection($direction, $cell, &$helperMatrix) { switch ($direction) { case self::DIRECTION_RIGHT: $cell['column'] += 1; break; case self::DIRECTION_BOTTOM: $cell['row'] += 1; break; case self::DIRECTION_LEFT: $cell['column'] -= 1; break; case self::DIRECTION_TOP: $cell['row'] -= 1; break; } if ($this->cellCorrect($cell, $helperMatrix)) { return $cell; } else { return false; } } /** * @param $previousCell array массив с ключами row и column * @param $helperMatrix array вспомогательная матрица для отслеживания уже посещённых клеток * @return mixed массив с ключами row и column либо false, если обход завершён */ private function iterateMatrixClockwise($previousCell, &$helperMatrix) { // пробуем продвинуться в матрице по всем направлениям по очереди, начиная с приоритетного foreach (array_unique(array($helperMatrix['direction'], self::DIRECTION_RIGHT, self::DIRECTION_BOTTOM, self::DIRECTION_LEFT, self::DIRECTION_TOP)) as $direction) { if ($newCell = $this->tryDirection($direction, $previousCell, $helperMatrix)) { $this->doMoveInHelperMatrix($newCell, $direction, $helperMatrix); return $newCell; } } return false; } /** * @param $cell array массив с ключами row и column * @param $helperMatrix array вспомогательная матрица для отслеживания уже посещённых клеток * @return bool принадлежит ли указанная клетка матрице */ private function cellCorrect($cell, &$helperMatrix) { $row = $cell['row']; $column = $cell['column']; return ($row >= 0) && ($row < $helperMatrix['totalRows']) && ($column >= 0) && ($column < $helperMatrix['totalColumns']) && (!$helperMatrix[$row][$column]); } /** * @param $cell array массив с ключами row и column * @param $direction string направление движения (константа класса) * @param $helperMatrix array вспомогательная матрица для отслеживания уже посещённых клеток */ private function doMoveInHelperMatrix($cell, $direction, &$helperMatrix) { $helperMatrix[$cell['row']][$cell['column']] = true; $helperMatrix['direction'] = $direction; } /** * Создаёт вспомогательную матрицу для отслеживания уже посещённых клеток во время обхода. * false означает, что клетка не посещалась. * Также в этой матрице есть специальный ключи: * 'direction' означает текущее направление движения, 'totalRows' и 'totalColumns' - размеры исходной матрицы * @param $matrix array исходная матрица, для которой нужно создать вспомогательную * @return array вспомогательная матрица, клетка [0, 0] уже помечена как посещённая */ private function createHelperMatrix($matrix) { $totalRows = count($matrix); $totalColumns = count($matrix[0]); $helper = array(); for ($row = 0; $row < $totalRows; ++$row) { $helper []= array_fill(0, $totalColumns, false); } $helper[0][0] = true; /* вся эта группа вспомогательных методов посвящена обходу по часовой стрелке => из начального положения движение идёт направо */ $helper['direction'] = self::DIRECTION_RIGHT; $helper['totalRows'] = count($matrix); $helper['totalColumns'] = count($matrix[0]); return $helper; } /** * Задание 4 * * Сформировать одномерный массив, получающийся при чтении квадратной матрицы по спирали, начиная * с верхнего левого элемента матрицы (против часовой стрелки). * * Например, для входной матрицы: * 1 2 3 4 * 5 6 7 8 * 9 10 11 12 * 13 14 15 16 * * Должен быть возвращен результат: * 1 5 9 13 14 15 16 12 8 4 3 2 6 10 11 7 * * @param array $matrix Входная квадратная матрица * @return array Одномерный массив */ public function task4($matrix) { /* Заметим, что обход матрицы против часовой стрелки аналогичен обходу транспонированной матрицы по часовой стрелке. Поэтому транспонируем исходную матрицу и воспользуемся существующим кодом для задания 3 */ $this->transpose($matrix); $helperMatrix = $this->createHelperMatrix($matrix); $cell = array('row' => 0, 'column' => 0); $elements = array(); do { // собираем числа по спирали $elements []= $matrix[$cell['row']][$cell['column']]; } while ($cell = $this->iterateMatrixClockwise($cell, $helperMatrix)); return $elements; } /** * Транспонирует матрицу * @param $matrix array */ private function transpose(&$matrix) { $totalRows = count($matrix); $totalColumns = count($matrix[0]); for ($row = 0; $row < $totalRows; ++$row) { for ($column = $row + 1; $column < $totalColumns; ++$column) { $temp = $matrix[$row][$column]; $matrix[$row][$column] = $matrix[$column][$row]; $matrix[$column][$row] = $temp; } } }} var_dump(get_class(new PetrosoftCandidate()));

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.40.0100.00718.71
8.3.30.0110.00318.93
8.3.20.0140.00420.21
8.3.10.0040.00421.89
8.3.00.0050.00319.26
8.2.170.0070.01422.96
8.2.160.0030.01020.44
8.2.150.0040.00424.18
8.2.140.0000.00824.66
8.2.130.0000.00826.16
8.2.120.0000.00822.10
8.2.110.0030.00720.34
8.2.100.0040.00817.97
8.2.90.0080.00019.14
8.2.80.0040.00417.97
8.2.70.0040.00417.38
8.2.60.0040.00417.78
8.2.50.0050.00318.07
8.2.40.0030.00619.89
8.2.30.0080.00017.98
8.2.20.0000.00717.59
8.2.10.0000.00717.88
8.2.00.0000.00717.64
8.1.270.0000.00823.96
8.1.260.0040.00426.35
8.1.250.0070.00028.09
8.1.240.0030.00623.88
8.1.230.0040.00719.14
8.1.220.0040.00417.74
8.1.210.0000.00818.77
8.1.200.0060.00317.23
8.1.190.0080.00017.10
8.1.180.0050.00318.10
8.1.170.0030.00618.46
8.1.160.0000.00721.89
8.1.150.0040.00418.75
8.1.140.0000.00817.35
8.1.130.0030.00317.69
8.1.120.0040.00417.42
8.1.110.0000.00917.32
8.1.100.0000.00717.39
8.1.90.0000.00717.43
8.1.80.0030.00317.34
8.1.70.0000.00717.31
8.1.60.0040.00417.37
8.1.50.0040.00417.38
8.1.40.0000.00817.29
8.1.30.0040.00417.43
8.1.20.0040.00417.56
8.1.10.0000.00817.49
8.1.00.0040.00417.40
8.0.300.0080.00018.77
8.0.290.0050.00216.63
8.0.280.0070.00018.46
8.0.270.0040.00417.14
8.0.260.0030.00317.16
8.0.250.0030.00316.88
8.0.240.0000.00816.88
8.0.230.0030.00316.73
8.0.220.0030.00316.76
8.0.210.0030.00316.66
8.0.200.0000.00716.86
8.0.190.0040.00416.89
8.0.180.0030.00516.75
8.0.170.0050.00316.82
8.0.160.0060.00316.78
8.0.150.0000.00816.75
8.0.140.0070.00416.66
8.0.130.0030.00313.32
8.0.120.0070.00016.78
8.0.110.0000.00716.75
8.0.100.0050.00216.85
8.0.90.0000.00716.70
8.0.80.0070.01016.79
8.0.70.0000.00816.79
8.0.60.0070.00016.67
8.0.50.0070.00016.88
8.0.30.0130.00816.88
8.0.20.0110.00817.40
8.0.10.0080.00016.80
8.0.00.0090.00816.68
7.4.330.0000.00515.00
7.4.320.0030.00316.46
7.4.300.0020.00516.49
7.4.290.0040.00416.53
7.4.280.0000.00816.50
7.4.270.0030.00316.43
7.4.260.0030.00316.53
7.4.250.0080.00016.51
7.4.240.0050.00216.42
7.4.230.0000.00816.53
7.4.220.0110.00616.35
7.4.210.0120.00616.57
7.4.200.0030.00316.32
7.4.160.0090.00616.39
7.4.150.0150.00317.40
7.4.140.0050.01517.86
7.4.130.0050.01416.32
7.4.120.0080.00916.49
7.4.110.0110.01116.46
7.4.100.0100.00716.36
7.4.90.0120.00416.26
7.4.80.0110.00719.39
7.4.70.0060.01116.47
7.4.60.0110.00416.47
7.4.50.0060.00316.04
7.4.40.0070.01516.36
7.4.30.0060.01216.69
7.3.330.0050.00013.21
7.3.320.0000.00513.06
7.3.310.0030.00316.09
7.3.300.0040.00416.12
7.3.290.0070.01116.21
7.3.280.0110.00716.18
7.3.270.0100.00617.40
7.3.260.0070.01116.12
7.3.250.0130.00816.40
7.3.240.0080.00916.54
7.3.230.0090.01516.43
7.3.210.0000.01616.19
7.3.200.0100.01019.39
7.3.190.0110.01116.43
7.3.180.0080.00816.01
7.3.170.0060.01016.27
7.3.160.0090.00616.31
7.2.330.0080.00916.61
7.2.320.0060.01716.61
7.2.310.0070.01016.51
7.2.300.0100.01416.32
7.2.290.0040.01716.44
5.6.20.0120.00313.71
5.6.10.0040.01113.79
5.6.00.0000.01514.12
5.5.180.0040.00410.95
5.5.170.0110.00013.76
5.5.160.0070.00710.93
5.5.150.0050.00510.68
5.5.140.0000.01010.95
5.5.130.0000.01110.87
5.5.120.0070.00410.95
5.5.110.0030.00610.46
5.5.100.0040.00910.45
5.5.90.0000.00810.68
5.5.80.0050.00510.92
5.5.70.0040.00711.05
5.5.60.0030.00810.87
5.5.50.0060.00610.64
5.5.40.0030.00610.97
5.5.30.0060.00610.98
5.5.20.0050.00510.87
5.5.10.0070.00310.92
5.5.00.0030.00710.36
5.4.340.0110.00010.81
5.4.330.0070.00310.85
5.4.320.0030.00710.62
5.4.310.0030.00610.93
5.4.300.0070.00410.72
5.4.290.0000.00910.86
5.4.280.0000.00810.80
5.4.270.0040.00410.64
5.4.260.0110.00010.66
5.4.250.0100.00010.51
5.4.240.0050.00511.02
5.4.230.0000.01110.85
5.4.220.0140.00010.57
5.4.210.0090.00010.51
5.4.200.0060.00610.93
5.4.190.0030.00610.93
5.4.180.0030.00610.77
5.4.170.0090.00310.90
5.4.160.0030.00710.41
5.4.150.0040.01010.68
5.4.140.0060.00310.63
5.4.130.0030.00610.50
5.4.120.0060.00610.76
5.4.110.0060.00210.92
5.4.100.0040.00810.61
5.4.90.0000.01010.41
5.4.80.0030.00610.82
5.4.70.0050.00311.04
5.4.60.0030.00710.76
5.4.50.0070.00310.55
5.4.40.0040.00410.76
5.4.30.0000.00910.59
5.4.20.0060.00310.67
5.4.10.0030.00710.79
5.4.00.0000.01210.75

preferences:
42.72 ms | 400 KiB | 5 Q