За последние 24 часа нас посетили 17724 программиста и 1709 роботов. Сейчас ищут 1634 программиста ...

Задачка на нахождение непрерывных интервалов

Тема в разделе "Прочее", создана пользователем artoodetoo, 9 май 2016.

Метки:
  1. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    Есть такая тема на русском стековерфлоу: 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++ или подобный ему.
     
  2. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Числа уже отсортированы по возрастанию? Вижу что в примере они отсортированы, но может стоит задача одновременно сортировки и вычисления интервалов.
     
  3. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    Я тоже думаю, что они уже отсортированы.
     
  4. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    PHP:
    1. <?php
    2. //$list = ['1','3','4','5','6','7','8','10','12','16','17','20','21','22','23','24'];
    3.  
    4. // случайные цифры
    5. $list = array_rand(range(1, 100), 80);
    6. unset($list[0]);
    7. echo implode(", ", $list)."<br><br><br><hr>";
    8.  
    9. // алгоритм
    10. $tmp = -1;
    11. $prev = -1;
    12. foreach ($list as $value) {
    13.  
    14.     $next = next($list);
    15.  
    16.     $tmp = $value - $prev;
    17.  
    18.     if ($tmp > 1 && $next - $value == 1) {
    19.         echo "$value";
    20.         echo "-";
    21.     } elseif ($tmp == 1 && $next - $value > 1 ) {
    22.         echo "$value, ";
    23.     } elseif ($next - $prev != 2) {
    24.         echo "$value, ";
    25.     }
    26.  
    27.     $prev = $value;
    28. }
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Если они отсортированы, то это не задача, а простейший цикл с проверкой предыдущего значения.
    Если они не отсортированы, то их надо отсортировать :D
     
  6. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    @igordata тогда будет обычная сортировка с простейшими условиями
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    Понятно, что это не убийственно трудная задача. Надо сделать коротко и элегантно, или как-то неожиданно — в этом интерес.
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    простейшая и есть
    --- Добавлено ---
    ну я понял. Просто не приходит в голову ничего прикольного кроме тупо в цикле перебрать
     
  9. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    =)
    PHP:
    1. for($i=0;$i<count($arr);) {
    2.     $start_value = $arr[$i];
    3.     $shift = $start_value - $i;
    4.     do {
    5.       $end_value = $arr[$i];
    6.       $i++;
    7.     } while ($i<count($arr) && $arr[$i] - $i == $shift);
    8.     echo ($start_value == $end_value) ? "{$start_value}, " :
    9.        ($start_value+1 == $end_value ? "{$start_value}, {$end_value}, " : "{$start_value}..{$end_value}, ");
    10. }
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    do-while попов стайл :D
     
  11. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Глупый что ли? ;)
     
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    да нет, ты не глупый, просто шутку не понял. (это была новая шутка)
     
  13. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Фи, прием уровня детского сада.
    Ну так "лопата" не забывай дописывать.
     
  14. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    denis01, или я чета непонял.... скопировал код, запустил - он вывел мен тупо исходный массив.
    --- Добавлено ---
    MiksIr, тоже непашет. ошибка с 16 и 17 из тестового массива
    --- Добавлено ---
    PHP:
    1. $list = [1,3,4,5,6,7,8,10,12,16,17,20,21,22,23,24];
    2. $first = array_shift($list);
    3. $i = 0;
    4. $out = [$i=>[$first,$first]];
    5. foreach($list as $v) {
    6.   if ( $v-$out[$i][1]==1 ) { $out[$i][1] = $v; }
    7.   else { $out[++$i] = [$v,$v]; }
    8. }
    9. foreach($out as $k=>$v) { // печатаем что получилось
    10.   echo ( $v[0]==$v[1] ? $v[0] : join('-',$v) ).',';
    11. }
    12. //1,3-8,10,12,16-17,20-24,
     
  15. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    @runcore на PHP7 мой код работает
     
  16. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Это не ошибка, это верное поведение. Никто не пишет "16-17". Если очень нужно - одно условие убрать. А тебе бы PSR почитать.
     
  17. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
     
  18. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    upload_2016-5-10_11-31-19.png
    @MiksIr, запятая в конце не радует.
    @denis01, да, проверил тоже, реально, работает на php 7.0.3
    но с считает не так как надо кажется.
    upload_2016-5-10_11-36-43.png
    --- Добавлено ---
    А почему все оставили в конце запятую?
     
  19. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    а вот как раз про PSR никто не писал. мало того, написано что важен алгоритм а не конкретный ЯП и его стандарты. хоть на C++ пиши.
    так что мимо.
     
  20. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    Ну думаю это не важно, можно вместо вывода собрать всё в переменную и удалить или в массив и потом сделать implode

    можно пример, а то смотрю и вроде всё нормально
     
  21. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    а что, в том коде использованы какието хитрые/новые возможности 7-й версии? ))) приоритет операторов чтоли?
    --- Добавлено ---
    mahmuzar, проверь мой код. может он непашет в Семерке )
     
  22. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    @denis01, денис я просто скопировал твой пример.
    --- Добавлено ---
    @runcore, сразу поверил. Пашет.

    @denis01, + у меня каждое обновление страницы выдает разный результат.
     
  23. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    О, тогда у тебя в коде слишком много переносов строк! Попробуй записать в одну строчку - код будет гораздо приятнее выглядеть!

    А 16-17 - просто неверная запись, мало ли что там хотят ;)
     
  24. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    @denis01, понял, у тебя исходные данные рандомные))
     
  25. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    правильно, он генерит всегда разные тестовые наборы данных
    $list = array_rand(range(1, 100), 80);