def isInside(grid, x, y): return y >= 0 and y < len(grid) and x >= -y and x <= y def getGrid(grid, x, y): if not isInside(grid, x, y): return 0 i = x + y return grid[y][i] def setGrid(grid, x, y, value): while len(grid) <= y: grid.append([0] * (2 * len(grid) + 1)) if not isInside(grid, x, y): return False i = x + y grid[y][i] = value def fancyPrint(grid): for j, line in enumerate(grid): s = ' ' * (len(grid) - j - 1) for i, value in enumerate(line): s += str(value) # s += 'X' if value else '.' print s def visit(grid, visited, query, x, y): setGrid(visited, x, y, 1) toVisit = [(x, y)] while len(toVisit) > 0: (x, y), toVisit = toVisit[0], toVisit[1:] for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]: nx, ny = (x + dx, y + dy) if isInside(grid, nx, ny) and not getGrid(visited, nx, ny) and \ getGrid(grid, nx, ny) == query: setGrid(visited, nx, ny, 1) toVisit.append((nx, ny)) def countRegions(grid, query): visited=[] count = 0 for y, line in enumerate(grid): for i, value in enumerate(line): x = i - y if value == query and not getGrid(visited, x, y): count = count + 1 visit(grid, visited, query, x, y) return count def countRegions2(grid, regionsBefore, countBefore): nextId = 1 currId = -1 lastWas1 = True idMap = {} y = len(grid) - 1 for x in range(-y, y + 1): if getGrid(grid, x, y): lastWas1 = True else: regionAbove = getGrid(regionsBefore, x, y-1) if lastWas1: # Use id map if appropriate try: currId = idMap[regionAbove] except KeyError: currId = nextId nextId = nextId + 1 lastWas1 = False if regionAbove: idMap[regionAbove] = currId setGrid(regionsBefore, x, y, currId) return nextId - 1 + countBefore - len(idMap) grid=[] regionsBefore = [] setGrid(grid, 0, 0, 1) rule = 30 countBefore = countRegions2(grid, regionsBefore, 0) #countBefore = countRegions(grid, 0) print 0, countBefore for y in range(1, 1000): for x in range(-y, y + 1): bitIndex = getGrid(grid, x + 1, y - 1) bitIndex += 2 * getGrid(grid, x, y - 1) bitIndex += 4 * getGrid(grid, x - 1, y - 1) value = 1 if rule & (1 << bitIndex) else 0 setGrid(grid, x, y, value) countBefore = countRegions2(grid, regionsBefore, countBefore) # countBefore = countRegions(grid, 0) print y, countBefore #fancyPrint(grid)