Есть такая тема на русском стековерфлоу: http://ru.stackoverflow.com/q/517070/176610 , её закрыли по причине несоответствия профилю сайта, но модераторы обсуждают расширение правил чтобы допускать подобные "code golf", только с оговорками как они должны оформляться. Мне кажется задачка любопытная. Давайте попробуем порешать на PHP, JS, SQL или чём угодно. Цитирую как есть: Для данного списка различных чисел от 1 до N нужно построить сокращённый вариант списка: если подряд идут несколько номеров, то они заменяются на интервал через тире. Пример: 1,3,4,5,6,7,8,10,12,16,17,20,21,22,23,24 превращается в 1,3-8,10,12,16-17,20-24 Как реализовать это наиболее изящным способом? Конкретный язык не важен, но лучше C++ или подобный ему.
Числа уже отсортированы по возрастанию? Вижу что в примере они отсортированы, но может стоит задача одновременно сортировки и вычисления интервалов.
PHP: <?php //$list = ['1','3','4','5','6','7','8','10','12','16','17','20','21','22','23','24']; // случайные цифры $list = array_rand(range(1, 100), 80); unset($list[0]); echo implode(", ", $list)."<br><br><br><hr>"; // алгоритм $tmp = -1; $prev = -1; foreach ($list as $value) { $next = next($list); $tmp = $value - $prev; if ($tmp > 1 && $next - $value == 1) { echo "$value"; echo "-"; } elseif ($tmp == 1 && $next - $value > 1 ) { echo "$value, "; } elseif ($next - $prev != 2) { echo "$value, "; } $prev = $value; }
Если они отсортированы, то это не задача, а простейший цикл с проверкой предыдущего значения. Если они не отсортированы, то их надо отсортировать
Понятно, что это не убийственно трудная задача. Надо сделать коротко и элегантно, или как-то неожиданно — в этом интерес.
простейшая и есть --- Добавлено --- ну я понял. Просто не приходит в голову ничего прикольного кроме тупо в цикле перебрать
=) PHP: for($i=0;$i<count($arr);) { $start_value = $arr[$i]; $shift = $start_value - $i; do { $end_value = $arr[$i]; $i++; } while ($i<count($arr) && $arr[$i] - $i == $shift); echo ($start_value == $end_value) ? "{$start_value}, " : ($start_value+1 == $end_value ? "{$start_value}, {$end_value}, " : "{$start_value}..{$end_value}, "); }
denis01, или я чета непонял.... скопировал код, запустил - он вывел мен тупо исходный массив. --- Добавлено --- MiksIr, тоже непашет. ошибка с 16 и 17 из тестового массива --- Добавлено --- PHP: $list = [1,3,4,5,6,7,8,10,12,16,17,20,21,22,23,24]; $first = array_shift($list); $i = 0; $out = [$i=>[$first,$first]]; foreach($list as $v) { if ( $v-$out[$i][1]==1 ) { $out[$i][1] = $v; } else { $out[++$i] = [$v,$v]; } } foreach($out as $k=>$v) { // печатаем что получилось echo ( $v[0]==$v[1] ? $v[0] : join('-',$v) ).','; } //1,3-8,10,12,16-17,20-24,
Это не ошибка, это верное поведение. Никто не пишет "16-17". Если очень нужно - одно условие убрать. А тебе бы PSR почитать.
@MiksIr, запятая в конце не радует. @denis01, да, проверил тоже, реально, работает на php 7.0.3 но с считает не так как надо кажется. --- Добавлено --- А почему все оставили в конце запятую?
а вот как раз про PSR никто не писал. мало того, написано что важен алгоритм а не конкретный ЯП и его стандарты. хоть на C++ пиши. так что мимо.
Ну думаю это не важно, можно вместо вывода собрать всё в переменную и удалить или в массив и потом сделать implode можно пример, а то смотрю и вроде всё нормально
а что, в том коде использованы какието хитрые/новые возможности 7-й версии? ))) приоритет операторов чтоли? --- Добавлено --- mahmuzar, проверь мой код. может он непашет в Семерке )
@denis01, денис я просто скопировал твой пример. --- Добавлено --- @runcore, сразу поверил. Пашет. @denis01, + у меня каждое обновление страницы выдает разный результат.
О, тогда у тебя в коде слишком много переносов строк! Попробуй записать в одну строчку - код будет гораздо приятнее выглядеть! А 16-17 - просто неверная запись, мало ли что там хотят