1. Python / Говнокод #3536

    −142

    1. 1
    2. 2
    3. 3
    for i in range(4, len(l)):
    	if l[i] - l[i - 1] == 1 and l[i - 1] - l[i - 2] == 1 and l[i - 2] - l[i - 3] == 1 and l[i - 3] - l[i - 4] == 1:
    		return True

    Нужно было найти в списке 5 элементов, которые могут начинаться на любой позиции, но должны идти по порядку (например [9, 10, 11, 12, 13]). Не придумал ничего лучше :(

    Запостил: cignatov, 22 Июня 2010

    Комментарии (40) RSS

    • так ты хочешь тут узнать как это сделать по нормальному? *Mr. Green*
      поставь в ветке if (l[i] - l[i - 1] == 1) цикл, который проверяет остальные 4 элемента причем лучше заменить for на while и инкрементить i вручную (во вложеном цикле тож будет i)
      Ответить
    • int i = strlen(l);
      int c = 0;
      while (i--) {
        if (l[i] - l[i - 1] == 1) {
          if (++c >= 5) {
            // Нашли
          };
        }
        else c = 0;
      }

      Как-то так. Извините за мой русский.
      Ответить
      • Поясните, пожалуйста, как работает «if (++c >= 5)»?
        Ответить
        • c = c + 1;
          if (c >= 5) {
          Ответить
          • В таком случае не сработает, ведь бывают списки вида
            [0, 1, 4, 6, 8, 9, 10]
            Когда программа сравнит 0 и 1, переменная с примет значение 1, затем ничего не изменится до тех пор, пока не будут сравниваться 8, 9 и 10. То есть, мы выясним, что в последовательности есть 5 случаев, когда соседние члены отличаются на единицу, а задача в том, чтобы выяснить, есть ли в последовательности sub-последовательность из 5 чисел, отличающихся на единицу (извините и за мой русский тоже :)
            Ответить
            • А как же else c = 0; при случае 8 - 6, например ?
              Ответить
              • Чёрт, действительно, спасибо! Я пробовал так делать, но забыл поставить else c=0!
                (разумеется, сперва необходимо отсортировать список)
                Ответить
                • "сперва необходимо отсортировать список"
                  Нахуя? // извините за мой C++
                  Ответить
                  • Потому что список необязательно может быть сортированным:
                    >>> l = [5, 8, 1, 8, 6, 7, 2, 4, 3]
                    >>> l.sort()
                    >>> print l
                    [1, 2, 3, 4, 5, 6, 7, 8, 8]
                    Ответить
                    • что-то я тоже не вкурил
                      тебе же нужно найти последовательность в исходном списке, так зачем же его сортировать?
                      Ответить
                      • Потому что в этом списке есть последовательность, но он перемешан, так что её не найти.
                        Этот код — часть проверки комбинации из 7 карт на содержание в ней покерного стрита:
                        http://en.wikipedia.org/wiki/List_of_poker_hands#Straight
                        Ответить
                        • Тем не менее, неточная постановка задачи detected. И исходный говнокод также предполагает сортировку.
                          Ответить
                          • Какая разница, что будет на входе? В принципе, можно не сортировать.
                            Ответить
      • показать все, что скрытоА причем тут С++ ?
        Ответить
    • показать все, что скрыто> Нужно было найти в списке 5 элементов, которые могут начинаться на любой позиции

      как элемент может "начинаться" на определённой позиции? это не элемент, а множетво, что ли? что это предложение вообще значит?
      Ответить
      • показать все, что скрытовсё, понял, здесь двусмысленность логиколингвистическая была

        в русском языке "Нужно было найти в списке 5 элементов, которые могут начинаться на любой позиции" может значить:

        1) Нужно было найти в списке 5 элементов, каждый из которых может начинаться на любой позиции
        2) Нужно было найти в списке 5 элементов, последовательный ряд которых может начинаться на любой позиции

        Умейте выражаться мысли чётко!
        Ответить
        • Второе. То есть найти такую последовательность в list = [0, 0, 4, 3, 5, 2, 3, 4, 5, 6, 9, 4, 3, 3]
          Ответить
        • >>>Умейте выражаться мысли чётко!
          lol
          Ответить
          • показать все, что скрытоЯ не претендую на звание мастера :)
            Да и вообще, это банальная механическая опечатка, а не врытое глубоко в когнитивные структуры неумение выражать мысли чётко :)
            Ответить
    • Можно сравнивать списки, слайсы, диапазоны...

      l = [1,2,3,4,0,5,6,7,8,9]
      maxlen = 5
      
      for i in range(len(l)-maxlen+1):
      	checkl = range(l[i],l[i]+maxlen,1)
      	if l[i:i+maxlen]==checkl:
      		print 'True'
      		break
      else:
      	print 'False'


      Строго говоря, даже конструкция "len(l)-maxlen+1" необязательна - максимум, будет несколько холостых прогонов в конце.
      Ответить
      • Сортировку и вывод позиции первого элемента последовательности добавить по вкусу.
        Ответить
      • Хм, я забыл про in, правда. Может тогда лучше так? Правда, если числа будут большими, то работать не будет.
        i = 0
        while i < sorted(l)[-1]: # не уверен, что сработает
            checkl = range (i, i + 5)
            if checkl in l:
                return True
                break
            i = i + 1
        Ответить
        • Ну, я не очень понимаю конструкции sorted(l)[-1] - её же можно заменить на max(l).
          Но вот это не сработало:
          i = 0
          while i < max(l):
          	checkl = range(i, i + maxlen)
          	if checkl in l:
          		print 'True'
          		break
          	i = i + 1
          else:
          	print 'False'

          Боюсь, in ищет элемент списка - объект range, а не вхождение последовательности, как в моем коде выше.
          Ответить
          • Надо будет попробовать. Спасибо за хорошую мысль. Список в списке можно искать; в крайнем случае, можно сделать deepcopy объекта range, чтобы получить список... или нельзя, не знаю.
            Ответить
          • Откуда у вас берётся maxlen?
            Ответить
            • Ооопс. Оттуда же, откуда и l - из первого кода.
              l = [1,2,3,4,0,5,6,7,8,9]
              maxlen = 5
              Ответить
      • очень неэффективный способ
        Ответить
        • Возможно. Это реализация "в лоб", как сделал бы человек.
          Ваше предложение?
          Ответить
          • лучший вариант, который приходит мне в голову - пример Stalker-а выше.

            и под очень неэффективным я имел в виду не исходный вариант (хотя он тоже не самый быстрый), а тот где для каждого элемента конструируется массив и сравнивается со слайсом
            Ответить
            • Реализовал пример Сталкера на питоне...
              Вот итог:
              [0, 1, 5, 6, 7, 8, 9]
              0. Yes
              1. Yes
              3. Yes
              method 0, 1000000 iterations
              3.968000 seconds
              method 1, 1000000 iterations
              5.313000 seconds
              method 3, 1000000 iterations
              3.406000 seconds

              Где нулевой метод - обсуждаемый говнокод, первый метод - мой, а третий - Сталкера. Так что вы правы.
              P.S.: Список из семи элементов выбран как максимальное число карт на руках в покере (AFAIK).
              Ответить
    • from itertools import groupby
      
      any(len(list(x[1]))>=5 for x in groupby(x-y for x,y in enumerate(a)))

      как-то так
      Ответить
    • Код автора самый быстрый. А вы все выеживаетесь, и делаете тормознутое говно.
      Ответить
      • Я просто оставлю это здесь http://tinyurl.com/37oogeu
        Ответить
        • Спасибо, пиарь меня, безликий, анонимус. Один из миллиона представителей серой кашицы ))
          Ответить

    Добавить комментарий