Как решить эту задачу от яндекса?

Дана доска размером M × N клеток. Клетка может находиться в одном из двух состояний: 1 — живая, 0 — мёртвая. Каждая клетка взаимодействует с восемью соседями. Правила таковы:

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

Живая клетка, у которой два или три живых соседа, выживает.

Живая клетка, у которой больше трёх живых соседей, погибает.

Мёртвая клетка, у которой три живых соседа, возрождается.

Напишите программу, которая будет:
— случайным образом генерить стартовое состояние;
— уметь получать его из файла (способ выбирается через параметры запуска в консоли);
— каждую секунду выводить в консоль новое состояние доски.

Вот мой код, генерирующий матрицу с рандомными столбцами и строками:

import random

class Matrix:

    def __init__(self, row, col):
        self.n = row
        self.matrix = [[random.randrange(0, 2) for a in range(col)] for b in range(row)]

    def print(self):
        matrix = self.matrix
        for im in range(len(matrix)):
            print(matrix[im])

Matrix(random.randint(5, 10), random.randint(5, 10)).print()


Как мне лучше сделать остальную часть? Не понятны две вещи:
1) Как написать условия? Вроде должно выглядеть так: если у клетки, допустим, три мертвых соседа, то она меняет значение с мертвой(0) на живую(1), то есть возрождается. И тому подобные условия. Я не понимаю, как клетку научить опознавать значения по соседству. Но есть еще усложнение - клетки должны менять состояния каждую секунду, то есть вся таблица будет обновляться ежесекундно, это еще больше сбивает с толку.
2) Что значит программа должна уметь получать стартовое состояние из файла? То есть, допустим, матрицу сохранять в csv файл, а потом из него получать таблицу и её использовать с помощью метода open, верно?
  • Вопрос задан
  • 641 просмотр
Решения вопроса 2
@kunjut19
поищите игра "жизнь". В интернете куча решений.

А вообще:
1) берете клетку (в цикле обходите каждую клетку поля)
2) циклом обозреваете клетки вокруг нее
3) если соседняя клетка живая, увеличиваете счетчик живых соседей на 1
4) после обхода всех соседних клеток (а их 8), смотрите - если клетка, которую вы рассматриваете живая, то
а) оставляете живой, если счетчик живых соседей равен 2 или 3 - оставляете все как есть
б) если другое значение - меняете ее значение на 0
5) если клетка изначально мертвая, то при значении счетчика живых соседей, равного 3, оживляете

Прошлись таким образом по всем клеткам доски, подождали секунду и заново запустили весь этот процесс

Стартовое значение из файла (как я понимаю) - это изначалое расположение живых и мертвых клеток.

У меня есть решение на javascript. Если понимаете этот язык, могу скинуть вам код, а вы переделаете под python
Ответ написан
kshnkvn
@kshnkvn Куратор тега Python
t.me/kshnkvn
Смотри что на г-кодил. Но чую где то напортачил, 100%
from random import randint, randrange
from pprint import pprint
from os import system
from copy import deepcopy


class CellLife:

    def __init__(self, x = None, y = None):
        self.x, self.y = [randrange(10, 25) for _ in range(2) if x is None or y is None]
        self.field = [[randint(0, 1) for _ in range(self.x)] for _ in range(self.y)]
        self.field_state = None

    def environment(self, row, index):
        left_neighbors = row[:index][-8:]
        right_neighbors = row[index:][1:9:]
        while len(left_neighbors + right_neighbors) > 8:
            if left_neighbors < right_neighbors:
                right_neighbors = right_neighbors[:-1]
            else:
                left_neighbors = left_neighbors[1:]
        return left_neighbors + right_neighbors

    def dead_or_alive(self, env, cell):
        state = None
        if cell == 1:
            if env.count(1) < 2 or env.count(1) > 3:
                state = False
            elif env.count(1) in (2, 3):
                state = True
        else:
            if env.count(1) == 3:
                state = True
        return state

    def start_survival(self):
        while self.field_state != self.field:
            self.field_state = deepcopy(self.field)
            for r_index, row in enumerate(self.field):
                for c_index, cell in enumerate(row):
                    env = self.environment(row, c_index)
                    state = self.dead_or_alive(env, cell)
                    if state is not None:
                        if state is True:
                            self.field[r_index][c_index] = 1
                        else:
                            self.field[r_index][c_index] = 0
                        system('cls')
                        pprint(self.field)
        

cell_field = CellLife()
cell_field.start_survival()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Сдаётся мне, что задача для реализации в несколько потоков: ограничение времени и произвольный размер поля - не спроста!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы