Улучшена последовательность "python-look-and-say"

Сначала я хотел бы представить последовательность взглядов и высказываний. Это идет как a = {1, 11, 21, 1211, 111221 ...

Система проверяет предыдущую цифру и считает цифры.

1 = one 1 (so = 11)
11 = two 1 (so = 21)
21 = one 2 one 1 (so = 1211)

Как правило, ни одно число не может превышать 3, так что создание таблицы перевода может вписаться. Но это не семантика, мне это не нравится.

То, что я хочу, - это скрипт, который оценивает заданное значение и возвращает строку, похожую на "смотри и говори".

Однако, чтобы выйти за пределы, я хочу, чтобы он даже оценивал символы, чтобы он мог вернуться 1A2b41,

Я пытался заставить его работать часами, логика вышла из строя, и у меня сейчас мозговая дрожь.

Вот сценарий, который на самом деле не работает (возвращает ложные результаты), но он может дать вам идею, по крайней мере.

def seq(a):
    k,last,result,a = 1,'','',str(a)
    for i in range(len(a)):
        if last==a[i]:k+=1
        else:
            result = result+str(k)+a[i]
            k=1
        last = a[i]
    return result

3 ответа

Решение

Я вижу две проблемы с вашим кодом:

  • result расширяется k а также a[i] хотя счетчик k не считает символы a[i] но символы last, замещать a[i] от last здесь (вы можете не захотеть добавлять что-либо в первом раунде).

  • После цикла вы должны добавить последнее значение счетчика вместе с последним символом снова (это еще не было сделано), т.е. добавить другое result = result+str(k)+last после петли.

В общей сложности это выглядит так

def seq(a):
    a = str(a)
    k,last,result = 1,a[0],''
    for i in range(1,len(a)):
        if last==a[i]:k+=1
        else:
            result = result+str(k)+last
            k=1
        last = a[i]
    result = result+str(k)+last
    return result

Ты можешь использовать groupby, это именно то, что вы хотите:

from itertools import groupby
def lookandsay(n):
    return ''.join( str(len(list(g))) + k for k, g in groupby(n))

>>> lookandsay('1')
'11'
>>> lookandsay('1A2b41')
'111A121b1411'
>>> lookandsay(lookandsay('1A2b41'))
'311A1112111b111421'

groupby возвращает последовательные ключи и группы из повторяемого объекта. Ключ - это функция, вычисляемая для каждого элемента, или тождественная функция, если она не указана (как указано выше). Группа является итератором - новая группа генерируется при изменении значения ключевой функции. Так, например, согласно документации:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D

Я думаю, что одна из причин, по которой вы оказались в тупике, - это использование бессмысленных имен переменных. Вы достаточно хорошо описали проблему и назвали ее по имени, но даже не использовали это имя для своей функции.

Если вы думаете о последовательности, с которой вы начинаете, как о "взгляде", а о той, с которой вы в конечном итоге говорите, как о "говорят", то это начало. result вероятно хорошо, но a а также k смутил вас. last Я думаю, что вводит в заблуждение, потому что это может означать либо предыдущий, либо последний.

Кроме того, Python for действительно foreach по причине - вы берете каждый символ в "look" по одному, так что делайте это явно в цикле.

def looksay(look):
    look = str(look)
    prev, count, say = look[0], 1, ''
    for char in look[1:]:
        if char == prev:
            count += 1
            continue
        say += str(count) + prev
        prev = char
        count = 1
    return say + str(count) + prev

Интервал менее важен, но у Python есть стандартный стиль кодирования, и он помогает читабельности использовать его. Чем меньше умственного времени вам придется потратить на анализ кода, тем больше внимания вы уделите проблеме.

Другие вопросы по тегам