%a.out 1112345678999
[23](111)(456)(789)(99)
(123)[11](456)(789)(99)
(111)(345)(678)(999)[2]
(123)[45](678)(999)(11)
(111)(234)[56](789)(99)
(111)(234)(678)(999)[5]
(123)(456)[78](999)(11)
(111)(234)(567)[89](99)
(111)(234)(567)(999)[8]
(123)(456)(789)[99](11)
#include <stdio.h>
#include <stdlib.h>
#define PIECE_KINDS 9
#define PIECE_CHAR(id) ('1'+(id))
typedef int Hand[PIECE_KINDS+2];
#define TRIPLET_ID_111(i) ((i)|0x1000)
#define TRIPLET_ID_123(i) ((i)|0x2000)
#define TRIPLET_ID_PAIR(i) ((i)|0x4000)
#define TRIPLET_IS_111(t) ((t)&0x1000)
#define TRIPLET_IS_123(t) ((t)&0x2000)
#define TRIPLET_IS_PAIR(t) ((t)&0x4000)
#define TRIPLET_FLAG_MASK 0xfff
int one_drawn;
static void print_triplets(int ntriplet, int *triplets);
bool Win(Hand hand, int start, int pair_idx,int ntriplet, int *triplets)
{
int i=start;
bool result = false;
if(ntriplet==4 && pair_idx !=-1)
{
triplets[4] = TRIPLET_ID_PAIR(pair_idx);
print_triplets(5, triplets);
return true;
}
while(hand[i] ==0)
{
if (hand[i] == -1) return false;
i++;
}
if(hand[i] ==2 && pair_idx == -1)
{
hand[i]-=2;
result |= Win(hand, i+1, i, ntriplet, triplets);
hand[i]+=2;
}
if(hand[i]==3)
{
hand[i]-=3;
triplets[ntriplet] = TRIPLET_ID_111(i);
result |= Win(hand, i+1, pair_idx, ntriplet+1, triplets);
hand[i]+=3;
}
if(hand[i+1]>0 && hand[i+2]>0 )
{
hand[i]--;
hand[i+1]--;
hand[i+2]--;
triplets[ntriplet] = TRIPLET_ID_123(i);
result |= Win(hand, i, pair_idx, ntriplet+1, triplets);
hand[i]++;
hand[i+1]++;
hand[i+2]++;
}
return result;
}
void print_hand(Hand hand)
{
int i,j;
for(i=0;i<PIECE_KINDS;i++)
{
for(j=0;j<hand[i];j++) putchar(PIECE_CHAR(i));
}
printf("\n");
}
int triplet_has_id(int tid, int id)
{
int id0 = tid & TRIPLET_FLAG_MASK;
if(id0 == id) return 1;
if(TRIPLET_IS_123(tid))
{
if(id0+1 == id) return 2;
if(id0+2 == id && id==0) return 4;
if(id0+2 == id) return 3;
}
return 0;
}
void print_triplet(int id, int omit_id)
{
if(omit_id ==-1)
putchar('(');
else
putchar('[');
int id0 = id&TRIPLET_FLAG_MASK;
if(TRIPLET_IS_PAIR(id))
{
putchar(PIECE_CHAR(id0));
if(omit_id != id0) putchar(PIECE_CHAR(id0));
}
else if(TRIPLET_IS_123(id))
{
if(omit_id != id0) putchar(PIECE_CHAR(id0));
if(omit_id != id0+1) putchar(PIECE_CHAR(id0+1));
if(omit_id != id0+2) putchar(PIECE_CHAR(id0+2));
}
else
{
if(omit_id != id0) putchar(PIECE_CHAR(id0));
putchar(PIECE_CHAR(id0));
putchar(PIECE_CHAR(id0));
}
if(omit_id ==-1)
putchar(')');
else
putchar(']');
}
void print_triplets(int ntriplet, int *triplets)
{
int i,j;
for(i=0;i<5;i++)
{
int f=triplet_has_id(triplets[i], one_drawn);
if(f!=0 && f!=3)
{
for(j=0;j<5;j++) print_triplet(triplets[j], (i==j) ? one_drawn:-1);
printf("\n");
}
}
}
int main(int argc, char **argv)
{
int i;
if(argc!=2)exit(1);
Hand hand;
for(i=0;i<PIECE_KINDS;i++)hand[i]=0;
hand[PIECE_KINDS]=hand[PIECE_KINDS+1]=-1;
for(i=0;i<13;i++)
{
if(argv[1][i]==0)exit(1);
int kind=argv[1][i]-'0';
if(kind<1 || kind>9)exit(1);
hand[kind-1]++;
}
int triplets[5];
for(i=0;i<PIECE_KINDS;i++)
{
one_drawn=i;
int j;
hand[i]++;
Win(hand, 0, -1, 0, triplets);
hand[i]--;
}
}