2013-12-14 6 views
3

У меня проблема в TalentBuddy, который звучит как производительность этогоНайти число последовательно ПОВЫШЕНИЕ элементов в списке

студента в лаборатории деятельности всегда должны улучшить, но это не всегда так. Поскольку прогресс является одним из самых важных показателей для ученика, давайте напишем программу, которая вычисляет самый длинный период повышения производительности для любого данного учащегося. Например, если его оценки для всех лабораторных действий в курсе: 9, 7, 8, 2, 5, 5, 8, 7, то самым длинным периодом будет 4 последовательных лаборатории (2, 5, 5, 8).

До сих пор я, похоже, слишком смущен, чтобы работать с кодом. Единственное, что я работал в

def longest_improvement(grades): 
    res = 0 
    for i in xrange(len(grades) - 2): 
     while grades[i] <= grades[i + 1]: 
      res += 1 
      i += 1 
    print res 

Но что печатает 17, а не 6 когда grades = [1, 7, 2, 5, 6, 9, 11, 11, 1, 6, 1].

Как выработать остальную часть кода? Спасибо

+0

Я думаю, что Тим использовал эту идею в Tim Sort ... :) – thefourtheye

ответ

3

решаемые с некоторой старомодной хвостовой рекурсии:

grades = [1, 7, 2, 5, 6, 9, 11, 11, 1, 6, 1] 

def streak(grades): 
    def streak_rec(longest, challenger, previous, rest): 
     if rest == []:    # Base case 
      return max(longest, challenger) 
     elif previous <= rest[0]: # Streak continues 
      return streak_rec(longest, challenger + 1, rest[0], rest[1:]) 
     else:      # Streak is reset 
      return streak_rec(max(longest, challenger), 1, rest[0], rest[1:]) 

    return streak_rec(0, 0, 0, grades) 

print streak(grades) # => 6 
print streak([2]) # => 1 
+1

'strreak ([1]) => 2' – Voo

+0

К сожалению, неправильный аккумулятор! Исправлена. Спасибо :) –

+0

Лучшее решение далеко! Awesomely done :) –

0

Вы используете ту же переменную res на каждой итерации внутреннего цикла while. Вероятно, вы захотите сбросить его и сохранить самый высокий промежуточный результат в другой переменной.

0

Немного поздня, но вот мой Обновлен версия:

from funcy import ilen, ireductions 


def streak(last, x): 
    if last and x >= last[-1]: 
     last.append(x) 
     return last 
    return [x] 


def longest_streak(grades): 
    xs = map(ilen, ireductions(streak, grades, None)) 
    return xs and max(xs) or 1 

grades = [1, 7, 2, 5, 6, 9, 11, 11, 1, 6, 1] 
print longest_streak(grades) 
print longest_streak([2]) 

я решил в конце концов не только производить правильную версии без ошибок, но использовать библиотеку я очень хотело funcy :)

Выход:

6 
1 
+0

Возможно, генератор был бы упрощен, и я подозреваю, что '' funcy'' или ' Библиотеки 'toolz'' (* или даже itertools *) очень помогли бы обобщить и упростить проблему :) –

+0

Это должно быть самое сложное решение этой проблемы, которое я когда-либо видел. Но я предполагаю, что если он работает ^^ – Voo

+0

IHMO это совсем не сложно. Он выполняет базовое разбиение списка входных данных. Это можно было бы упростить, используя хорошие функциональные библиотеки. –

1

Поскольку текущее решение включает в себя выход и карты и дополнительные накладные расходы памяти, это, вероятно, хорошая идея, по крайней мере, упомянуть простое решение:

def length_of_longest_sublist(lst): 
    max_length, cur_length = 1, 1 
    prev_val = lst[0] 
    for val in lst[1:]: 
     if val >= prev_val : 
      cur_length += 1 
     else: 
      max_length = max(max_length, cur_length) 
      cur_length = 1 
     prev_val = val 
    return max(max_length, cur_length) 

Мы могли бы сократить этот код, получая предыдущее значение непосредственно:

def length_of_longest_sublist2(lst): 
    max_length, cur_length = int(bool(lst)), int(bool(lst)) 
    for prev_val, val in zip(lst, lst[1:]): 
     if val >= prev_val: 
      cur_length += 1 
     else: 
      max_length = max(max_length, cur_length) 
      cur_length = 1 
    return max(max_length, cur_length) 

, который является хорошим трюком, чтобы знать (и позволяет ему легко вернуть правильный результат для пустого списка), но смущает людей, которые не знают идиомы.

0

Может быть не столь эффективным, как и предыдущие ответы, но это коротко: P

diffgrades = np.diff(grades) 
maxlen = max([len(list(g)) for k,g in groupby(diffgrades, lambda x: x >= 0) if k]) + 1 
+0

Не будет работать, если 'len (оценки) <2', в противном случае это круто – Suor

1

Этот метод использует довольно простые питона и возвращение оператор может быть быстро изменен, так что у вас есть список всех длин строк.

def longest_streak(grades): 
    if len(grades) < 2: 
     return len(grades) 
    else: 
     start, streaks = -1, [] 
     for idx, (x, y) in enumerate(zip(grades, grades[1:])): 
      if x > y: 
       streaks.append(idx - start) 
       start = idx 
     else: 
      streaks.append(idx - start + 1) 
     return max(streaks) 
0

Основываясь на идее @ M4rtini использовать itertools.groupby.

def longest_streak(grades): 
    from itertools import groupby  
    if len(grade) > 1: 
     streak = [x <= y for x, y in zip(grades,grades[1:])] 
     return max([sum(g, 1) for k, g in groupby(streak) if k]) 
    else: 
     return len(grades) 
1

я бы решить это следующим образом:

from itertools import groupby 
from funcy import pairwise, ilen 

def streak(grades): 
    if len(grades) <= 1: 
     return len(grades) 
    orders = (x <= y for x, y in pairwise(grades)) 
    return max(ilen(l) for asc, l in groupby(orders) if asc) + 1 

Очень четко: orders является итератор True с для восходящих пар и False с для нисходящей из них. Тогда нам нужно просто найти самый длинный список по возрастанию и добавить 1.

+0

Мне это нравится :) Очень приятно продумано! –

Смежные вопросы