#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
enum Color_t
{
RED_HEART,
BLACK_HEART,
SQUARE,
GRASS
};
enum RankType_t
{
MAX = 0,
PAIR,
DOUBLE_PAIR,
TRIPLE,
SEQ,
SAME_COLOR,
TRIPLE_PAIR,
QUATERNARY,
SAME_COLOR_SEQ
};
struct Poker
{
void Set(char* input)
{
char num = input[0];
if ((num >= '2') && (num <= '9'))
Number = num - '0';
else
{
switch(num)
{
case 'T':
Number = 10;
break;
case 'J':
Number = 11;
break;
case 'Q':
Number = 12;
break;
case 'K':
Number = 13;
break;
default: //case 'A':
Number = 14;
break;
}
}
switch(input[1])
{
case 'C':
Color = GRASS;
break;
case 'D':
Color = SQUARE;
break;
case 'H':
Color = RED_HEART;
break;
default: // case 'S':
Color = BLACK_HEART;
break;
}
}
bool operator > (const Poker& other) const
{
return (Number > other.Number);
}
bool operator < (const Poker& other) const
{
return (Number < other.Number);
}
bool operator >= (const Poker& other) const
{
return !(this->operator<(other));
}
bool operator <= (const Poker& other) const
{
return !(this->operator>(other));
}
bool operator == (const Poker& other) const
{
return (Number == other.Number);
}
bool operator != (const Poker& other) const
{
return !(this->operator==(other));
}
int operator - (const Poker& other) const
{
return Number - other.Number;
}
operator int ()
{
return Number;
}
int Number;
Color_t Color;
};
#define MAX_POKER_NUM 5
class PokerSeq
{
public:
PokerSeq(char* input)
{
for(int i = 0; i < MAX_POKER_NUM; ++i)
{
m_pokers[i].Set(input);
input += 3;
}
Analyze();
}
int CompareTo(const PokerSeq& other)
{
if (m_RankType > other.m_RankType)
return 1;
if (m_RankType < other.m_RankType)
return -1;
int compairPokerNum = 0;
switch (m_RankType)
{
case SAME_COLOR_SEQ:
case QUATERNARY:
case TRIPLE_PAIR:
case SEQ:
case TRIPLE:
compairPokerNum = 1;
break;
case SAME_COLOR:
case MAX:
compairPokerNum = MAX_POKER_NUM;
break;
case PAIR:
compairPokerNum = MAX_POKER_NUM - 1;
break;
case DOUBLE_PAIR:
compairPokerNum = MAX_POKER_NUM - 2;
default:
break;
}
for (int i = 1; i <= compairPokerNum; ++i)
{
int diff = m_Max[MAX_POKER_NUM - i] - other.m_Max[MAX_POKER_NUM - i];
if (diff == 0)
continue;
return diff;
}
return 0;
}
private:
void Analyze()
{
sort(m_pokers, m_pokers + MAX_POKER_NUM);
for (int i = 0; i < MAX_POKER_NUM; ++i)
m_Max[i] = m_pokers[i];
m_RankType = MAX;
bool isSeq = IsSequence();
bool isSameColor = IsSameColor();
if (isSeq && isSameColor)
{
m_RankType = SAME_COLOR_SEQ;
return;
}
if (isSeq)
{
m_RankType = SEQ;
return;
}
if (isSameColor)
{
m_RankType = SAME_COLOR;
return;
}
int index = GetMultipleSameIndex(4, MAX_POKER_NUM, m_pokers);
if (index >= 0)
{
m_RankType = QUATERNARY;
m_Max[MAX_POKER_NUM - 1] = m_pokers[index];
return;
}
index = GetMultipleSameIndex(3, MAX_POKER_NUM, m_pokers);
if (index >= 0)
{
m_Max[MAX_POKER_NUM - 1] = m_pokers[index];
if (index == (MAX_POKER_NUM - 1))
index = GetMultipleSameIndex(2, 2, m_pokers);
else if (index == (MAX_POKER_NUM - 3))
index = GetMultipleSameIndex(2, 2, m_pokers + 3);
else
index = -1;
m_RankType = (index < 0) ? TRIPLE : TRIPLE_PAIR;
return;
}
int maxPairindex = GetMultipleSameIndex(2, MAX_POKER_NUM, m_pokers);
if (maxPairindex >= 0)
{
m_Max[MAX_POKER_NUM - 1] = m_pokers[maxPairindex];
int secondPairIndex = -1;
if (maxPairindex == (MAX_POKER_NUM - 1))
{
secondPairIndex = GetMultipleSameIndex(2, 3, m_pokers);
if (secondPairIndex >= 0)
{
m_Max[MAX_POKER_NUM - 2] = m_pokers[secondPairIndex];
m_Max[MAX_POKER_NUM - 3] = (secondPairIndex == 2) ? m_pokers[0] : m_pokers[2];
}
}
else if (maxPairindex == (MAX_POKER_NUM - 2))
{
secondPairIndex = GetMultipleSameIndex(2, 2, m_pokers);
if (secondPairIndex >= 0)
{
m_Max[MAX_POKER_NUM - 2] = m_pokers[secondPairIndex];
m_Max[MAX_POKER_NUM - 3] = m_pokers[MAX_POKER_NUM - 1];
}
}
if (secondPairIndex < 0)
{
index = MAX_POKER_NUM - 1;
for (int i = MAX_POKER_NUM - 1; i >= 0; --i)
{
if ((maxPairindex == i) || ((maxPairindex - 1) == i))
continue;
--index;
m_Max[index] = m_pokers[i];
}
}
m_RankType = (secondPairIndex < 0) ? PAIR : DOUBLE_PAIR;
return;
}
}
bool IsSequence()
{
for (int i = 1; i < MAX_POKER_NUM; ++i)
{
if ((m_pokers[i] - m_pokers[i - 1]) != 1)
return false;
}
return true;
}
bool IsSameColor()
{
for (int i = 1; i < MAX_POKER_NUM; ++i)
{
if ((m_pokers[i].Color != m_pokers[i - 1].Color))
return false;
}
return true;
}
int GetMultipleSameIndex(int times, int total, Poker* pStartPoker)
{
for(int i = total - 1; i >= (times - 1); --i)
{
bool bingo = true;
for (int j = (i - times + 2); j <= i; ++j)
{
if (pStartPoker[j] != pStartPoker[j - 1])
{
bingo = false;
break;
}
}
if (bingo)
return i;
}
return -1;
}
private:
Poker m_pokers[MAX_POKER_NUM];
int m_Max[MAX_POKER_NUM];
RankType_t m_RankType;
};
void DoWork()
{
char buf[MAX_POKER_NUM * 6 + 1];
while(fgets(buf, MAX_POKER_NUM * 6 + 1, stdin))
{
if (strlen(buf) < (MAX_POKER_NUM * 6))
return;
PokerSeq black(buf), white(buf + MAX_POKER_NUM * 3);
int result = black.CompareTo(white);
if (result == 0)
cout << "Tie." << endl;
else if (result > 0)
cout << "Black wins." << endl;
else
cout << "White wins." << endl;
}
}
int main(int argc, char* argv[])
{
DoWork();
return 0;
}