텍스트를 암호화는 방법 중에 보안상 취약하긴 하지만 흔하게 쓰이는 방법으로 알파벳 글자를 다른 글자로 돌리는 방법이 있다.

즉 알파벳의 각 글자를 다른 글자로 치환한다. 암호화된 것을 다시 원래대로 되돌릴 수 있으려면 두 개의 서로 다른 글자가 같은 글자로 치환되지 않아야 한다.

 

암호화된 텍스트가 한 줄 입력되는데, 이 때 매 시도마다 서로 다른 치환 방법이 적용된다.

암호화 이전의 텍스트에 있는 단어는 모두 주어진 사전에 들어있는 단어라고 가정하고, 암호화 된 텍스트를 해독하여 원래 텍스트를 알아내자.

 

입력

입력은 한 개의 정수 n이 들어 있는 행으로 시작되며 그 다음 줄부터는 한 줄에 하나씩 n개의 소문자로 쓰인 단어들이 입력된다.

이 n개의 단어들은 복호화된 텍스트에 들어갈 수 있는 단어로 구성된 사전이다. 사전 뒤에는 몇 줄의 텍스트가 입력된다. 

각 줄은 앞에서 설명한 방법에 따라서 복호화 된다.

 

사전에 들어갈 수 있는 단어의 수는 1000개를 넘어가지 않는다. 단어의 길이는 16 글자를 넘지 않는다. 

암호화된 텍스트에는 소문자와 스페이스만 들어가며 한 줄의 길이는 80 글자를 넘어가지 않는다.

 

출력

각 줄을 복호화하여 표준 출력으로 출력한다. 여러 문장으로 복호화 할 수 있다면 그 중 아무 결과나 출력하면 된다. 

가능한 풀이가 없다면 모든 문자를 아스테리스크(*)로 바꾸면 된다.

 

 

예제

6

and

dick

jane

puff

spot

yertle

bjvg xsb hsxn xsb qymm xsb rqat xsb pnetfn

dick and jane and puff and spot and yertle


해설

꽤 좌절을 겪은 문제다. 이래저래 2달 정도 걸린 것 같다. 내가 생각한 풀이는 다음과 같다.

1. 입력으로 받은 사전과 암호화 된 단어의 '알파벳'을 기준으로 치환 가능한 모든 '조합'을 구한다.

2. 구해진 '조합'으로 암호화 된 단어를 복호화 해서 원본 단어가 모두 있으면 출력

3. 하나라도 원본 단어가 없다면 모든 단어를 아스테리스크(*)로 출력

 

재귀 호출(Recursive Call)을 이용해서 '하노이 탑' 문제 풀듯이 했는데, 방법 자체는 맞는 것 같다.

다만 문제가 시간이 기하급수적으로 오래 걸린다는 것이다. '조합'을 구하는데 알파벳 수의 Factorial 만큼 걸리는데 어마어마한 수가 나온다.

 

일단 답은 올린다. 시간만 오래 걸리는거 빼고는 잘 동작하는 것 같다.

다시 이 문제를 찬찬히 읽어보니, 알파벳이 아니라 그냥 단어 단위로 쉽고 무식하게 풀면 될 것 같긴한데 너무 처음에 어렵게 생각한 걸까?

기회가 되면 2번째 풀이를 이 글에 올려보겠다~

# Quiz 0012, Crypt Kicker
# written by badsaram

import sys

class CryptKicker(object):
    def __init__(self, dbgMode):
        self.numDictionary = 0
        self.dictionary = []

        self.cryptFrom  = []
        self.cryptTo    = []

        self.cryptMatrix = []

        self.dbgMode = dbgMode

    def inputDictionary(self):
        str = input()
        if ((str.isdigit() != True) or (int(str) <= 0) or (int(str) > 1000)):
            print("Please Input Correct Number (0 < n <= 1000).")
            sys.exit(-1)

        self.numDictionary = int(str)

        for i in range(0, self.numDictionary):
            str = input()
            if ((len(str) > 16) or (str.isalpha() == False)):
                print("Please Input String Under 16 Characters. You should input %d strings" % (self.numDictionary))
                sys.exit(-1)

            self.dictionary.append(str)

        self.makeSymbolArray(self.dictionary, self.cryptFrom)

    def makeSymbolArray(self, words, cryptArray):
        # make cryptFrom
        for word in words:
            for ch in word:
                try:
                    cryptArray.index(ch)
                except:
                    cryptArray.append(ch)

    def isEmpty(self, ch):
        ret = False

        if (ch.isalpha() == True):
            ret = False
        else:
            ret = True

        return ret

    def insertCryptMatrix(self, cryptPattern):
        dup_flag = False

        for pattern in self.cryptMatrix:
            sameCnt = 0

            for i in range(len(pattern)):
                if (pattern[i] == cryptPattern[i]):
                    sameCnt += 1
                else:
                    break

            if (sameCnt == len(pattern)):
                dup_flag = True
                break

        if (dup_flag == False):
            self.cryptMatrix.append(cryptPattern.copy())
            if (self.dbgMode == True):
                print(cryptPattern)

    def makeCryptMatrix(self, cryptMatrix, n):
        for i in range(len(self.cryptFrom)):
            cryptPattern = [ '' for i in range(len(self.cryptFrom)) ]

            for j in range(len(self.cryptTo)):
                try:
                    cryptPattern.index(self.cryptTo[j])
                except:
                    cryptPattern[i] = self.cryptTo[j]

                    self.makeCryptMatrixRecursive(cryptPattern, n + 1)
                    cryptPattern[i] = ''

    def makeCryptMatrixRecursive(self, cryptPattern, n):
        if ( (n >= len(self.cryptFrom)) or (n >= len(self.cryptTo)) ):
            self.insertCryptMatrix(cryptPattern)
            return

        for i in range(len(self.cryptFrom)):
            if (self.isEmpty(cryptPattern[i]) == False):
                continue

            for j in range(len(self.cryptTo)):
                try:
                    cryptPattern.index(self.cryptTo[j])
                except:
                    cryptPattern[i] = self.cryptTo[j]

                    self.makeCryptMatrixRecursive(cryptPattern, n + 1)
                    cryptPattern[i] = ''

    def decodeChar(self, pattern, ch):
        index = pattern.index(ch)

        return self.cryptFrom[index]

    def tryDecode(self):
        successFlag = False

        strInput = input()

        encodedWords = strInput.split(" ")
        self.makeSymbolArray(encodedWords, self.cryptTo)

        if (len(self.cryptTo) > len(self.cryptFrom)):
            successFlag = False
        else:
            self.makeCryptMatrix(self.cryptMatrix, 0)
            if (self.dbgMode == True):
                print(self.cryptMatrix)

            for pattern in self.cryptMatrix:
                successFlag = True

                decodedResult = []

                for word in encodedWords:
                    temp = list(word)  # string is immutable

                    for i in range(len(word)):
                        temp[i] = self.decodeChar(pattern, word[i])

                    decodedWord = ''.join(temp)
                    if (self.dictionary.count(decodedWord) > 0):
                        if (self.dbgMode == True):
                            print("%s is found" % (decodedWord))

                        decodedResult.append(decodedWord)
                    else:
                        successFlag = False
                        break

                if (successFlag == True):
                    break

        if (successFlag == True):
            if (self.dbgMode == True):
                print("found")

            self.printDecodedWord(decodedResult)
        else:
            if (self.dbgMode == True):
                print("not found")

            self.printNotDecodedWord(encodedWords)

    def printDecodedWord(self, decodedResult):
        for word in decodedResult:
            print(word, end=' ')

    def printNotDecodedWord(self, encodedWords):
        for word in encodedWords:
            for i in range(len(word)):
                print("*", end='')

            print(" ", end='')

if __name__ == '__main__':
    dbgMode = False

    obj = CryptKicker(dbgMode)

    obj.inputDictionary()
    obj.tryDecode()

 

방글라데시의 정당들은 자신의 세를 과시하기 위해 정기적인 동맹 휴업(파업)을 추진한다고 합니다.

이 문제는 동맹 휴업 지수(hartal parameter)라고 부르는 h라는 양의 정수로 나타낼 수 있습니다. 이 값은 한 동맹 휴업과 다른 동맹 휴업 사이의 기간을 날짜 수로 표시한 값입니다.

 

세 개의 정당이 있다고 생각해봅시다. i 번째 당의 동맹 휴업 지수를 h(i) 라고 할 때, h(1) = 3, h(2) = 4, h(3) = 8 이라고 가정합니다. N일(N=14)일 동안의 세 당의 행보를 시뮬레이션하면 다음과 같이 표시할 수 있습니다. 시뮬레이션은 항상 일요일에 시작하며 금요일이나 토요일에는 동맹 휴업이 없습니다.

요일 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1번 정당     X     X     X     X    
2번 정당       X       X       X    
3번 정당               X            
동맹 휴업     1 2       3 4     5    

이 결과를 보면 14일 동안 정확하게 다섯 번의 동맹 휴업(3, 4, 8, 9, 12일)이 있음을 알 수 있습니다. 6일은 금요일이기 때문에 동맹 휴업이 일어나지 않습니다. 결국 2주 동안 근무 일수로 5일의 동맹 휴업이 실시됩니다.

 

몇 정당의 동맹 휴업 지수와, 어떤 정수 N이 주어졌을 때, N일 가운데 동맹 휴업으로 인해 일을 하지 않은 근무 일수를 계산해봅시다.

 

입력

입력의 첫째 줄에는 한 개의 정수 N(7 ≤ N ≤ 3,650)이 들어있으며 시뮬레이션을 돌릴 기간(날 수)를 나타냅니다. 그 다음 줄에는 정당의 개수를 나타내는 정수 P(1 ≤ P ≤ 100) 가 들어갑니다. 그 다음부터 시작하는 P개의 줄 가운데 i 번째 줄(1≤ i ≤ P) 에는 i번째 동맹 휴업 지수를 나타내는 양의 정수 h(i)가 들어있습니다. 이때 h(i) 값은 7의 배수가 아닙니다.

 

출력

각 입력에 대해 손실된 근무 일수를 한 줄에 하나씩 출력합니다.

 

예제


해설

기간을 입력 받고 그 갯수만큼 리스트(배열) 할당. 이 후에는 각 정당별로 휴업 일수마다 '1'로 Marking.

Marking시 금요일, 토요일일때는 수행하지 않고 건너뛰도록 해준다. 모든 정당에 대해서 수행한 뒤, 나중에 Marking된 '1'의 갯수가 몇개인지 확인하면 끝.

# Quiz 0011, Hartal
# written by badsaram

import sys

class Hartal(object):
    def __init__(self):
        self.working_day = 0
        self.member_count = 0
        self.working_states = []
        self.hartal_parameters = []

    def input(self):
        # input days
        str = input()
        if (str.isdigit() == False):
            print("Please input number for working days")
            sys.exit(-1)

        working_day = int(str)
        if ((working_day < 7) or (working_day > 3650)):
            print("Please input working days in 7 - 3650 range.")
            sys.exit(-1)

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

        member_count = int(str)
        if ((member_count < 1) or (member_count > 100)):
            print("Please input member count in 1 - 100 range.")
            sys.exit(-1)

        hartal_parameters = []

        # input hartal parameter
        for i in range(member_count):
            str = input()
            if (str.isdigit() == False):
                print("Please input number for hartal parameters.")
                sys.exit(-1)

            hartal_parameters.append(int(str))

        working_states = [ 0 for i in range(working_day) ]

        self.working_day        = working_day
        self.member_count       = member_count
        self.working_states     = working_states
        self.hartal_parameters  = hartal_parameters

    def calc(self):
        if ((self.hartal_parameters == []) or (self.working_states == [])):
            print("There is no hartal parameters and working states.")
            return

        for hartal_parameter in self.hartal_parameters:
            for day in range(0, self.working_day, hartal_parameter):
                if (((day % 7) != 6) and ((day % 7) != 7) and (day != 0)):
                    self.working_states[day - 1] = 1

        print("%d" % (self.working_states.count(1)))

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

    obj.input()
    obj.calc()

 

윈도우용 프로그램을 개발할 일이 있습니다.

 

요새는 MFC (Microsoft Foundation Library)를 사용하지 않습니다. 최신 Visual Studio 에서는 MFC를 기본적으로는 지원하지 않고 별도로 Extension을 설치해야만 사용할 수 있습니다.

 

윈도우용 프로그램 개발은 크게 아래 2가지 방식을 사용합니다.

  • Visual Studio + C#
  • Visual Studio + QT

Visual Studio는 이제 무료가 돼서 쓰지 않을 이유가 없습니다. 본인은 C# 에는 익숙치 않고 Linux 등 다른 기종에서도 일부 S/W를 재활용하고 싶다면 QT를 사용하세요. 

 

그럼 Visual Studio 2022 와 QT 개발 환경을 셋업해봅시다.

 

Visual Studio 2022 설치

URL : https://visualstudio.microsoft.com/ko/downloads/

 

Visual Studio Tools 다운로드 - Windows, Mac, Linux용 무료 설치

Visual Studio IDE 또는 VS Code를 무료로 다운로드하세요. Windows 또는 Mac에서 Visual Studio Professional 또는 Enterprise Edition을 사용해 보세요.

visualstudio.microsoft.com

 

위 주소에서 무료 다운로드를 눌러줍니다.

설치시 Microsoft 계정 가입을 해야 합니다. 설치할 구성 요소는 필요에 따라 선택하되, "C++를 사용한 데스크톱 개발"".Net 데스크톱 개발", "유니버설 Windows 플랫폼 개발" 정도면 그게 무리가 없습니다.

 

 

QT 다운로드

QT 공식 홈페이지를 방문합니다.

URL : https://www.qt.io/

 

 

Qt | Cross-platform software development for embedded & desktop

Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.

www.qt.io

 

이곳도 가입을 해야 합니다. 가입을 하고 진행해주세요.

 

사이트를 보시면 "Download" 관련 메뉴가 있습니다. 이곳으로 갑니다.

참고로 사이트 디자인은 계속 바뀔 수 있는거라 염두해주세요.

우측 밑에 "Downloads for open source users" 라는 항목이 있죠? 이걸 선택해 줍니다.

 

 

좀 더 가시면 "Download the Qt Online Installer"가 있습니다. 이걸 선택해 줍니다.

이어지는 메뉴에서 "Download"를 눌러서 Installer를 다운 받고 실행해줍니다. Installer 파일명은 "qt-unified-windows-x64-4.4.1-online.exe" 이런 식의 이름을 가지고 있습니다. 이 글을 쓰는 시점에서 버전은 4.4.1인 것 같습니다.

 

인스톨러 화면이 뜹니다. QT 가입은 하셨나요? 없으면 여기서 계정을 만들어서 로그인까지 해주고 쭉쭉 진행해줍니다.

구성 요소에서 선택은 아래처럼 해주세요

  • 개인 개발자는 "나는 개인이며 어떤 회사 업무에도 Qt를 사용하지 않습니다" 선택. 회사라면 회사 정보도 입력.
  • Custom Installation 을 선택합니다. 밑에서 따로 QT 버전과 MinGW 버전을 선택하기 위함입니다. 그냥 필요 없다면 "Qt 6.3 for desktop development" 를 선택하셔도 됩니다.

  • QT 버전은 최신으로. 이 시점에서는 6.3.1이 최신이었습니다. 설치하는 김에 MinGW 11.2.0 64-bit도 넣었습니다.

용량이 꽤 되네요. 설치를 시작합니다. 32GB 정도네요. 용량이 너무 크다면 본인에 맞게 구성 요소를 조정해줍니다.

시간이 제법 걸리니 가볍게 영화를 하나 시청해 줍니다.

수시간이 걸려서 겨우 설치가 됐습니다. 저는 노트북에 설치했는데 절전 모드 들어가니까 다운로드가 취소 됐습니다. 이 부분 감안하셔서 절전 모드를 필요시 잠시 끄는 것도 필요할 것 같습니다.

 

Visual Studio 에 QT 연동하기

Visual Studio에 QT 확장을 설치해봅시다. 상단 메뉴에서 "확장" → "확장관리" 에서 "qt" 로 검색해서 "Qt Visual Studio Tools" 를 설치합니다.

설치하고 Visual Studio 2022를 실행하면 아래처럼 Qt version을 설정하라는 메시지가 뜹니다. 눌러줍니다.

아래처럼 qmake.exe가 있는 곳을 찾아서 선택해줍니다. 예제의 경우 "C:\Qt\6.3.1\msvc2019_64\bin\qmake.exe" 입니다.

이후에도 상단 메뉴 "확장" → "Qt VS Tools" → "Qt Versions" 에서 확인이랑 설정을 변경할 수 있습니다.

 

Qt Project 생성하기

이제 Visual Studio 2022를 실행해서 QT 프로젝트를 만들어봅니다. 

"새 프로젝트 만들기" → "C++" 을 선택. 템플릿에서 조금 밑으로 내리면 아래처럼 QT 프로젝트들이 보입니다.

예제로 하나 만들어보려고 하니, "Qt Quick Application"을 선택해서 프로젝트 경로를 적당한 곳에 만들어줍니다. 아래 화면이 나오면 프로젝트가 만들어진 것입니다.

샘플 소스 코드가 보입니다. 여기서 자신의 코드를 덧붙여서 작업을 하면 되겠습니다.

샘플 소스 코드 그대로 실행한 결과입니다. 

 

윈도우용 QT 응용 프로그램을 만들려면 아무래도 Python + Qt 가 접근성에서는 좋습니다.

하지만 Device Driver 처럼 좀 더 시스템에 밀접한 작업을 해야할 경우에는 C/C++이 제격이죠.

 

모두 즐거운 QT 프로그래밍 합시다.

'Windows' 카테고리의 다른 글

파워쉘(PowerShell) UnauthroizedAccess 오류 해결  (0) 2023.07.01
파워쉘(PowerShell) 익히기  (0) 2023.01.18

포커용 카드는 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()

+ Recent posts