Улучшена последовательность "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 есть стандартный стиль кодирования, и он помогает читабельности использовать его. Чем меньше умственного времени вам придется потратить на анализ кода, тем больше внимания вы уделите проблеме.