http://nabetani.sakura.ne.jp/hena/ord4tetroid/
で出題されたテトロミノ認識をPythonで解いてみる
全検索して、
ifで図形一つずつ比較していく作戦
ブロックは4つしかない。と決めつけて解いている。
yhpg04.py
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# https://yhpg.doorkeeper.jp/
# http://nabetani.sakura.ne.jp/hena/ord4tetroid/
def solve(data):
field = createField(data)
for i in range(len(field)-1):
for j in range(len(field[i])-1):
if isL(field,i,j):
return "L"
elif isI(field,i,j):
return "I"
elif isT(field,i,j):
return "T"
elif isO(field,i,j):
return "O"
elif isS(field,i,j):
return "S"
else:
continue
return "-"
def isL(field,i,j):
#1,
#1,
#1,1
# or
#x,1
#x,1
#1,1
if field[i][j] == 1 and field[i+1][j] == 1 and field[i+2][j] == 1 and (field[i+2][j+1] or field[i+2][j-1]):
return True
#1,1,1
#x,x,1
#or
#x,x,1
#1,1,1
elif field[i][j] == 1 and field[i][j+1] == 1 and field[i][j+2] == 1 and (field[i+1][j+2] or field[i-1][j+2]):
return True
#1,1,1
#1
#or
#1,
#1,1,1
elif field[i][j] == 1 and field[i][j+1] == 1 and field[i][j+2] == 1 and (field[i+1][j] or field[i-1][j]):
return True
#1,1
#1
#1
elif field[i][j] == 1 and field[i+1][j] == 1 and field[i+2][j] == 1 and field[i][j+1]:
return True
#1,1
#x,1
#x,1
elif field[i][j] == 1 and field[i][j+1] == 1 and field[i+1][j+1] == 1 and field[i+2][j+1]:
return True
return False
def isI(field,i,j):
#1
#1
#1
#1
if field[i][j] == 1 and field[i+1][j] == 1 and field[i+2][j] == 1 and field[i+3][j] == 1:
return True
#1,1,1,1
elif field[i][j] == 1 and field[i][j+1] == 1 and field[i][j+2] == 1 and field[i][j+3] == 1:
return True
return False
def isT(field,i,j):
#x,1,
#1,1,1
#or
#1,1,1
#x,1,
if field[i][j] == 1 and field[i][j+1] == 1 and field[i][j+2] == 1 and (field[i-1][j+1] == 1 or field[i+1][j+1]):
return True
#1,
#1,1,
#1,
#x,1
#1,1
#x,1
elif field[i][j] == 1 and field[i+1][j] == 1 and field[i+2][j] == 1 and (field[i+1][j+1] == 1 or field[i+1][j-1] == 1):
return True
return False
def isO(field,i,j):
#1,1,
#1,1,
if field[i][j] == 1 and field[i][j+1] == 1 and field[i+1][j] == 1 and field[i+1][j+1] == 1:
return True
return False
def isS(field,i,j):
#1,
#1,1
#x,1
#or
#x,1
#1,1
#1,
if field[i][j] == 1 and field[i+1][j] == 1 and ((field[i+1][j+1] == 1 and field[i+2][j+1] == 1) or ( field[i+1][j-1] == 1 and field[i+2][j-1] == 1)):
return True
#x,1,1
#1,1,
#or
#1,1,
#x,1,1
elif field[i][j] == 1 and field[i][j+1] == 1 and ((field[i+1][j-1] == 1 and field[i+1][j] == 1) or (field[i+1][j+1] == 1 and field[i+1][j+2] == 1)):
return True
return False
def createField(data):
field = [[0 for rows in range(12)] for columns in range(12)]
dataArray = data.split(",")
for d in dataArray:
field[int(d[0],10)+1][int(d[1],10)+1] = 1
return field
def test(data, expect):
result = solve(data)
if result == expect:
print("成功: " + result + "/" + expect )
else:
print("失敗: " + result + "/" + expect )
test("55,55,55,55", "-")
test("39,28,27,29", "L")
test("63,62,43,53", "L");
test("32,42,43,44", "L");
test("81,72,91,71", "L");
test("62,64,72,63", "L");
test("45,25,35,24", "L");
test("12,20,22,21", "L");
test("66,46,67,56", "L");
test("44,46,45,43", "I");
test("04,24,14,34", "I");
test("43,42,41,40", "I");
test("48,38,58,68", "I");
test("31,20,22,21", "T");
test("69,79,78,89", "T");
test("42,33,44,43", "T");
test("16,25,05,15", "T");
test("27,37,28,38", "O");
test("13,24,23,14", "O");
test("63,72,62,73", "O");
test("73,63,62,74", "S");
test("56,57,47,66", "S");
test("88,99,98,87", "S");
test("62,43,52,53", "S");
test("86,95,87,96", "S");
test("84,83,73,94", "S");
test("32,33,41,42", "S");
test("86,85,75,96", "S");
test("97,76,96,77", "-");
test("53,55,45,43", "-");
test("73,93,94,84", "-");
test("31,33,41,42", "-");
test("21,32,11,12", "-");
test("73,75,65,64", "-");
test("64,65,45,54", "-");
test("12,00,01,10", "-");
test("94,85,75,74", "-");
test("87,86,77,75", "-");
test("56,56,56,56", "-");
test("41,42,41,52", "-");
test("61,60,63,61", "-");
test("03,13,33,13", "-");
test("92,96,94,93", "-");
test("15,25,55,45", "-");
test("17,14,16,13", "-");
test("72,83,83,92", "-");
test("40,40,42,51", "-");
test("81,80,93,82", "-");
test("51,61,30,41", "-");
test("17,37,35,15", "-");
もうちょっとどうにかならないかと思って考えてみた。
縦と横から1がならんでいる数をかぞえて図形を判断する作戦。
なんとかif文の数を減らしたいなと思ったのだけれど、結果は何も変わらなかった。ふしぎ。
図形がfieldの中に1つしか存在しないとなりたたないのも、最初に書いた奴と変わらない。
yhpg04_02.py
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# https://yhpg.doorkeeper.jp/
# http://nabetani.sakura.ne.jp/hena/ord4tetroid/
def solve(data):
field = createField(data)
pattern = []
pattern.append(countDuplicate(field))
pattern.append(countDuplicate(list(zip(*field))))
if isL(pattern) :
return "L"
elif isI(pattern):
return "I"
elif isT(pattern):
return "T"
elif isO(pattern):
return "O"
elif isS(pattern):
return "S"
else:
return "-"
def isL(pattern):
if pattern == [[3, 1], [1, 1, 2]]:
return True
elif pattern == [[1, 1, 2], [1, 3]]:
return True
elif pattern == [[1, 3], [2, 1, 1]]:
return True
elif pattern == [[2, 1, 1], [3, 1]]:
return True
elif pattern == [[3, 1], [2, 1, 1]]:
return True
elif pattern == [[2, 1, 1], [1, 3]]:
return True
elif pattern == [[1, 3], [1, 1, 2]]:
return True
elif pattern == [[1, 1, 2], [3, 1]]:
return True
else:
return False
def isI(pattern):
if pattern == [[4], [1, 1, 1, 1]]:
return True
elif pattern == [[1, 1, 1, 1], [4]]:
return True
elif pattern == [[4], [1, 1, 1, 1]]:
return True
elif pattern == [[1, 1, 1, 1], [4]]:
return True
else:
return False
def isT(pattern):
if pattern == [[3, 1], [1, 2, 1]]:
return True
elif pattern == [[1, 2, 1], [1, 3]]:
return True
elif pattern == [[1, 3], [1, 2, 1]]:
return True
elif pattern == [[1, 2, 1], [3, 1]]:
return True
else:
return False
def isO(pattern):
if pattern == [[2, 2], [2, 2]]:
return True
else:
return False
def isS(pattern):
if pattern == [[2, 2], [1, 2, 1]]:
return True
elif pattern == [[1, 2, 1], [2, 2]]:
return True
else:
return False
def countDuplicate(field):
result = []
for i in range(len(field)):
count = 0
for j in range(len(field[i])):
if field[i][j] == 1:
count = countChain(1,field,i,j)
break
if(count != 0):
result.append(count)
return result
#右方向に自身の数も加えて何個つながっているか数える
def countChain(count,field,i,j):
if field[i][j+1] == 1:
count+=1
return countChain(count, field,i,j+1)
else:
return count
def createField(data):
field = [[0 for rows in range(11)] for columns in range(11)]
dataArray = data.split(",")
for d in dataArray:
field[int(d[0],10)][int(d[1],10)] = 1
return field