Устранил ошибку ( round(log10($n), 0) ) и добавил комментарии на русском. Код (Text): function sum_jo5($a) { $size = count($a); //длина массива $s = 0; //здесь будет результат $ranks = array_fill(1, 9, 0); //для разрядов чисел и кол-ва повторений array_walk($a, //тут посчитаем разряды чисел и повторения function(&$n) use(&$ranks) { if ($n == 0) return; ++$ranks[(int)round(log10($n) + 0.5, 0)]; } ); $ranks = array_filter($ranks); //удалим разряды, для которых ни 1 повторения не было найдено foreach($ranks as $i=>$rank){//для каждого разряда $pow = pow(10, $i); array_walk($a, //берем само число и дописываем к нему нулей по числу разрядов function(&$n) use (&$s, $pow, $rank, $size) {$s += $n * $pow * $rank + $n * $size;} //само число войдет в сумму столько раз, ); //сколько было чисел всего } return $s; }
@johovich честно говоря результат снова не сходится. Еще заметил, что у других функций, кроме функции @artoodetoo производительность падает если массив состоит из уникальных значений. Потому что там перебираются ключи дважды, а в этом случае число ключей та же тысяча.
Да. Хорошо, что заметил. Нашел 2 ошибки. Спасибо. Вот нормальный код: Код (Text): function sum_jo5($a) { $size = count($a); //длина массива $s = 0; //здесь будет результат $ranks = array_fill(1, 9, 0); //для разрядов чисел и кол-ва повторений array_walk($a, //тут посчитаем разряды в числе и повторения function($n) use(&$ranks, &$s, $size) { $rank = $n == 0 ? 1 : (int)round(log10($n) + 0.5, 0); ++$ranks[$rank]; $s += $n * $size; //Каждое число обязательно входит в сумму такое число раз, сколько чисел в исходном наборе } ); $ranks = array_filter($ranks); //удалим разряды, для которых ни 1 повторения не было найдено foreach($ranks as $i=>$rank){//для каждого разряда $pow = pow(10, $i); array_walk($a, //берем само число и дописываем к нему нулей по числу разрядов, умножаем на число вхождений этого разряда function($n) use (&$s, $pow, $rank) {$s += $n * $pow * $rank;} ); } return $s; }
В итоге на оригинальном массиве: Код (Text): sum_vs | Time: 0.000034, Iterations: 256, Sum: 60059300 sum_fel | Time: 0.000042, Iterations: 256, Sum: 60059300 sum_arte | Time: 0.000203, Iterations: 3000, Sum: 60059300 sum_jo5 | Time: 0.000795, Iterations: 5, Sum: 60059300 на твоем массиве: Код (Text): sum_arte | Time: 0.000254, Iterations: 4000, Sum: 454594950000 sum_jo5 | Time: 0.000969, Iterations: 7, Sum: 454594950000 sum_vs | Time: 0.098036, Iterations: 1000000, Sum: 454594950000 sum_fel | Time: 0.164514, Iterations: 1000000, Sum: 454594950000 Твой метод и метод @artoodetoo дают наиболее постоянный результат по количеству итераций и скорости, два других сильно зависят от количества повторений.