Chain Disappearance Puzzle

We are playing a puzzle. An upright board with H rows by 5 columns of cells is used in this puzzle. A stone engraved with a digit, one of 1 through 9, is placed in each of the cells. When three or more stones in horizontally adjacent cells are engraved with the same digit, the stones will disappear. If there are stones in the cells above the cell with a disappeared stone, the stones in the above cells will drop down, filling the vacancy.

The puzzle proceeds taking the following steps:
1. When three or more stones in horizontally adjacent cells are engraved with the same digit, the stones will disappear. Disappearances of all such groups of stones take place simultaneously.
2. When stones are in the cells above the emptied cells, these stones drop down so that the emptied cells are filled.
3. After the completion of all stone drops, if one or more groups of stones satisfy the disappearance condition, repeat by returning to step 1.

The score of this puzzle is the sum of the digits on the disappeared stones. Write a program that calculates the score of given configurations of stones.

Input:
The input consists of multiple datasets. Each dataset is formed as follows:
Board height H
Stone placement of each row from top to bottom.

The first line specifies the height (H) of the puzzle board (1 ≤ H ≤ 10). The remaining H lines give placement of stones on each of the rows from top to bottom. The placements are given by five digits (1 through 9), separated by a space. These digits are engraved on the five stones in the corresponding row, in the same order. The input ends with a line with a single zero.

Output:
For each dataset, output the score in a line. Output lines may not include any characters except the digits expressing the scores.

Sample Input:
1
6 9 9 9 9
5
5 9 5 5 9
5 5 6 9 9
4 6 3 6 9
3 3 2 9 9
2 2 1 1 1
10
3 5 6 5 6
2 2 2 8 3
6 2 5 9 2
7 7 7 6 1
4 6 6 4 9
8 9 1 1 8
5 6 1 8 1
6 8 2 1 2
9 6 3 3 5
5 3 8 8 8
5
1 2 3 4 5
6 7 8 9 1
2 3 4 5 6
7 8 9 1 2
3 4 5 6 7
3
2 2 8 7 4
6 5 7 7 7
8 8 9 9 9
0

Output for the Sample Input:
36
38
99
0
72

# Buggy version:
from itertools import zip_longest

while True:
    n = int(input())
    if not n:
        break
    field = [list(map(int, input().split())) for _ in range(n)]
    field.reverse()
    score = 0
    while True:
        no_more_disappear = True

        for y, row in enumerate(field):
            for i, stone in enumerate(row):
                if stone is None:
                    continue
                cnt = 1
                for stone2 in row[i + 1:]:
                    if stone != stone2:
                        break
                    cnt += 1
                if cnt >= 3:
                    row[i:i + cnt] = [None] * cnt
                    score += stone * cnt
                    no_more_disappear = False

        if no_more_disappear:
            break

        fieldT = map(lambda row: filter(None, row), zip(*field))
        field = map(list, zip_longest(*fieldT))

    print(score)

# Fixed version:
from itertools import zip_longest

while True:
    n = int(input())
    if not n:
        break
    field = [list(map(int, input().split())) for _ in range(n)]
    field.reverse()
    score = 0
    while True:
        no_more_disappear = True

        for row in field:
            for i, stone in enumerate(row[:3]):
                if stone is None:
                    continue
                cnt = 1
                for stone2 in row[i + 1:]:
                    if stone != stone2:
                        break
                    cnt += 1
                if cnt >= 3:
                    row[i:i + cnt] = [None] * cnt
                    score += stone * cnt
                    no_more_disappear = False

        if no_more_disappear:
            break

        fieldT = map(lambda row: filter(None, row), zip(*field))
        field = list(map(list, zip_longest(*fieldT)))

    print(score)

# Buggy version:
def calc(puzzle,H,score):
    flag=False
    for i in range(H-1,-1,-1):
        stones=[]
        for j in range(5):
            now=puzzle[j][i]
            if (len(stones)==0 or stones[-1]==now) and now!=0: stones.append(now)
            elif len(stones)<3: stones=[now]
            else: break
        if len(stones)>2:
            flag=True
            score+=sum(stones)
            stone=stones[0]
            for j in range(5):
                now=puzzle[j][i]
                if now==stone:
                    if (j<4 and now==puzzle[j+1][i]) or (j>0 and now==puzzle[j-1][i]):
                        puzzle[j].pop(i)
                        puzzle[j].append(0)
    if flag==True:
        return calc(puzzle,H,score)
    else:
        return score

if __name__=="__main__":
    while True:
        score=0
        H=int(input())
        if H==0:
            break
        puzzle=[[] for _ in range(5)]
        for i in range(H):
            temp=list(map(int,input().split()))
            for j in range(5):
                puzzle[j].insert(0,temp[j])
        score=calc(puzzle,H,score)
        print(score)


# Fixed version:
def calc(puzzle,H,score):
    flag=False
    for i in range(H-1,-1,-1):
        stones=[]
        for j in range(5):
            now=[j,puzzle[j][i]]
            if (len(stones)==0 or stones[-1][1]==now[1]) and now[1]!=0: stones.append(now)
            elif len(stones)<3: stones=[now]
            else: break
        if len(stones)>2:
            flag=True
            score+=stones[0][1]*len(stones)
            for stone in stones:
                puzzle[stone[0]].pop(i)
                puzzle[stone[0]].append(0)

    if flag==True:
        return calc(puzzle,H,score)
    else:
        return score

if __name__=="__main__":
    while True:
        score=0
        H=int(input())
        if H==0:
            break
        puzzle=[[] for _ in range(5)]
        for i in range(H):
            temp=list(map(int,input().split()))
            for j in range(5):
                puzzle[j].insert(0,temp[j])
        score=calc(puzzle,H,score)
        print(score)

# Buggy version:
a = int(input())
global s
s = 0

def de(ppp,h):
	re = False
	co  = 0
	global s
	for lo in ppp:
		for j ,cell in enumerate(lo):
			k = j
			p = j
			if k <= 2:
				while cell == lo[k+1] and cell != None:
					co += 1
					if k == 3:
						j = k+1
						break
					k += 1
					j = k
				if co >= 2:
					re = True
					s += (co+1)*cell
					for l in range(5):
						if l >= p and l <= j:
							lo[l] = None
				co = 0

	return re



def mo(ppp,h):
	for i ,roe in enumerate(ppp):
		for j , cell in enumerate(roe):
			kkk = i
			while i != 0 and ppp[kkk-1][j] == None:
				ppp[kkk-1][j] = ppp[kkk][j]
				ppp[kkk][j] = None
				if kkk == 1:
					break
				kkk -= 1


while a != 0:
	ppp = [list(map(int,input().split())) for i in range(a)]
	ppp.reverse()
	while(de(ppp,a) == True):
		mo(ppp,a)
	print(ppp)
	print(s)

	s = 0

	a = int(input())




# Fixed version:
a = int(input())
global s
s = 0

def de(ppp,h):
	re = False
	co  = 0
	global s
	for lo in ppp:
		for j ,cell in enumerate(lo):
			k = j
			p = j
			if k <= 2:
				while cell == lo[k+1] and cell != None:
					co += 1
					if k == 3:
						j = k+1
						break
					k += 1
					j = k
				if co >= 2:
					re = True
					s += (co+1)*cell
					for l in range(5):
						if l >= p and l <= j:
							lo[l] = None
				co = 0

	return re



def mo(ppp,h):
	for i ,roe in enumerate(ppp):
		for j , cell in enumerate(roe):
			kkk = i
			while i != 0 and ppp[kkk-1][j] == None:
				ppp[kkk-1][j] = ppp[kkk][j]
				ppp[kkk][j] = None
				if kkk == 1:
					break
				kkk -= 1


while a != 0:
	ppp = [list(map(int,input().split())) for i in range(a)]
	ppp.reverse()
	while(de(ppp,a) == True):
		mo(ppp,a)
	print(s)

	s = 0

	a = int(input())