#python #for-loop
#python #для цикла
Вопрос:
РЕДАКТИРОВАТЬ: Я РЕШИЛ ВОПРОС, НО Я БЫЛ БЫ ПРИЗНАТЕЛЕН, ЕСЛИ БЫ КТО-НИБУДЬ МОГ ПРОСТО ПОМОЧЬ МНЕ СДЕЛАТЬ МОЙ КОД КАК МОЖНО КОРОЧЕ (ЗАДАЧА СОСТОЯЛА В ТОМ, ЧТОБЫ ЗАКОДИРОВАТЬ ЕГО С НАИМЕНЬШИМ КОЛИЧЕСТВОМ ВОЗМОЖНЫХ СИМВОЛОВ).
Я проходил через некоторые проблемы с python в Интернете, и я наткнулся на этот вопрос.
Нажмите здесь, чтобы просмотреть вопрос-вызов
Я довольно долго пытался решить эту проблему, но я застрял в одном месте (вот мой код):
c = ['H','H','H','H','H','H','H','I','H','H','H','H','F','H','H','H','H','H','H','H','H','H','H','H','H',]
c_copy = list(c)
def prt():
print("n" c[0] "t" c[1] "t" c[2] "t" c[3] "t" c[4] "n"
c[5] "t" c[6] "t" c[7] "t" c[8] "t" c[9] "n"
c[10] "t" c[11] "t" c[12] "t" c[13] "t" c[14] "n"
c[15] "t" c[16] "t" c[17] "t" c[18] "t" c[19] "n"
c[20] "t" c[21] "t" c[22] "t" c[23] "t" c[24])
generations = 3
while generations > 0:
for x, y in enumerate(c):
if(y == 'F'):
c_copy[x] = 'H'
if(y == 'I'):
c_copy[x] = 'F'
try:
if(c[x 1] == 'H'):
c_copy[x 1] = 'I'
if(c[x-1] == 'H'):
c_copy[x-1] = 'I'
if(c[x 5] == 'H'):
c_copy[x 5] = 'I'
if(c[x-5] == 'H'):
c_copy[x-5] = 'I'
except IndexError:
pass
c = list(c_copy)
generations = generations - 1
prt()
Я знаю, в чем моя проблема, но, похоже, я не могу ее обойти. В цикле for, когда i [7] == I, я меняю значение с востока на ‘I’, но когда цикл for переходит к i [8], он снова изменит значение на восток. Это продолжается до тех пор, пока значение не станет «I». как мне обойти это? А также, если кто-то может выполнить задачу более простым и лучшим способом, пожалуйста, разместите свой код.
Спасибо
Комментарии:
1. У меня нет времени на полный ответ, но краткое объяснение: поскольку вы просматриваете каждую ячейку по очереди, но заражение должно распространяться только на одну сетку, вместо изменения существующего массива вы должны создавать новую копию каждого поколения и заполнять каждую ячейку на основеправила. Затем в конце каждого поколения установите c=c_copy .
2. @Wehrdo Спасибо, я попробовал это, и это сработало.
3. AFAIK, обзоры кода должны быть на codereview.stackexchange.com
Ответ №1:
Попробуйте использовать списки для отслеживания ячеек, которые необходимо изменить при определенных условиях. Я также использовал многомерный список для отслеживания поля цветов.
Код с аннотациями:
#sets up the grid and the number of generations
grid=[['H','H','H','H','H'],['H','H','I','H','H'],['H','H','F','H','H'],['H','H','H','H','H'],['H','H','H','H','H']]
gen=3
#loops for each generation
for i in range(gen):
#creates lists for cells that need to be infected if possible
#and cells that need to be replanted
infect=[]
plant=[]
#loops through the grid cells
for x in range(5):
for y in range(5):
if grid[x][y]=='F':
#adds each fading cell to the list for replanting
plant.append([x,y])
if grid[x][y]=='I':
#makes the cell fade
grid[x][y]='F'
#checks if each of its neighbours is a valid grid square
#and if so adds it to the list to be infected if possible
if x>0:
infect.append([x-1,y])
if x<4:
infect.append([x 1,y])
if y>0:
infect.append([x,y-1])
if y<4:
infect.append([x,y 1])
#infects healthy cells in the 'to be infected' list
for x,y in infect:
if grid[x][y]=='H':
grid[x][y]='I'
#replants cells in the replanting list
for x,y in plant:
grid[x][y]='H'
#nicely prints the grid
for a in grid:
for b in a:
print(b,end='')
print()
Код без аннотаций:
grid=[['H','H','H','H','H'],['H','H','I','H','H'],['H','H','F','H','H'],['H','H','H','H','H'],['H','H','H','H','H']]
gen=3
for i in range(gen):
infect=[]
plant=[]
for x in range(5):
for y in range(5):
if grid[x][y]=='F':
plant.append([x,y])
if grid[x][y]=='I':
grid[x][y]='F'
if x>0:
infect.append([x-1,y])
if x<4:
infect.append([x 1,y])
if y>0:
infect.append([x,y-1])
if y<4:
infect.append([x,y 1])
for x,y in infect:
if grid[x][y]=='H':
grid[x][y]='I'
for x,y in plant:
grid[x][y]='H'
for a in grid:
for b in a:
print(b,end='')
print()
Ответ №2:
Вот другое решение:
import sys
# use a string to hold the flowerbed
bed = 'HHHHH' 'HHIHH' 'HHFHH' 'HHHHH' 'HHHHH'
# a function to write out a flowerbed
pr = lambda b: sys.stdout.write('n'.join(b[x:x 5] for x in range(0, 25, 5)) 'nn')
# make a list of the cells to check for infection, for each bed position
ckl = [ list(cc for cc in (5*(r-1) c, 5*r c-1, 5*r c, 5*r c 1, 5*(r 1) c)
if 0 <= cc < 25 and (cc // 5 ==r or cc % 5 == c))
for r in range(5)
for c in range(5) ]
pr(bed) # print the initial configuration
for gen in range(5):
bed = ''.join([ tx.get(c, 'I' if bed[i]=='H' and any([bed[n]=='I' for n in ckl[i]])
else 'H')
for i,c in enumerate(bed) ])
pr(bed)
Ответ №3:
Этот ответ должен работать
class Flowers(object):
def __init__(self, flowers_state):
self.flowers_state = flowers_state
def run_rule(self):
"""
Rule1 -> Infected area become faded the following year
Rule2 -> Faded aread becomes Healthy
Rule3 -> Infected area passes infections to North, east, west, south.
"""
visited = []
for row_index, row_flowers_state in enumerate(self.flowers_state):
for flower_index, flower_state in enumerate(row_flowers_state):
if (row_index, flower_index) not in visited and flower_state == 'I':
# Rule -> 3
for x, y in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
try:
if (row_index x, flower_index y) not in visited and
self.flowers_state[row_index x][flower_index y] == 'H':
self.flowers_state[row_index x][flower_index y] = 'I'
visited.append((row_index x, flower_index y))
except IndexError:
pass
# Rule -> 1
self.flowers_state[row_index][flower_index] = 'F'
visited.append((row_index, flower_index))
elif (row_index, flower_index) not in visited and flower_state == 'F':
# Rule -> 2
self.flowers_state[row_index][flower_index] = 'H'
visited.append((row_index, flower_index))
def print_states(self):
print "n".join(["".join(flowers_state_row) for flowers_state_row in self.flowers_state])
def main():
flowers_state = [
['H', 'H', 'H', 'H', 'H'],
['H', 'H', 'I', 'H', 'H'],
['H', 'H', 'F', 'H', 'H'],
['H', 'H', 'H', 'H', 'H'],
['H', 'H', 'H', 'H', 'H']
]
f = Flowers(flowers_state)
for _ in xrange(0, 3):
f.run_rule()
f.print_states()
print "n"
main()
Ответ №4:
Решение на основе Numpy (в 2D массивах numpy curr
и next
в функции update
0, 1 и 2 соответствуют «исправным», «зараженным» и «исчезнувшим» соответственно):
import numpy as np
def update(curr, next):
next[curr==1] = 2 # infected flowers become faded
next[curr==2] = 0 # faded flowers become healthy
iw0 = np.argwhere(curr==0) # indices of elements of `curr` that are 0 (healthy)
next[tuple(iw0.T)] = 0
def fix_bad_indices(ia, shape):
""" ia : an array of array-indices, some of which may be bad (exceed array dimensions)
shape: an array's shape based on which any bad index in `ia` will be fixed
(Note that the data in `ia` may get modified in this function)
"""
assert ia.ndim == 2 and len(shape) == ia.shape[1]
for axis, size in enumerate(shape):
for bad, new in [(-1, 0), (size, size-1)]:
kk = ia[:, axis]
kk[bad == kk] = new
return ia
senw = [(1, 0), (0, 1), (-1, 0), (0, -1)] # south, east, north, west
# an array of neighbour indices of all healthy flowers
nb_idxs = np.stack([fix_bad_indices(iw0 shift, curr.shape) for shift in senw], axis=1)
# elements of `curr` at neighbour-indices
nb_elems = curr[tuple(nb_idxs.reshape(-1, 2).T)]
nb_elems = nb_elems.reshape(*nb_idxs.shape[:-1])
nb_elems[nb_elems==2] = 0
next[tuple(iw0.T)] = np.any(nb_elems, axis=1)
def run(grid):
curr = grid
next = curr.copy()
while 1:
update(curr, next)
yield next
next, curr = curr, next
def main(grid, ngens):
dct = {'H':0, 'I':1, 'F':2}
rdct = dict(zip(dct.values(), dct.keys()))
def to_string(array):
return 'n'.join(''.join(rdct[x] for x in row) for row in array)
def to_array(string):
return np.array([[dct[x] for x in row] for row in string.splitlines()])
# grid = np.mod(np.arange(20).reshape(5, 4), 3)
grid = to_array(grid)
print(to_string(grid))
print()
for i, grid in zip(range(ngens), run(grid)):
print(to_string(grid))
print()
return to_string(grid)
if __name__ == '__main__':
grid="""HHHHH
HHIHH
HHFHH
HHHHH
HHHHH""".replace(' ','')
main(grid, 3)