포커용 카드는 52개의 카드로 이루어집니다.

 

각 카드는 클럽, 다이아몬드, 하트, 스페이드의 무늬을 가집니다.

이 모양은 C, D, H, S 로 표기합니다. 

 

또한 각 카드는 2에서 10까지, 그리고 잭, 퀸, 킹 또는 에이스의 값을 갖습니다. 

이 값은 2, 3, 4, 5, 6, 7, 8, 9, T, J, Q, K, A 로 표기합니다. 

 

점수를 매길 때 위에 열거한 순서대로 등급이 매겨지며 2가 가장 낮고 에이스가 가장 높습니다.

무늬는 값에 영향을 끼치지 않습니다.

 

포커 패는 다섯 장의 카드로 구성되며 다음과 같은 순서대로 등급이 매겨집니다.

 

하이카드 : 아래에 있는 것 가운데 어떤 범주에도 속하지 않는 패. 가장 높은 카드의 값에 따라 등급이 매겨집니다. 가장 높은 카드의 값이 같으면 그 다음 카드, 그 다음 카드도 같으면 그 다음 카드, 이런 식으로 등급이 매겨집니다.

 

원 페어 : 다섯 장의 카드 가운데 두 장이 같은 경우. 같은 원 페어끼리 맞붙는 경우에는 그 중 더 높은 페어의 값에 의해 더 높은 등급이 매겨집니다. 두 쌍의 값이 모두 같으면 남은 카드에 의해 더 높은 패가 결정됩니다.

 

쓰리 카드 : 다섯 장 가운데 세 장이 같은 값을 가지는 경우. 스트레이트끼리 맞붙을 경우에는 가장 높은 카드에 의해 더 높은 패가 결정됩니다.

 

스트레이트 : 다섯 장의 카드가 연속적인 값을 가지는 경우. 스트레이트끼리 맞붙을 경우에는 가장 높은 카드에 의해 더 높은 패가 결정됩니다.

 

플러시 : 다섯 장의 카드의 무늬가 모두 같은 경우. 플러시끼리 맞붙을 경우에는 하이 카드의 규칙에 따라서 더 높은 패가 결정됩니다. 

 

풀 하우스 : 세 장의 카드가 같은 값을 가지고 나머지 두 장의 카드가 같은 값을 가지는 경우. 같은 값을 가지는 세장의 카드의 우열에 의해 더 높은 패가 결정됩니다.

 

포 카드 : 네 장의 카드가 같은 값을 가지는 경우. 포 카드끼리 맞붙는 경우에는 네 장의 같은 값을 가지는 카드의 값에 의해 더 높은 패가 결정됩니다.

 

스트레이트 플러시 : 다섯 장의 카드가 무늬가 같으면서 모두 연속적인 값을 가지는 경우. 패에 있는 것 중 가장 높은 카드에 의해서 더 높은 패가 결정됩니다.

 

포커패를 비교해서 어느 쪽이 이겼는지 아니면 무승부인지를 알아내는 프로그램을 만들어 봅시다.

 

입력

입력은 한 줄을 입력 받습니다. 이 줄에는 열 장의 카드를 나타내는 값이 들어가 있습니다.

앞에 있는 다섯 장의 카드는 "Black" 참가자의 카드고, 뒤의 카드는 "White" 참가자의 카드입니다.

 

출력

입력된 각 줄에 대해 다음 중 한가지가 들어있는 행을 출력합니다.

 

Black wins.

White wins.

Tie 

 

예제

※ 중간에 디버깅을 위해, 각 참가자의 카드를 출력하고 패의 종류를 표기하는 것을 추가했습니다.


해설

포커에 경험이 있어야 이해가 쉬울 수 있습니다. 포커에 대한 내용은 다른 사이트를 참조해보시면 좋을 것 같습니다.

처리하면서 골치아픈 중의 하나가 에이스 (A) 의 처리입니다. 에이스 (A)는 1일 수도 있고, 14를 의미할 수도 있기 때문입니다. 그리고 같은 등급의 패일 경우, 각 카드를 검색해서 더 높은 패를 가려야 하는 부분이 은근히 귀찮습니다.

# Quiz 0010, Poker Hands
# written by badsaram

import sys
import re

from enum import IntEnum

class Color(IntEnum):
    BLACK = 0
    RED = 1

class Mark(IntEnum):
    SPADE = 0
    HEART = 1
    DIAMOND = 2
    CLOVER = 3

class Hand(IntEnum):
    HIGHCARD = 0
    ONEPAIR = 1
    TWOPAIR = 2
    THREECARD = 3
    STRAIGHT = 4
    FLUSH = 5
    FULLHOUSE = 6
    FOURCARD = 7
    STFLUSH = 8
    RSTFLUSH = 9

class PokerCard(object):
    def __init__(self, strCard):
        self.convertCard(strCard)

    def getMark(self):
        return self.mark

    def getColor(self):
        return self.color

    def getNumber(self):
        return self.number

    def getPrint(self):
        print_num = ('A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K')
        print_mark = ('S', 'H', 'D', 'C')

        ret = "{num}{mark}".format(num = print_num[self.number - 1], mark = print_mark[self.mark])
        return ret

    def convertCard(self, strCard):
        tempStr = strCard.upper()

        if (re.match("[2-9]+", tempStr[0]) != None):
            self.number = int(tempStr[0])
        elif (tempStr[0] == 'T'):
            self.number = 10
        elif (tempStr[0] == 'J'):
            self.number = 11
        elif (tempStr[0] == 'Q'):
            self.number = 12
        elif (tempStr[0] == 'K'):
            self.number = 13
        elif (tempStr[0] == 'A'):
            self.number = 1
        else:
            pass

        if (tempStr[1]) == 'S':
            self.mark = Mark.SPADE
            self.color = Color.BLACK
        elif (tempStr[1]) == 'H':
            self.mark = Mark.HEART
            self.color = Color.RED
        elif (tempStr[1]) == 'D':
            self.mark = Mark.DIAMOND
            self.color = Color.RED
        else:
            self.mark = Mark.CLOVER
            self.color = Color.BLACK

class PokerHands(object):
    def __init__(self):
        self.card1 = []
        self.card2 = []

    def input(self):
        str = input()

        # The order of black and white are changed
        str_cards = str.split(' ')

        if (len(str_cards) == 10):
            self.card2.append(PokerCard(str_cards[0]))
            self.card2.append(PokerCard(str_cards[1]))
            self.card2.append(PokerCard(str_cards[2]))
            self.card2.append(PokerCard(str_cards[3]))
            self.card2.append(PokerCard(str_cards[4]))

            self.card1.append(PokerCard(str_cards[5]))
            self.card1.append(PokerCard(str_cards[6]))
            self.card1.append(PokerCard(str_cards[7]))
            self.card1.append(PokerCard(str_cards[8]))
            self.card1.append(PokerCard(str_cards[9]))
        else:
            pass

    def run(self):
        if ((len(self.card1) != 5) or (len(self.card2) != 5)):
            print("Error")
            return

        white_rank = self.checkHandRanking(self.card1)
        black_rank = self.checkHandRanking(self.card2)

        self.printHands(self.card1, "White", white_rank)
        self.printHands(self.card2, "Black", black_rank)

        if (white_rank > black_rank):
            print("White wins.")
        elif (white_rank < black_rank):
            print("Black wins.")
        else:
            if (white_rank == Hand.RSTFLUSH):
                ret = 0
            elif (white_rank == Hand.STFLUSH):
                ret = self.checkTieForStFlush(self.card1, self.card2)
            elif (white_rank == Hand.FOURCARD):
                ret = self.checkTieForFourCard(self.card1, self.card2)
            elif (white_rank == Hand.FULLHOUSE):
                ret = self.checkTieForFullHouse(self.card1, self.card2)
            elif (white_rank == Hand.FLUSH):
                ret = self.checkTieForFlush(self.card1, self.card2)
            elif (white_rank == Hand.STRAIGHT):
                ret = self.checkTieForStraight(self.card1, self.card2)
            elif (white_rank == Hand.THREECARD):
                ret = self.checkTieForThreeCard(self.card1, self.card2)
            elif (white_rank == Hand.TWOPAIR):
                ret = self.checkTieForTwoPair(self.card1, self.card2)
            elif (white_rank == Hand.ONEPAIR):
                ret = self.checkTieForOnePair(self.card1, self.card2)
            else:
                ret = self.checkTieForHighCard(self.card1, self.card2)

            if (ret > 0):
                print("White wins")
            elif (ret < 0):
                print("Black wins")
            else:
                print("Tie.")

    def getRankPrint(self, rank):
        print_rank = ("High Card", "One Pair", "Two Pair", "Three Card", "Straight", "Flush", "Full House", \
                      "Four Card", "Straight Flush", "Royal Straight Flush")

        return print_rank[rank]

    def printHands(self, hands, prompt, rank):
        print("%s : %s %s %s %s %s -> %s" % (prompt, hands[0].getPrint(), hands[1].getPrint(), hands[2].getPrint(), \
                                    hands[3].getPrint(), hands[4].getPrint(), self.getRankPrint(rank)))

    def getNumArray(self, hands):
        ret = []

        for hand in hands:
            ret.append(hand.getNumber())

        return ret

    def checkHandRanking(self, hands):
        rank = Hand.HIGHCARD

        if (self.isRstFlush(hands) == True):
            rank = Hand.RSTFLUSH
        elif (self.isStFlush(hands) == True):
            rank = Hand.STFLUSH
        elif (self.isFourCard(hands) == True):
            rank = Hand.FOURCARD
        elif (self.isFullHouse(hands) == True):
            rank = Hand.FULLHOUSE
        elif (self.isFlush(hands) == True):
            rank = Hand.FLUSH
        elif (self.isStraight(hands) == True):
            rank = Hand.STRAIGHT
        elif (self.isThreeCard(hands) == True):
            rank = Hand.THREECARD
        elif (self.isTwoPair(hands) == True):
            rank = Hand.TWOPAIR
        elif (self.isOnePair(hands) == True):
            rank = Hand.ONEPAIR
        else:
            rank = Hand.HIGHCARD

        return rank

    def isRstFlush(self, hands):
        ret = False

        if (self.isStFlush(hands) == True):
            num_array = self.getNumArray(hands)
            num_array.sort()
            if ((num_array[0] == 1) and (num_array[1] == 10)):
                ret = True

        return ret

    def isStFlush(self, hands):
        ret = False

        if ((self.isFlush(hands) == True) and (self.isStraight(hands) == True)):
            ret = True

        return ret

    def isFourCard(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if ((4 in check_array) == True):
            ret = True

        return ret

    def isFullHouse(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if ((check_array.count(3) == 1) and (check_array.count(2) == 1)):
            ret = True

        return ret

    def isFlush(self, hands):
        ret = True

        check_mark = hands[0].getMark()
        for hand in hands:
            if (hand.getMark() != check_mark):
                ret = False

        return ret

    def isStraight(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if (check_array.count(1) != 5):
            ret = False
        else:
            num_array = self.getNumArray(hands)
            num_array.sort()
            if ((num_array[4] - num_array[0]) == 4):
                ret = True
            elif ((num_array[0] == 1) and (num_array[1] == 10)):
                ret = True
            else:
                pass

        return ret

    def isThreeCard(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if ((3 in check_array) == True) and (2 not in check_array):
            ret = True

        return ret

    def isTwoPair(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if (check_array.count(2) == 2):
            ret = True

        return ret

    def isOnePair(self, hands):
        ret = False

        check_array = [ 0 for i in range(13) ]
        for hand in hands:
            check_array[hand.getNumber() - 1] += 1

        if ((check_array.count(2) == 1) and (3 not in check_array)):
            ret = True

        return ret

    def checkTieForRstFlush(self, hands1, hands2):
        ret = 0

        return ret

    def checkTieForStFlush(self, hands1, hands2):
        ret = self.checkTieForHighCard()

        return ret

    def checkTieForFourCard(self, hands1, hands2):
        ret = 0

        paircard1 = 0
        paircard2 = 0

        check_array1 = [ 0 for i in range(13) ]
        for hand1 in hands1:
            check_array1[hand1.getNumber() - 1] += 1
            if (check_array1[hand1.getNumber() - 1] >= 4):
                paircard1 = hand1.getNumber()

        check_array2 = [ 0 for i in range(13) ]
        for hand2 in hands2:
            check_array2[hand2.getNumber() - 1] += 1
            if (check_array2[hand2.getNumber() - 1] >= 4):
                paircard2 = hand2.getNumber()

        if (paircard1 != paircard2):
            if (paircard1 == 1):
                paircard1 = 14
            if (paircard2 == 1):
                paircard2 = 14

            if (paircard1 > paircard2):
                ret = 1
            else:
                ret = -1
        else:
            num_array1 = self.getNumArray(hands1)
            num_array2 = self.getNumArray(hands2)

            num_array1.sort()
            num_array2.sort()

            if ((1 in num_array1) and (1 not in num_array2)):
                ret = 1
            elif ((1 not in num_array1) and (1 in num_array2)):
                ret = -1
            else:
                for i in range(4, 0, -1):
                    if (num_array1[i] > num_array2[i]):
                        ret = 1
                        break
                    elif (num_array1[i] < num_array2[i]):
                        ret = -1
                        break

        return ret

    def checkTieForFullHouse(self, hands1, hands2):
        ret = 0

        paircard1_3 = 0
        paircard1_2 = 0
        paircard2_3 = 0
        paircard2_1 = 0

        check_array1 = [ 0 for i in range(13) ]
        for hand1 in hands1:
            check_array1[hand1.getNumber() - 1] += 1

        check_array2 = [ 0 for i in range(13) ]
        for hand2 in hands2:
            check_array2[hand2.getNumber() - 1] += 1

        for i in range(13):
            if (check_array1[i] >= 3):
                if (i == 1):
                    paircard1_3 = 14
                else:
                    paircard1_3 = i
            elif (check_array1[i] >= 2):
                if (i == 1):
                    paircard1_2 = 14
                else:
                    paircard1_2 = i
            else:
                pass

            if (check_array2[i] >= 3):
                if (i == 1):
                    paircard2_3 = 14
                else:
                    paircard2_3 = i
            elif (check_array2[i] >= 2):
                if (i == 1):
                    paircard2_2 = 14
                else:
                    paircard2_2 = i
            else:
                pass

        if (paircard1_3 > paircard2_3):
            ret = -1
        elif (paircard1_3 < paircard2_3):
            ret = 1
        else:
            if (paircard1_2 > paircard2_2):
                ret = -1
            elif (paircard1_2 < paircard2_2):
                ret = 1
            else:
                ret = 0

        return ret

    def checkTieForFlush(self, hands1, hands2):
        ret = self.checkTieForHighCard(hands1, hands2)

        return ret

    def checkTieForStraight(self, hands1, hands2):
        ret = self.checkTieForHighCard(hands1, hands2)

        return ret

    def checkTieForThreeCard(self, hands1, hands2):
        ret = 0

        paircard1 = 0
        paircard2 = 0

        check_array1 = [ 0 for i in range(13) ]
        for hand1 in hands1:
            check_array1[hand1.getNumber() - 1] += 1
            if (check_array1[hand1.getNumber() - 1] >= 3):
                paircard1 = hand1.getNumber()

        check_array2 = [ 0 for i in range(13) ]
        for hand2 in hands2:
            check_array2[hand2.getNumber() - 1] += 1
            if (check_array2[hand2.getNumber() - 1] >= 3):
                paircard2 = hand2.getNumber()

        if (paircard1 != paircard2):
            if (paircard1 == 1):
                paircard1 = 14
            if (paircard2 == 1):
                paircard2 = 14

            if (paircard1 > paircard2):
                ret = 1
            else:
                ret = -1
        else:
            num_array1 = self.getNumArray(hands1)
            num_array2 = self.getNumArray(hands2)

            num_array1.sort()
            num_array2.sort()

            if ((1 in num_array1) and (1 not in num_array2)):
                ret = 1
            elif ((1 not in num_array1) and (1 in num_array2)):
                ret = -1
            else:
                for i in range(4, 0, -1):
                    if (num_array1[i] > num_array2[i]):
                        ret = 1
                        break
                    elif (num_array1[i] < num_array2[i]):
                        ret = -1
                        break

        return ret

    def checkTieForTwoPair(self, hands1, hands2):
        ret = 0

        paircard1 = []
        paircard2 = []

        check_array1 = [ 0 for i in range(13) ]
        for hand1 in hands1:
            check_array1[hand1.getNumber() - 1] += 1
            if (check_array1[hand1.getNumber() - 1] >= 2):
                paircard1.append(hand1.getNumber())

        check_array2 = [ 0 for i in range(13) ]
        for hand2 in hands2:
            check_array2[hand2.getNumber() - 1] += 1
            if (check_array2[hand2.getNumber() - 1] >= 2):
                paircard2.append(hand2.getNumber())

        if ((1 in paircard1) and (1 not in paircard2)):
            ret = 1
        elif ((1 not in paircard1) and (1 in paircard2)):
            ret = -1
        else:
            num_array1 = self.getNumArray(hands1)
            num_array2 = self.getNumArray(hands2)

            num_array1.sort()
            num_array2.sort()

            if ((1 in num_array1) and (1 not in num_array2)):
                ret = 1
            elif ((1 not in num_array1) and (1 in num_array2)):
                ret = -1
            else:
                for i in range(4, 0, -1):
                    if (num_array1[i] > num_array2[i]):
                        ret = 1
                        break
                    elif (num_array1[i] < num_array2[i]):
                        ret = -1
                        break

        return ret

    def checkTieForOnePair(self, hands1, hands2):
        ret = 0

        paircard1 = 0
        paircard2 = 0

        check_array1 = [ 0 for i in range(13) ]
        for hand1 in hands1:
            check_array1[hand1.getNumber() - 1] += 1
            if (check_array1[hand1.getNumber() - 1] >= 2):
                paircard1 = hand1.getNumber()

        check_array2 = [ 0 for i in range(13) ]
        for hand2 in hands2:
            check_array2[hand2.getNumber() - 1] += 1
            if (check_array2[hand2.getNumber() - 1] >= 2):
                paircard2 = hand2.getNumber()

        if (paircard1 != paircard2):
            if (paircard1 == 1):
                paircard1 = 14
            if (paircard2 == 1):
                paircard2 = 14

            if (paircard1 > paircard2):
                ret = 1
            else:
                ret = -1
        else:
            num_array1 = self.getNumArray(hands1)
            num_array2 = self.getNumArray(hands2)

            num_array1.sort()
            num_array2.sort()

            if ((1 in num_array1) and (1 not in num_array2)):
                ret = 1
            elif ((1 not in num_array1) and (1 in num_array2)):
                ret = -1
            else:
                for i in range(4, 0, -1):
                    if (num_array1[i] > num_array2[i]):
                        ret = 1
                        break
                    elif (num_array1[i] < num_array2[i]):
                        ret = -1
                        break

        return ret

    def checkTieForHighCard(self, hands1, hands2):
        ret = 0

        num_array1 = self.getNumArray(hands1)
        num_array2 = self.getNumArray(hands2)

        num_array1.sort()
        num_array2.sort()

        if ((1 in num_array1) and (1 not in num_array2)):
            ret = 1
        elif ((1 not in num_array1) and (1 in num_array2)):
            ret = -1
        else:
            for i in range(4, 0, -1):
                if (num_array1[i] > num_array2[i]):
                    ret = 1
                    break
                elif (num_array1[i] < num_array2[i]):
                    ret = -1
                    break

        return ret

    def makePattern1(self):
        self.card1.append(PokerCard("AS"))
        self.card1.append(PokerCard("2S"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("4S"))
        self.card1.append(PokerCard("5S"))

        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("2C"))
        self.card2.append(PokerCard("3D"))
        self.card2.append(PokerCard("4C"))
        self.card2.append(PokerCard("5H"))

    def makePattern2(self):
        self.card1.append(PokerCard("AS"))
        self.card1.append(PokerCard("KS"))
        self.card1.append(PokerCard("TS"))
        self.card1.append(PokerCard("QS"))
        self.card1.append(PokerCard("JS"))

        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("2C"))
        self.card2.append(PokerCard("3D"))
        self.card2.append(PokerCard("4C"))
        self.card2.append(PokerCard("5H"))

    def makePattern3(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("2S"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("4S"))
        self.card1.append(PokerCard("5S"))

        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("2C"))
        self.card2.append(PokerCard("3D"))
        self.card2.append(PokerCard("4C"))
        self.card2.append(PokerCard("5H"))

    def makePatternTieHighcard(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("5S"))
        self.card1.append(PokerCard("7S"))
        self.card1.append(PokerCard("9S"))

        self.card2.append(PokerCard("2D"))
        self.card2.append(PokerCard("4C"))
        self.card2.append(PokerCard("6D"))
        self.card2.append(PokerCard("8C"))
        self.card2.append(PokerCard("9H"))

    def makePatternTieOnePair(self):
        self.card1.append(PokerCard("2C"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("5S"))
        self.card1.append(PokerCard("AD"))
        self.card1.append(PokerCard("AS"))

        self.card2.append(PokerCard("2D"))
        self.card2.append(PokerCard("4C"))
        self.card2.append(PokerCard("6D"))
        self.card2.append(PokerCard("9C"))
        self.card2.append(PokerCard("9H"))

    def makePatternTieTwoPair(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("3H"))
        self.card1.append(PokerCard("6D"))
        self.card1.append(PokerCard("6S"))

        self.card2.append(PokerCard("2D"))
        self.card2.append(PokerCard("3C"))
        self.card2.append(PokerCard("3D"))
        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("AH"))

    def makePatternTieThreeCard(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("3S"))
        self.card1.append(PokerCard("6H"))
        self.card1.append(PokerCard("6D"))
        self.card1.append(PokerCard("6S"))

        self.card2.append(PokerCard("2D"))
        self.card2.append(PokerCard("3C"))
        self.card2.append(PokerCard("AS"))
        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("AH"))

    def makePatternTieStraight(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("2S"))
        self.card1.append(PokerCard("3H"))
        self.card1.append(PokerCard("4D"))
        self.card1.append(PokerCard("5S"))

        self.card2.append(PokerCard("9D"))
        self.card2.append(PokerCard("KC"))
        self.card2.append(PokerCard("QS"))
        self.card2.append(PokerCard("JD"))
        self.card2.append(PokerCard("TH"))

    def makePatternTieFlush(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("2C"))
        self.card1.append(PokerCard("3C"))
        self.card1.append(PokerCard("4C"))
        self.card1.append(PokerCard("6C"))

        self.card2.append(PokerCard("AD"))
        self.card2.append(PokerCard("KD"))
        self.card2.append(PokerCard("QD"))
        self.card2.append(PokerCard("JD"))
        self.card2.append(PokerCard("9D"))

    def makePatternTieFullHouse(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("AH"))
        self.card1.append(PokerCard("AS"))
        self.card1.append(PokerCard("3D"))
        self.card1.append(PokerCard("3C"))

        self.card2.append(PokerCard("KD"))
        self.card2.append(PokerCard("KS"))
        self.card2.append(PokerCard("KH"))
        self.card2.append(PokerCard("QC"))
        self.card2.append(PokerCard("QD"))

    def makePatternTieFourCard(self):
        self.card1.append(PokerCard("AC"))
        self.card1.append(PokerCard("AH"))
        self.card1.append(PokerCard("AS"))
        self.card1.append(PokerCard("AD"))
        self.card1.append(PokerCard("6C"))

        self.card2.append(PokerCard("KD"))
        self.card2.append(PokerCard("KS"))
        self.card2.append(PokerCard("KH"))
        self.card2.append(PokerCard("KC"))
        self.card2.append(PokerCard("9D"))

if __name__ == '__main__':
    obj = PokerHands()

    obj.input()
    #obj.makePattern1()
    #obj.makePattern2()
    #obj.makePattern3()
    #obj.makePatternTieHighcard()
    #obj.makePatternTieOnePair()
    #obj.makePatternTieTwoPair()
    #obj.makePatternTieThreeCard()
    #obj.makePatternTieStraight()
    #obj.makePatternTieFlush()
    #obj.makePatternTieFullHouse()
    #obj.makePatternTieFourCard()

    obj.run()

n개의 정수(n > 0) 으로 이루어진 수열에 대해 서로 인접해 있는 두 수의 차가 1에서 (n - 1)까지의 값을 모두 가지면 그 수열을 유쾌한 점퍼라고 부른다. 예를 들어 다음과 같은 수열에서

 

1 4 2 3 

 

앞뒤에 있는 숫자 차의 절대 값이 각각 3, 2, 1 이므로 이 수열은 유쾌한 점퍼가 된다. 어떤 수열이 유쾌한 점퍼인지 판단할 수 있는 프로그램을 작성하라.

 

입력

수열을 나타내는 n 개의 정수가 입력 된다. 

 

출력

입력된 수열에 대해  "Jolly" 또는 "Not jolly"를 한 줄씩 출력한다.

 

예제

1 4 2 3  → Jolly

1 4 2 -1 6  → Not jolly


해설

한 줄을 입력 받아서 split() 함수를 통해 각 수를 분리해낸다. 이제 각 수를 분리해서 list에 넣으면 된다.

list를 하나씩 검색하면서 앞뒤 숫자의 차를 구한 후, (n - 1) 까지의 수가 모두 있는지 검사하면 된다.

# Quiz 0009 , Jolly Jumpers
# written by badsaram

import sys

class JollyJumpers(object):
    def __init__(self):
        self.sequence = []
        self.gap = []

    def input(self):
        input_valid = False
        self.sequence = []
        self.gap = []

        str = input()

        tokens = str.split(' ')
        for token in tokens:
            if (token.lstrip('-').isdigit() == True):
                self.sequence.append(int(token))
                input_valid = True
            else:
                break

        print(self.sequence)

        if (input_valid == True):
            for i in range(0, len(self.sequence) - 1):
                self.gap.append(abs(self.sequence[i] - self.sequence[i + 1]))
        else:
            self.sequence = []
            print("There is invalid digit. Please input again")

        print(self.gap)

    def check(self):
        isjolly = True

        for i in range(0, len(self.sequence) - 1):
            try:
                self.sequence.index(i + 1)
            except:
                isjolly = False

        if (len(self.sequence) == 0):
            pass
        elif (isjolly == True):
            print("Jolly")
        else:
            print("Not jolly")

if __name__ == '__main__':
    obj = JollyJumpers()

    obj.input()
    obj.check()

호주(오스트레일리아) 에서는 투표를 할 때, 모든 후보에 대해서 선호도 순으로 투표를 한다고 합니다.

 

처음에는 1순위로 선택한 것만 집계를 먼저하고, 이 중 한 후보가 50% 이상 득표하면 그 후보가 바로 선출됩니다. 하지만 50% 이상 득표한 후보가 없으면 가장 적은 표를 받은 후보(둘 이상이 될 수 있음)가 우선 탈락합니다. 그리고 이렇게 탈락한 후보를 1순위로 찍었던 표만 다시 집계해서 아직 탈락하지 않은 후보들 가운데 가장 높은 선호를 얻는 후보가 그 표를 얻게 됩니다.

 

이런 식으로 가장 약한 후보들을 탈락시키면서, 그 다음 순위의 아직 탈락하지 않은 후보에게 표를 주는 과정을 50% 이상의 표를 얻는 후보가 나오거나 탈락되지 않는 후보가 동률이 될때까지 반복한다.

 

입력

첫 입력은 후보 수를 나타내는 20 이하의 정수 n이 입력된다. 그 밑으로 n개의 줄에 걸쳐서 후보의 이름이 순서대로 입력되며 각 후보의 이름은 80글자 이하로 출력 가능한 문자로 구성된다.

 

그 뒤에는 최대 1,000줄이 입력될 수 있는데, 각 줄에는 투표 내역이 입력된다. 각 투표 내역에는 어떤 순서로 1부터 n까지의 수가 입력된다. 첫번째 숫자는 1순위로 찍은 후보의 번호, 두번째 숫자는 2순위로 찍은 후보의 번호, 이런 식으로 숫자가 기록된다.

 

출력

각 테스트 케이스에 대해 당선된 후보의 이름 한 줄, 또는 동률을 이룬 후보들의 이름이 들어있는 여러줄을 출력한다. 두 개 이상의 테스트 케이스가 있는 경우 각 결과는 한 개의 빈줄로 구분한다.

 

예제


해설

문제는 단순한데 구현하면서 꽤 골치가 아팠던 문제입니다.

처음 투표 평가하고, 탈락자 선별 이후에 다시 재귀적으로 처리하는 부분에서 깔끔하게 구현하려고 고민 좀 했습니다.

# AusVote.py , 0008 quiz
# written by badsaram

import sys

class AusVote(object):
    def __init__(self):
        self.info_candidates = []
        self.info_votes = []
        self.info_scores = []

        self.max_candidates = 20
        self.max_namelen = 80
        self.max_votes = 1000

    def inputCases(self):
        max_candidates = 0

        # input candidates
        str = input()
        if (str.isdigit() == False):
            print("Please input number.")
            sys.exit(-1)

        max_candidates = int(str)
        if ((max_candidates > self.max_candidates) or (max_candidates < 0)):
            print("number of candidates : (0 < n <= 20)")
            sys.exit(-1)

        for i in range(max_candidates):
            str = input()
            if (len(str) > self.max_namelen):
                print("name is too long. The size of name is under %d" % (self.max_namelen))
                sys.exit(-1)

            self.info_candidates.append(str)
            self.info_scores.append(0)

        for i in range(self.max_votes):
            str = input()
            if (str == ""):
                break

            str_votes = str.split(' ')
            if (len(str_votes) != max_candidates):
                print("please input votes correctly")
                sys.exit(-1)

            int_votes = []
            for str_vote in str_votes:
                if (str_vote.isdigit() == False):
                    print("plese input number")
                    sys.exit(-1)

                int_votes.append(int(str_vote))

            self.info_votes.append(int_votes)

    def calcVotes(self):
        isFinished = False

        if (len(self.info_votes) <= 0):
            return

        for each_vote in self.info_votes:
            target = self.findVotes(each_vote, 1)
            self.info_scores[target] += 1

        while (isFinished == False):
            if (self.checkAllSame(self.info_scores) == True):
                isFinished = True
            elif ( max(self.info_scores) >= (len(self.info_votes) / 2) ):
                isFinished = True
            else:
                # drop out loser
                target = self.findMin(self.info_scores)
                losers = self.findLosers(self.info_scores, target)
                self.recalcScore(losers, self.info_votes)

        if (isFinished == True):
            target = max(self.info_scores)
            winners = self.findWinners(self.info_scores, target)
            for winner_name_index in winners:
                print("%s " % (self.info_candidates[winner_name_index]))

    def checkAllSame(self, scores):
        ret = True
        target = scores[0]

        for score in scores:
            if (target != score):
                ret = False
                break

        return ret

    def findMin(self, scores):
        minScore = -1

        for score in scores:
            if (score >= 0):
                if (minScore == -1):
                    minScore = score
                elif (score < minScore):
                    minScore = score
                else:
                    pass

        return minScore

    def findVotes(self, info_votes, rank):
        ret = -1

        for i in range(0, len(info_votes) - 1):
            if (info_votes[i] == rank):
                ret = i
                break

        return ret

    def findLosers(self, scores, min_score):
        ret = []

        for i in range(0, len(scores)):
            if (scores[i] == min_score):
                ret.append(i)

        return ret

    def findWinners(self, scores, max_score):
        ret = []

        for i in range(0, len(scores)):
            if (scores[i] == max_score):
                ret.append(i)

        return ret

    def recalcScore(self, losers, info_votes):
        for each_vote in info_votes:
            for loser_num in losers:
                if (each_vote[loser_num] == 1):
                    target = self.findVotes(each_vote, 2)
                    self.info_scores[target] += 1

        for loser_num in losers:
            self.info_scores[loser_num] = -1

    def makeTestPattern1(self):
        self.info_candidates.append('John Doe')
        self.info_candidates.append('Jane Smith')
        self.info_candidates.append('Sirhan Sirhan')
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([2, 1, 3])
        self.info_votes.append([2, 3, 1])
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([3, 1, 2])
        self.info_scores.append(0)
        self.info_scores.append(0)
        self.info_scores.append(0)

    def makeTestPattern2(self):
        self.info_candidates.append('John Doe')
        self.info_candidates.append('Jane Smith')
        self.info_candidates.append('Sirhan Sirhan')
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([2, 1, 3])
        self.info_votes.append([2, 3, 1])
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([3, 1, 2])
        self.info_votes.append([3, 2, 1])
        self.info_scores.append(0)
        self.info_scores.append(0)
        self.info_scores.append(0)

    def makeTestPattern3(self):
        self.info_candidates.append('John Doe')
        self.info_candidates.append('Jane Smith')
        self.info_candidates.append('Sirhan Sirhan')
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([2, 1, 3])
        self.info_votes.append([2, 3, 1])
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([3, 1, 2])
        self.info_votes.append([3, 2, 1])
        self.info_votes.append([1, 2, 3])
        self.info_votes.append([2, 1, 3])
        self.info_votes.append([1, 2, 3])
        self.info_scores.append(0)
        self.info_scores.append(0)
        self.info_scores.append(0)

if __name__ == '__main__':
    obj = AusVote()
    obj.inputCases()
    #obj.makeTestPattern1()
    #obj.makeTestPattern2()
    #obj.makeTestPattern3()
    obj.calcVotes()

체스(Chess) 좋아하시나요? 서양식 장기 게임입니다.

체스

 

체스판 설정을 읽어서, 킹이 공격받고 있는지(체스 상태인지) 확인하는 프로그램을 만들어 봅시다. 다음 수에 의해 킹이 죽을 수 있는 위치에 있으면 킹이 체크 상태가 됩니다.

 

흰 말은 대문자로, 검은 말은 소문자로 표시됩니다. 흰 편은 항상 판의 아래쪽에, 검은 편은 판의 윗쪽에 자리잡습니다.

 

체스를 잘 모르는 사람을 위해 각 말의 이동 방법을 설명하면 다음과 같습니다.

  • 폰(Pawn, p 또는 P) : 한 번에 한 칸씩 앞으로만 갈 수 있다. 하지만 대각선에 있는 상대 말을 잡을 수 있습니다.
  • 나이트(Knight, n 또는 N) : L 자 모양으로 움직일 수 있습니다. 한칸 전진, 한칸 대각선으로 움직입니다. 다른 말을 뛰어넘을수 있는 유일한 말입니다.
  • 비숍(Bishop, b 또는 B) : 대각선 방향으로 어느 쪽으로든 이동 거리에 제한을 받지 않고 이동할 수 있습니다.
  • 록(Rock, r 또는 R) : 수직 또는 수평 방향으로 이동 거리에 제한을 받지 않고 움직일 수 있습니다.
  • 퀸(Queen, q 또는 Q) : 수직, 수평, 대각선 방향으로 어느 쪽으로든 이동 거리에 제한을 받지 않고 움직일 수 있습니다.
  • 킹(King, k 또는 K) : 수직, 수평, 대각선 방향으로 어느 쪽으로든 한 칸을 움직일 수 있습니다.

 

입력

입력에는 체스판 1개의 입력을 받습니다. 체스판의 크기는 가로 8칸, 세로 8칸입니다. 각 칸은 문자로 구성되어 있습니다. 

'.' 은 빈칸을 의미하고, 위에 정한 각 말을 의미하는 대문자 또는 소문자가 입력됩니다. 예외 처리를 간단하기 하기 위해, 틀린 문자 입력은 없고, 두 킹이 모두 체크를 당하는 배치는 입력되지 않는다고 정합니다.

 

'.' 문자만으로 구성된 비어 있는 체스판이 입력되면 처리하지 않고 프로그램을 종료합니다. 

 

출력

입력된 각 판 배치에 대해서 다음 중 한가지 답을 출력합니다.

 

white king is in check.

black king is in check.

no king is in check.

 

예제

아래처럼 8x8 체스판을 입력 받아서, 체크 여부를 출력한다.

빈 체스판이 입력되면 종료한다.


해설

체크 규칙을 잘 알고 있어야 수월한 문제이다. 폰(Pawn)의 처리가 까다롭고, 나이트(N) 이외에는 다른 기물을 넘을 수 없다는 것이 유이해야 한다.

 

전체적으로 코드가 길어지는 감이 있다. 이외에는 2차원 배열을 다루는 평이한 문제이다.

# check.py , 0007 quiz
# written by badsaram

import sys

class chess_board(object):
    def __init__(self):
        self.BOARD_WIDTH  = 8
        self.BOARD_HEIGHT = 8

        self.board = []

    def isPawn(self, cell):
        if ((cell == 'P') or (cell == 'p')):
            return True
        else:
            return False

    def isBishop(self, cell):
        if ((cell == 'B') or (cell == 'b')):
            return True
        else:
            return False

    def isRock(self, cell):
        if ((cell == 'R') or (cell == 'r')):
            return True
        else:
            return False

    def isKnight(self, cell):
        if ((cell == 'N') or (cell == 'n')):
            return True
        else:
            return False

    def isQueen(self, cell):
        if ((cell == 'Q') or (cell == 'q')):
            return True
        else:
            return False

    def isKing(self, cell):
        if ((cell == 'K') or (cell == 'k')):
            return True
        else:
            return False

    def isWhite(self, cell):
        return cell.isupper()

    def isWhiteKing(self, cell):
        ret = False
        if ( (self.isWhite(cell) == True) and (self.isKing(cell) == True) ):
            ret = True

        return ret

    def isBlack(self, cell):
        return cell.islower()

    def isBlackKing(self, cell):
        ret = False
        if ( (self.isBlack(cell) == True) and (self.isKing(cell) == True) ):
            ret = True

        return ret

    def isEmpty(self, cell):
        return (cell == '.')

    def isChecked(self, board_obj, target_obj):
        ret = 0  # 0 : empty, 1 : black in check, 2 : white in check, 3 : not empty

        if ((self.isWhite(board_obj) == True) and (self.isBlackKing(target_obj))):
            ret = 1
        elif ((self.isBlack(board_obj) == True) and (self.isWhiteKing(target_obj))):
            ret = 2
        elif (self.isEmpty(target_obj) == False):
            ret = 3

        return ret

    def getObject(self, y, x):
        return (self.board[y][x])

    # if there are not allowed object, this is error
    def inputBoard(self):
        ret = False
        inputted_row = 0
        self.board = []

        while (True):
            if (inputted_row == self.BOARD_HEIGHT):
                ret = True
                break

            str = input()
            if (self.checkInputRow(str) == True):
                inputted_row += 1
            else:
                print("Input String Error : %s" % str)
                break

            self.board.append(str)

        if (ret == True):
            if (self.checkBoardValidity() == False):
                ret = False

        return ret

    def checkInputRow(self, row_string):
        ret = False

        for ch in row_string:
            if ( (self.isEmpty(ch) == True) or (self.isPawn(ch) == True) or (self.isKnight(ch) == True) or \
                    (self.isBishop(ch) == True) or (self.isRock(ch) == True) or (self.isQueen(ch) == True) or \
                    (self.isKing(ch) == True) ):
                ret = True
            else:
                ret = False
                break

        if (len(row_string) != self.BOARD_WIDTH):
            ret = False

        return ret

    def checkBoardValidity(self):
        ret = False
        white_king_cnt = 0
        black_king_cnt = 0
        all_empty = True

        for str in self.board:
            for ch in str:
                if (self.isKing(ch) == True):
                    if (self.isWhite(ch) == True):
                        white_king_cnt += 1
                    else:
                        black_king_cnt += 1
                elif (self.isEmpty(ch) != False):
                    all_empty = False
                else:
                    pass

        if ( (all_empty == False) and (white_king_cnt == 1) and (black_king_cnt == 1) ):
            ret = True

        return ret

    def checkMove(self, board_obj, y, x):
        ret = 0        # 0 : no king in check, 1 : black king in check, 2 : white king in check
        retChecked = 0 # 0 : empty, 1 : black in check, 2 : white in check, 3 : not empty
        target_obj = '.'
        target_x = 0
        target_y = 0
        block_flg = [False, False, False, False]

        if (self.isEmpty(board_obj) == True):
            pass

        if (self.isPawn(board_obj) == True):
            if (self.isWhite(board_obj) == True):
                if ( (y - 1) >= 0 ):
                    if ( (x - 1) >= 0):
                        target_obj = self.getObject(y - 1, x - 1)
                        if ( (self.isKing(target_obj) == True) and (self.isBlack(target_obj) == True) ):
                            ret = 1

                    if ( (x + 1) < self.BOARD_WIDTH):
                        target_obj = self.getObject(y - 1, x + 1)
                        if ( (self.isKing(target_obj) == True) and (self.isBlack(target_obj) == True) ):
                            ret = 1

            else:
                if ( ( y + 1) < self.BOARD_HEIGHT):
                    if ( (x - 1) >= 0):
                        target_obj = self.getObject(y + 1, x - 1)
                        if ( (self.isKing(target_obj) == True) and (self.isWhite(target_obj) == True) ):
                            ret = 1

                    if ( (x + 1) < self.BOARD_WIDTH):
                        target_obj = self.getObject(y + 1, x + 1)
                        if ( (self.isKing(target_obj) == True) and (self.isWhite(target_obj) == True) ):
                            ret = 1

        if ( (self.isBishop(board_obj) == True) or (self.isQueen(board_obj) == True) ):
            block_flg = [False, False, False, False]

            # 4-way traverse
            for step in range(1, self.BOARD_WIDTH - 1):
                target_x = x - step
                target_y = y - step
                if ( (target_x >= 0) and (target_y >= 0) and (block_flg[0] == False) ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[0] = True
                    else:
                        pass

                target_x = x - step
                target_y = y + step
                if ( (target_x >= 0) and (target_y < self.BOARD_HEIGHT) and (block_flg[1] == False) ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[1] = True
                    else:
                        pass

                target_x = x + step
                target_y = y - step
                if ( (target_x < self.BOARD_WIDTH) and (target_y >= 0) and (block_flg[2] == False) ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[2] = True
                    else:
                        pass

                target_x = x + step
                target_y = y + step
                if ( (target_x < self.BOARD_WIDTH) and (target_y < self.BOARD_HEIGHT) and (block_flg[3] == False) ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[3] = True
                    else:
                        pass

        if ( (self.isRock(board_obj) == True) or (self.isQueen(board_obj) == True) ):
            block_flg = [False, False, False, False]

            # 4-way traverse
            for step in range(1, self.BOARD_WIDTH - 1):
                target_x = x
                target_y = y - step
                if ( target_y >= 0 ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[2] = True
                    else:
                        pass

                target_x = x
                target_y = y + step
                if ( target_y < self.BOARD_HEIGHT ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[2] = True
                    else:
                        pass

                target_x = x - step
                target_y = y
                if ( target_x >= 0 ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[2] = True
                    else:
                        pass

                target_x = x + step
                target_y = y
                if ( target_x < self.BOARD_WIDTH ):
                    target_obj = self.board[target_y][target_x]

                    retChecked = self.isChecked(board_obj, target_obj)
                    if ( (retChecked == 1) or (retChecked == 2) ):
                        ret = retChecked
                    elif (retChecked == 3):
                        block_flg[2] = True
                    else:
                        pass

        if (self.isKnight(board_obj) == True):
            target_x = x - 1
            target_y = y - 2
            if ( (target_x >= 0) and (target_y >= 0) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x - 2
            target_y = y - 1
            if ( (target_x >= 0) and (target_y >= 0) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x - 2
            target_y = y + 1
            if ( (target_x >= 0) and (target_y < self.BOARD_HEIGHT) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x - 1
            target_y = y + 2
            if ( (target_x >= 0) and (target_y < self.BOARD_HEIGHT) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x + 1
            target_y = y + 2
            if ( (target_x < self.BOARD_WIDTH) and (target_y < self.BOARD_HEIGHT) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x + 2
            target_y = y + 1
            if ( (target_x < self.BOARD_WIDTH) and (target_y < self.BOARD_HEIGHT) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x + 2
            target_y = y - 1
            if ( (target_x < self.BOARD_WIDTH) and (target_y >= 0) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

            target_x = x + 1
            target_y = y - 2
            if ( (target_x < self.BOARD_WIDTH) and (target_y >= 0) ):
                target_obj = self.board[target_y][target_x]

                retChecked = self.isChecked(board_obj, target_obj)
                if ((retChecked == 1) or (retChecked == 2)):
                    ret = retChecked
                else:
                    pass

        elif (self.isQueen(board_obj) == True):
            pass

        elif (self.isKing(board_obj) == True):
            # This can be error condition because two kings are checked mated at same time
            pass

        return ret

    def runCheckmate(self):
        ret = 0
        exit_flg = 0
        board_obj = '.'
        target_obj = '.'

        for i in range(0, self.BOARD_HEIGHT - 1):
            for j in range(0, self.BOARD_WIDTH - 1):
                board_obj = self.board[i][j]
                ret = self.checkMove(board_obj, i, j)
                if (ret != 0):
                    exit_flg = 1
                    break

            if (exit_flg == 1):
                break

        return ret

    def makeTestPattern1(self):
        self.board.append("..k.....")
        self.board.append("ppp.pppp")
        self.board.append("........")
        self.board.append(".R...B..")
        self.board.append("........")
        self.board.append("........")
        self.board.append("PPPPPPPP")
        self.board.append("K.......")

    def makeTestPattern2(self):
        self.board.append("rnbqkbnr")
        self.board.append("pppppppp")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("PPPPPPPP")
        self.board.append("RNBQKBNR")

    def makeTestPattern3(self):
        self.board.append("rnbqk.nr")
        self.board.append("ppp..ppp")
        self.board.append("....p...")
        self.board.append("...p....")
        self.board.append(".bPP....")
        self.board.append(".....N..")
        self.board.append("PP..PPPP")
        self.board.append("RNBQKB.R")

    def makeTestPattern4(self):
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")
        self.board.append("........")

if __name__ == '__main__':
    obj = chess_board()

    while (True):
        if (obj.inputBoard() == 0):
            sys.exit(0)
        #obj.makeTestPattern1()
        #obj.makeTestPattern2()
        #obj.makeTestPattern3()
        #.makeTestPattern4()
        ret = obj.runCheckmate()
        if (ret == 1):
            print("black king is in check.")
        elif (ret == 2):
            print("white king is in check.")
        else:
            print("no king is in check.")

'코딩 테스트' 카테고리의 다른 글

문제 9 : 유쾌한 점프 (Jolly Jumpers)  (0) 2022.08.05
문제 8 : 호주식 투표법  (0) 2022.08.01
문제 6 : 인터프리터(Interpreter)  (0) 2022.07.28
문제 5 : 그래픽 편집기  (0) 2022.07.27
문제 4 : LCD 디스플레이  (0) 2022.07.26

요즘 python 많이 쓰시죠? python 같은 언어를 '인터프리터 언어' 라고 부릅니다. 

컴파일을 거치치 않고 인터프리터라는 해석기가 코드를 수행해주는 방식입니다.

 

저는 게임을 좋아해서 MAME 같은 에뮬레이터로 레트로 게임도 즐기는데요

이런 에뮬레이터도 인터프리터의 한 종류라고 볼 수 있습니다.

 

이번에 구현할 프로그램은 간단한 인터프리터를 구현해 보는 것입니다.

개인적으로 흥미로운 주제였습니다. 인터프리터와 CPU의 기본 동작을 공부해볼 수 있습니다.

 

열개의 레지스터와 1,000워드 분량의 램(RAM)을 가진 컴퓨터를 가정해봅니다.

각 레지스터 또는 램 위치에는 0 이상 999 이하의 세 자리 정수가 저장됩니다.

명령어는 세 자리 정수로 인코딩되고 램에 저장됩니다.

 

각 명령어를 살펴봅니다.

명령어 설명
100  종료
2dn  d 레지스터를 n으로 설정 (0 이상 9 이하)
3dn  d 레지스터에 n 더함
4dn  d 레지스터에 n 곱함
5ds  d 레지스터를 s 레지스터의 값으로 설정
6ds  s 레지스터의 값을 d 레지스터에 더함
7ds  d 레지스터에 s 레지스터의 값을 곱함
8da  d 레지스터를 a 레지스터에 저장된 주소의 램에 들어있는 값으로 설정
9sa  a 레지스터에 저장된 주소의 램에 s 레지스터의 값을 대입
0ds  s 레지스터에 0이 들어있지 않으면 d 레지스터에 있는 위치로 이동

 

모든 레지스터의 초기 값은 000입니다. 처음으로 실행될 명령은 주소가 0인 램에 들어있습니다. 모든 결과는 값이 1,000이 넘어가면 1,000으로 나눈 나머지로 줄어듭니다.

 

입력

각 입력 케이스는 최대 1,000개의 부호가 없는 세 자리 저수로 구성되고, 그 숫자들은 0부터 시작하는 연속된 램 위치에 저장되는 내용을 나타냅니다. 값이 지정되지 않은 램 위치는 000으로 초기화 합니다.

 

출력

각 테스트 케이스마다 하나씩의 정수를 출력합니다. 출력되는 정수는 종료 명령어에 이르기까지(종료 명령어 포함) 실행된 명령어의 개수입니다. 프로그램이 종료된다고 미리 가성해도 됩니다. 케이스가 여러 개 있는 경우에는 각 출력 사이에 빈 줄을 출력합니다.

 

예제

메모리 0번지부터 쭉 명령어를 입력 받습니다. 입력을 종료할 경우 ENTER 키를 눌러서 종료합니다.


해설

크기 1000인 1차원 배열을 선언해서 RAM을 표현합니다. 크기 10인 1차원 배열도 선언해서 레지스터를 표현합니다. 이 후 입력 받은 명령어를 배열에 저장합니다.

 

현재 CPU의 실행 위치를 pc 라는 정수형 변수로 표현합니다. 현재 pc 위치의 명령어를 읽고, 이를 해석해서 명령어 정의에 맞게 실행해 줍니다. 

 

실제 CPU도 이와 비슷한 방식으로 명령어를 처리합니다. 어셈블리어(Assembly)를 공부해보시면 유사함을 느끼실 수 있을 을 것입니다.

# Interpreter.py , 0006 quiz
# written by badsaram

import sys

class Interpreter(object) :
    def __init__(self):
        self.RAM_SIZE   = 1000
        self.REG_SIZE   = 10
        self.MAX_VALUE  = 10
        self.MAX_CODING = 1000

        self.ram = [0 for i in range(self.RAM_SIZE)]
        self.reg = [0 for i in range(self.REG_SIZE)]
        self.pc = 0

    # input
    # ignore spare input
    def input(self):
        self.init()

        for i in range(self.RAM_SIZE):
            while(True):
                str = input("RAM %3d : " % i)
                if(str == ""):
                    return

                elif ((str.isdigit() == False) or (int(str) >= 1000)):
                    print("Error : please input valid ram data (ram data <= 1000")
                    continue
                else:
                    self.ram[i] = int(str)
                    break

    # run
    def run(self):
        self.pc = 0

        step = 0

        try :
            while (True):
                step += 1

                ram_data = self.ram[self.pc]

                cmd  = int(ram_data / 100)
                arg1 = int(ram_data / 10) % 10
                arg2 = (ram_data % 10)

                #print("PC : %d, cmd : %d, arg1 : %d, arg2 : %d" % (self.pc, cmd, arg1, arg2))

                # in quiz, only 100 means 'exit'. but I allow 1XX is also 'exit'
                if (cmd == 1):
                    print("step : %d" % step)
                    self.exit()

                # set
                if (cmd == 2):
                    self.set(arg1, arg2)

                # add
                if (cmd == 3):
                    self.add(arg1, arg2)

                # mul
                if (cmd == 4):
                    self.mul(arg1, arg2)

                # seti
                if (cmd == 5):
                    self.load(arg1, arg2)

                # addi
                if (cmd == 6):
                    self.addi(arg1, arg2)

                # muli
                if (cmd == 7):
                    self.muli(arg1, arg2)

                # loadi
                if (cmd == 8):
                    self.loadi(arg1, arg2)

                # storei
                if (cmd == 9):
                    self.storei(arg1, arg2)

                # jumpz
                if (cmd == 0):
                    self.jumpz(arg1, arg2)

        except Exception as e:
            print("Exception : ", str(e))

    # init
    def init(self):
        for i in range(self.RAM_SIZE):
            self.ram[i] = 0

        for i in range(self.REG_SIZE):
            self.reg[i] = 0

        self.pc = 0

    # exit
    def exit(self):
        sys.exit()

    # set
    def set(self, d, n):
        if ((self.isValidREG(d) == False) or (self.isValidValue(n) == False)):
            return False

        self.reg[d] = n
        self.pc += 1

        return True

    # add
    def add(self, d, n):
        if ((self.isValidREG(d) == False) or (self.isValidValue(n) == False)):
            return False

        self.reg[d] += n
        if (self.reg[d] >= self.MAX_CODING):
            self.reg[d] %= self.MAX_CODING

        self.pc += 1

        return True

    # mul
    def mul(self, d, n):
        if ((self.isValidREG(d) == False) or (self.isValidValue(n) == False)):
            return False

        self.reg[d] *= n
        if (self.reg[d] >= self.MAX_CODING):
            self.reg[d] %= self.MAX_CODING

        self.pc += 1

        return True

    # load
    def load(self, d, s):
        if ((self.isValidREG(d) == False) or (self.isValidREG(s) == False)):
            return False

        self.reg[d] = self.reg[s]
        self.pc += 1

        return True

    # addi
    def addi(self, d, s):
        if ((self.isValidREG(d) == False) or (self.isValidREG(s) == False)):
            return False

        self.reg[d] += self.reg[s]
        if (self.reg[d] >= self.MAX_CODING):
            self.reg[d] %= self.MAX_CODING

        self.pc += 1

        return True

    # muli
    def muli(self, d, s):
        if ((self.isValidREG(d) == False) or (self.isValidREG(s) == False)):
            return False

        self.reg[d] *= self.reg[s]
        if (self.reg[d] >= self.MAX_CODING):
            self.reg[d] %= self.MAX_CODING

        self.pc += 1

        return True

    # loadi
    def loadi(self, d, a):
        if ((self.isValidREG(d) == False) or (self.isValidREG(a) == False)):
            return False

        self.reg[d] = self.ram[self.reg[a]]
        self.pc += 1

        return True

    # storei
    def storei(self, s, a):
        if ((self.isValidREG(s) == False) or (self.isValidREG(a) == False)):
            return False

        self.ram[self.reg[a]] = self.reg[s]
        self.pc += 1

        return True

    # jumpz
    def jumpz(self, d, s):
        if ((self.isValidREG(d) == False) or (self.isValidREG(s) == False)):
            return False

        if (self.reg[s] != 0):
            self.pc = self.reg[d]
        else:
            self.pc += 1

        return True

    # check valid ram address
    def isValidRAM(self, ram_addr):
        if ((ram_addr >= 0) and (ram_addr < self.RAM_SIZE)):
            return True
        else:
            return False

    # check valid reg address
    def isValidREG(self, reg_addr):
        if ((reg_addr >= 0) and (reg_addr < self.REG_SIZE)):
            return True
        else:
            return False

    # check valid value
    def isValidValue(self, value):
        if ((value >= 0) and (value < self.MAX_VALUE)):
            return True
        else:
            return False

    # test case 1
    def makeManualTestCase1(self):
        self.init()

        self.ram[0] = 299
        self.ram[1] = 492
        self.ram[2] = 495
        self.ram[3] = 399
        self.ram[4] = 492
        self.ram[5] = 495
        self.ram[6] = 399
        self.ram[7] = 283
        self.ram[8] = 279
        self.ram[9] = 689
        self.ram[10] = 78
        self.ram[11] = 100
        self.ram[12] = 0
        self.ram[13] = 0
        self.ram[14] = 0

if __name__ == "__main__":
    obj = Interpreter()
    obj.input()
    #obj.makeManualTestCase1()
    obj.run()

'코딩 테스트' 카테고리의 다른 글

문제 8 : 호주식 투표법  (0) 2022.08.01
문제 7 : 체크 확인 (Check the Check)  (0) 2022.07.29
문제 5 : 그래픽 편집기  (0) 2022.07.27
문제 4 : LCD 디스플레이  (0) 2022.07.26
문제 3 : 여행 경비 계산  (0) 2022.07.20

포토샵 같은 그래픽 편집기를 이용하면, 이미지를 수정할 수 있습니다.

이미지 캔버스는 M x N 크기의 배열로 표현되며, 각 픽셀마다 색이 주어집니다.

 

간단한 대화형 그래픽 편집기를 흉내 내는 프로그램을 만들어 봅시다.

 

입력

입력은 한 줄에 하나씩의 그래픽 편집기 명령으로 구성됩니다.

각 명령은 줄 맨 앞에 있는 대문자 한개로 표현된다. 매개 변수가 필요한 경우에는 그 명령과 같은 줄에 스페이스로 분리되어 매개변수가 입력됩니다.

 

픽셀 좌표는 1 이상 M 이하의 열 번호와 1 이상 N 이하의 행 번호, 이렇게 두 개의 정수로 표현됩니다.

이 때 1 ≤ M, N ≤ 250 의 범위를 가집니다. 좌표 (0, 0)은 2차원 배열의 왼쪽 위입니다. 사용하는 문자는 모두 대문자를 사용합니다. 

 

명령의 형식은 다음과 같습니다.

명령 설명
I M N 모든 픽셀이 흰색(O)으로 칠해진 M x N 이미지를 새로 만든다. 
C 모든 픽셀을 흰색(O)으로 칠해서 표를 지운다. 이미지의 크기는 바뀌지 않는다.
L X Y C (X, Y) 픽셀을 주어진 색(C) 로 칠한다.
V X Y1 Y2 C X 열에 Y1 행과 Y2 행(Y1, Y2 포함) 사이에 주어진 색(C)으로 수직 방향 직선을 긋는다.
H X1 X2 Y C Y 행에 X1 열과 X2 열(X1, X2 포함) 사이에 주어진 색(C)으로 수평 방향 직선을 긋는다.
K X1 Y1 X2 Y2 C 주어진 색(C)으로 채워진 직사각형을 그린다. (X1, Y1)은 왼쪽 위 끝점, (X2, Y2)는 오른쪽 아래 끝 점을 의미한다.
F X Y C R 영역을 주어진 색(C)으로 채우는데, 영역 R은 다음과 같이 정의한다. (X, Y) 픽셀은 R에 속한다. (X, Y) 픽셀과 색이 같고 R에 포함된 픽셀과 맞닿은 부분이 하나라도 있다면 그 픽셀도 R 영역에 포함된다.
S Name 파일명을 MSDOS 8.3 형식으로 출력하고, 그 뒤에 현재 이미지의 내용을 출력한다.
X 세션을 종료한다.

 

출력

S NAME 이라는 명령이 있을 때마다 NAME으로 주어진 파일명을 출력하고 현재 이미지의 내용을 출력한다. 각 행은 각 픽셀의 색을 나타내는 문자로 표시됩니다. 출력 예를 참고해주세요.

I, C, L, V, H, K, F, S, X를 제외한 문자로 정의된 명령이 있으면 그 줄 전체를 무시하고 다음 명령으로 넘어간다. 다른 오류에 대해서는 프로그램의 행동을 예측할 수 없습니다. 

 

예제

※ 중간에 "G 2 3 J" 는 없는 명령어입니다. 출력 부분에 정의되지 않는 명령어는 무시하라고 되어 있습니다. 


해설

2차원 배열을 다루는 문제입니다. 

이 중 제법 난이도가 있는 것은 'F' 채우기 명령입니다. 그 외에는 평이한 수준입니다.

다만 입력의 자유도가 있다보니, 틀린 입력을 처리하는 예외 처리문 때문에 코드가 좀 지저분해집니다.

# GEditor.py , 0005 quiz
# written by badsaram

import sys

class GEditor(object):
    def __init__(self):
        self.canvas = []
        self.width  = 0
        self.height = 0

    def inputCommand(self):
        str = input()
        arr = str.split(' ')

        if (len(arr) == 0):
            print("Error : Input Command")

        # command options over the specification is just ignored
        if (arr[0] == 'X'):
            # exit
            sys.exit()

        elif (arr[0] == 'I'):
            # create canvas
            if ((len(arr) < 3) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False)):
                print("Error : I M N, (1 <= M, N <= 250)")
            else:
                temp_width = int(arr[1])
                temp_height = int(arr[2])

                if ((temp_width < 0) or (temp_width > 250) or (temp_height < 0) or (temp_height > 250)):
                    print("Error : I M N, (1 <= M, N <= 250)")
                else:
                    self.createCanvas(temp_width, temp_height)

        elif (arr[0] == 'C'):
            # in case of 'C', ignore other options
            self.clearCanvas()

        elif (arr[0] == 'L'):
            # put pixel
            if ((len(arr) < 4) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False) or (arr[3].isalpha() == False)):
                print("Error : L X Y C, X & Y is a number, C is a character")
            else:
                temp_x = int(arr[1])
                temp_y = int(arr[2])

                if ((temp_x < 0) or (temp_x > self.width) or (temp_y < 0) or (temp_y > self.height)):
                    print("Error : X, Y are smaller than canvas size")
                else:
                    self.putPixel(temp_x, temp_y, arr[3])

        elif (arr[0] == 'V'):
            # draw vertical line
            if ((len(arr) < 5) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False) or (arr[3].isdigit() == False) or \
                (arr[4].isalpha() == False) or (len(arr[4]) != 1)):
                print("Error : V X Y1 Y2 C, X & Y is a number, C is a character")
            else:
                temp_x  = int(arr[1])
                temp_y1 = int(arr[2])
                temp_y2 = int(arr[3])

                if ((temp_x < 0) or (temp_x > self.width) or (temp_y1 < 0) or (temp_y1 > self.height) or \
                    (temp_y2 < 0) or (temp_y2 > self.height)):
                    print("Error : X, Y1, Y2 are smaller than canvas size")
                else:
                    self.drawVerticalLine(temp_x, temp_y1, temp_y2, arr[4])

        elif (arr[0] == 'H'):
            # draw vertical line
            if ((len(arr) < 5) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False) or (arr[3].isdigit() == False) or \
                (arr[4].isalpha() == False) or (len(arr[4]) != 1)):
                print("Error : V X1 X2 Y C, X & Y is a number, C is a character")
            else:
                temp_x1 = int(arr[1])
                temp_x2 = int(arr[2])
                temp_y  = int(arr[3])

                if ((temp_x1 < 0) or (temp_x1 > self.width) or (temp_x2 < 0) or (temp_x2 > self.width) or \
                    (temp_y < 0) or (temp_y > self.height)):
                    print("Error : X1, X2, Y are smaller than canvas size")
                else:
                    self.drawHorizontalLine(temp_x1, temp_x2, temp_y, arr[4])

        elif (arr[0] == 'K'):
            # draw rectangle
            if ((len(arr) < 6) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False) or (arr[3].isdigit() == False) or \
                (arr[4].isdigit() == False) or (arr[5].isalpha() == False) or (len(arr[5]) != 1)):
                print("Error : K X1 Y1 X2 Y2 C, X & Y is a number, C is a character")
            else:
                temp_x1 = int(arr[1])
                temp_y1 = int(arr[2])
                temp_x2 = int(arr[3])
                temp_y2 = int(arr[4])

                if ((temp_x1 < 0) or (temp_x1 > self.width) or (temp_x2 < 0) or (temp_x2 > self.width) or \
                    (temp_y1 < 0) or (temp_y1 > self.height) or (temp_y2 < 0) or (temp_y2 > self.height)):
                    print("Error : X1, X2, Y1, Y2 are smaller than canvas size")
                else:
                    self.drawRectangle(temp_x1, temp_y1, temp_x2, temp_y2, arr[5])

        elif (arr[0] == 'F'):
            # fill range
            if ((len(arr) < 4) or (arr[1].isdigit() == False) or (arr[2].isdigit() == False) or (arr[3].isalpha() == False) or (len(arr[3]) != 1)):
                print("Error : F X Y C, X & Y is a number, C is a character")
            else:
                temp_x = int(arr[1])
                temp_y = int(arr[2])

                if ((temp_x < 0) or (temp_x > self.width) or (temp_y < 0) or (temp_y > self.height)):
                    print("Error : X, Y are smaller than canvas size")
                else:
                    self.fillRangeNoRecursive(temp_x, temp_y, arr[3])

                    # there are 2 kinds of fill range
                    # 1) recursive,  2) non-recursive
                    # recursive type has a beautiful code. but it uses stack for recursive call
                    # to prevent an issue which is caused by stack overflow, I use non-recursive type

        elif (arr[0] == 'S'):
            # print canvas
            if (len(arr) < 2):
                print("Error : S Name")
            else:
                self.printCanvas(arr[1])

    def createCanvas(self, m, n):
        if ((m <= 0) or (m > 250) or (n <= 0) or (n > 250)):
            return False

        try:
            self.canvas = [['O'] * m for i in range(n)]
            self.width  = m
            self.height = n
        except:
            self.canvas = []
            self.width  = 0
            self.height = 0
            return False

        return True

    def clearCanvas(self):
        for i in range(self.height):
            for j in range(self.width):
                self.canvas[i][j] = 'O'

    def putPixel(self, x, y, c):
        if ((x < 0) or (x >= self.width) or (y < 0) or (y >= self.height)):
            return False

        self.canvas[y][x] = c
        return True

    def drawVerticalLine(self, x, y1, y2, c):
        if ((x < 0) or (y1 < 0) or (y1 >= self.height) or (y2 < 0) or (y2 >= self.height)):
            return False

        if (y1 > y2):
            y2, y1 = y1, y2 # swap

        for i in range(y1, y2 + 1):
            self.canvas[i][x] = c

        return True

    def drawHorizontalLine(self, x1, x2, y, c):
        if ((x1 < 0) or (x1 >= self.width) or (x2 < 0) or (x2 >= self.width) or (y < 0) or (y >= self.height)):
            return False

        if (x1 > x2):
            x2, x1 = x1, x2 # swap

        for i in range(x1, x2 + 1):
            self.canvas[y][i] = c

    def drawRectangle(self, x1, y1, x2, y2, c):
        if ((x1 < 0) or (x1 >= self.width) or (x2 < 0) or (x2 >= self.width) or \
            (y1 < 0) or (y1 >= self.height) or (y2 < 0) or (y2 >= self.height)):
            return False

        from_x = x1
        to_x = x2
        if (from_x > to_x):
            from_x, to_x = to_x, from_x # swap

        from_y = y1
        to_y = y2
        if (from_y > to_y):
            from_y, to_y = to_y, from_y # swap

        for i in range(from_y, to_y + 1):
            for j in range (from_x, to_x + 1):
                self.canvas[i][j] = c

        return True

    def fillRangeRecursive(self, x, y, c):
        if ((x < 0) or (x >= self.width) or (y < 0) or (y >= self.height)):
            return False

        org_c = self.canvas[y][x]
        self.fillPixelRecursive(x, y, org_c, c)

        return True

    def fillPixelRecursive(self, x, y, org_c, c):
        if ((x < 0) or (x >= self.width) or (y < 0) or (y >= self.height)):
            return False

        if (self.canvas[y][x] == org_c):
            self.canvas[y][x] = c

            self.fillPixelRecursive(x - 1, y, org_c, c)
            self.fillPixelRecursive(x + 1, y, org_c, c)
            self.fillPixelRecursive(x, y - 1, org_c, c)
            self.fillPixelRecursive(x, y + 1, org_c, c)

        return True

    def fillRangeNoRecursive(self, x, y, c):
        if ((x < 0) or (x >= self.width) or (y < 0) or (y >= self.height)):
            return False

        org_c = self.canvas[y][x]

        #search up
        new_y = y
        while (True):
            new_y -= 1
            if (new_y < 0):
                break

            if (self.fillPixelHorizon(x, new_y, org_c, c) == False):
                break

        #search same line
        self.fillPixelHorizon(x, y, org_c, c)

        #search down
        new_y = y
        while (True):
            new_y += 1
            if (new_y >= self.height):
                break

            if (self.fillPixelHorizon(x, new_y, org_c, c) == False):
                break

        return True

    def fillPixelHorizon(self, x, y, org_c, c):
        if ((x < 0) or (x >= self.width) or (y < 0) or (y >= self.height)):
            return False

        if(self.canvas[y][x] != org_c):
            return False

        self.canvas[y][x] = c

        # search left
        new_x = x
        while (True):
            new_x -= 1
            if (new_x < 0):
                break

            if (self.canvas[y][new_x] != org_c):
                break

            self.canvas[y][new_x] = c

        #search right
        new_x = x
        while (True):
            new_x += 1
            if (new_x >= self.width):
                break

            if (self.canvas[y][new_x] != org_c):
                break

            self.canvas[y][new_x] = c

        return True

    def printCanvas(self, filename):
        print(filename)

        for i in range(self.height):
            for j in range(self.width):
                print(self.canvas[i][j], end='')

            print('')

if __name__ == "__main__":
    obj = GEditor()

    while (True):
        obj.inputCommand()

'코딩 테스트' 카테고리의 다른 글

문제 7 : 체크 확인 (Check the Check)  (0) 2022.07.29
문제 6 : 인터프리터(Interpreter)  (0) 2022.07.28
문제 4 : LCD 디스플레이  (0) 2022.07.26
문제 3 : 여행 경비 계산  (0) 2022.07.20
문제 2 : 지뢰 찾기  (0) 2022.07.18

+ Recent posts