python вызывает qn для цикла

#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)