HackerRank Conway的生命游戏算法

时间:2014-04-24 00:05:51

标签: algorithm conways-game-of-life

我最近完成了题为“康威的生命游戏”的有趣HackerRank问题。"问题陈述如下:

  

生命游戏是由英国数学家John Horton Conway设计的细胞自动机游戏。原始游戏是零玩家   游戏。它的演变完全取决于它的输入。

     

生命游戏发生在2D网格上。网格中的每个单元格都是   在两种可能的状态之一,

     

ALIVE DEAD细胞的出生或死亡基于以下内容   规则。

     

如果单元格正好被3包围,则单元格从DEAD切换到ALIVE   活细胞。如果一个细胞被2或3个生命包围,它仍然存活   细胞。如果被包围,则单元格从ALIVE切换到DEAD   由于人口过多,超过3个活细胞。一个小区切换   如果被不到2个细胞包围,则从活着变为死亡   因为人口不足每个细胞被8个细胞包围,4个细胞   它的两侧和四角。极端角落的细胞只有   3个邻居和最右边,左边,顶部和底部的细胞   董事会有5个相邻的单元格。上面提到的规则   也适用于这些细胞。

     

此版本的生命游戏取代了左上角的29x29网格   单元格为(0,0),右下单元格为(28,28)。它的索引为   (行,列)类似于计算机科学中的数组。两名球员对战   彼此。这个游戏与原版的不同之处在于细胞   ALIVE时有两种状态。

这两个州      

白色黑色第一条规则有所不同。

     

当一个单元格从DEAD切换到ALIVE时,它会呈现颜色   大多数3个细胞。由于3是奇数,因此多数总是存在。   其余规则遵循游戏的原始版本。原来,   所有细胞都处于死亡状态。第一个玩家玩WHITE和   第二位玩家扮演黑人。每个玩家轮流切换一个DEAD   细胞到ALIVE状态。 ALIVE单元格采用分配给的颜色   播放器。这一直持续到每个玩家放置了40个细胞   网格上各自的颜色。然后比赛开始了。活着的细胞   在500个生命周期结束时的最大颜色赢得比赛!

     

输入格式

     

第一个玩家由角色w(ascii值119)和   第二个玩家由角色b(ascii值98)表示。   输入的第一行代表玩家的角色。 29   行跟随。每行有29个字符,之间没有任何空格   他们。活细胞由它们各自的特征表示   死细胞用 - (ascii值45)表示。

     

输出

     

输出是2个单行间隔的整数,表示位置   需要从DEAD切换到ALIVE的单元格。

此处的官方问题网站上有一个示例输入和示例输出以及更多详细信息:https://www.hackerrank.com/challenges/conway

我想知道其他黑客使用的算法。我现在正好在列表的底部 - 任何其他视角都非常有用。

1 个答案:

答案 0 :(得分:0)

Conway的生命游戏的两个玩家版本非常有趣,到目前为止,我已经开发并向HackerRank提交了一个可靠的算法(获得41.656分)。

我写的这个程序试图全面设置对角线作为障碍,阻止对手部署他们的常规策略,同时为我提供更多的空间来重现和全面展开。

下面是我的实现(在Python中):

#!/usr/bin/python
# Conway's game of life - set up diagonals across the board
BOARD_SIZE = 28;

#get the next move, 
def nextMove(player, board):
    b = [] #append to b
    for s in board:
        b.append(list(s))

    #check up left (rows) 
    for r in range(0, BOARD_SIZE, 2):
        if (b[BOARD_SIZE - r][BOARD_SIZE] == "-"):
            return BOARD_SIZE - r, BOARD_SIZE
        else:
            row, col= diagUL(b, BOARD_SIZE - r, BOARD_SIZE)
            if (row!= -1):
                return row, col

    #check up left (cols)
    for c in range(0, BOARD_SIZE, 2):
        if (b[BOARD_SIZE][BOARD_SIZE - c] == "-"):
            return BOARD_SIZE, BOARD_SIZE - c
        else:
            row, col= diagUL(b, BOARD_SIZE, BOARD_SIZE - c)
            if (row!= -1):
                return row, col

    #check up right (rows) 
    for r in range(0, BOARD_SIZE, 2):
        if (b[r][BOARD_SIZE] == "-"):
            return r, BOARD_SIZE
        else:
            row, col= diagUR(b, r, BOARD_SIZE)
            if (row!= -1):
                return row, col

    #check up right (cols)
    for c in range(0, BOARD_SIZE, 2):
        if (b[0][BOARD_SIZE - c] == "-"):
            return 0, BOARD_SIZE - c
        else:
            row, col= diagUR(b, 0, BOARD_SIZE - c)
            if (row!= -1):
                return row, col

#gets the diagonals (up right and up left) 
def diagUL(bd, r, c):
    if (r == 0 or c == 0):
        return -1, -1
    elif (bd[r - 1][c - 1] == "-"):
        return r - 1, c - 1
    else:
        return diagUL(bd, r - 1, c - 1)

def diagUR(bd, r, c):
    if (r == BOARD_SIZE or c == 0):
        return -1, -1
    elif (bd[r + 1][c - 1] == "-"):
        return r + 1, c - 1
    else:
        return diagUL(bd, x + 1, y - 1)

#i/o
player = raw_input()
board = []
for row in xrange(0, 29):
    board.append(raw_input())
a,b = nextMove(player, board)
print a,b