LoginSignup
0
0

More than 5 years have passed since last update.

yhpg04 - テトロミノ認識 をPythonで解いてみる

Posted at

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
0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0