/* 以下代码(120行)给出24点游戏全部独立解 */
#include<stdio.h>
int MAX=13;//扑克牌的最大点数
int way;
void print(char *format,int a,char o1,int b,char o2,int c,char o3,int d)
{ way++;
if(way==1)printf("\n");
printf(format,a,o1,b,o2,c,o3,d);
}
int OP(int x,int iop,int y)
{ if(iop==1)return x>=y ? x+y:-9999;
if(iop==2)return x>=y ? x-y:-9999;
if(iop==3)return x>=y ? x*y:-9999;
if(iop==4)if(y && y-1 && x%y==0)return x/y;
return -9999;
}
int op(int x,int iop,int y)
{ if(iop==1)return x+y;else
if(iop==3)return x*y;else
return OP(x,iop,y);
}
int quan_pai_lie(int a[],int n)
{ //from 54321 to 12345
int i,j,k,temp,t;
for(k=n-1;k>0;k--)
if(a[k-1]>a[k])break;
if(k==0)return 0;
temp=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(temp>a[j]&&a[j]>a[i])i=j;
a[k-1]=a[i];a[i]=temp;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j+1]>a[j])
{t=a[j];a[j]=a[j+1];a[j+1]=t;}
return 1;
}
#define DO(I,a1,a2, J,m1,m2, K,z1,z2) for(K=z1;K<=z2;K++)for(J=m1;J<=m2;J++)for(I=a1;I<=a2;I++)
int main(void)
{ int p[5],A[5],noslv=0;
int a,b,c,d,op1,op2,op3;
char os[]=" +-*/";
for(p[1]= 1 ;p[1]<=MAX;p[1]++) //全
for(p[2]=p[1];p[2]<=MAX;p[2]++) //面
for(p[3]=p[2];p[3]<=MAX;p[3]++) //搜
for(p[4]=p[3];p[4]<=MAX;p[4]++) //索
{
A[4]=p[1],A[3]=p[2],A[2]=p[3],A[1]=p[4];
a=A[1];b=A[2];c=A[3];d=A[4]; way=0;
printf("%d,%d,%d,%d: ",p[1],p[2],p[3],p[4]);
if(a==13 && b==13 && c==12 && d==12) //K-K+Q+Q
print("%d%c%d%c%d%c%d=24\n",a,os[2],b,os[1],c,os[1],d);
DO(op1,1,2, op2,1,2, op3,1,2) {//此法唯一遗漏K-K+Q+Q
if(OP(OP(OP(a,op1,b),op2,c),op3,d)==24) //a+b+c+d,a+b+c-d,a+b-c-d
if( !(op2==2 && op3==1 && c==d) )
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
}
DO(op1,3,4, op2,3,4, op3,3,4) {//abcd, abc/d, ab/c/d
if(OP(OP(OP(a,op1,b),op2,c),op3,d)==24) {
if( !(op2==4 && op3==3 && c==d) &&
!(op1==4 && op3==3 && d==b) &&
!(op1==4 && op2==3 && b==c) )
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
}
else if(b-c && OP(OP(OP(a,op1,c),op2,d),op3,b)==24 && op3==4)
print("%d%c%d%c%d%c%d=24\n",a,os[op1],c,os[op2],d,os[op3],b);
else if(a-b && OP(OP(OP(b,op1,c),op2,d),op3,a)==24 && op3==4)
print("%d%c%d%c%d%c%d=24\n",b,os[op1],c,os[op2],d,os[op3],a);
}
do
{ a=A[1];b=A[2];c=A[3];d=A[4];
DO(op1,1,2, op2,1,2, op3,0,0) {//(a±b±c)*d
if(OP(OP(a,op1,b),op2,c)*d==24 && !(op1==2 && op2==1) && !(op1==op2 && b<c))
print("(%d%c%d%c%d)%c%d=24\n",a,os[op1],b,os[op2],c,os[3],d);
}
if(op(OP(a,3,b),1,c)*d==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[1],c,os[3],d); //(a*b+c)*d
if(op(OP(a,3,b),2,c)*d==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[2],c,os[3],d); //(a*b-c)*d
DO(op1,1,2, op2,0,0, op3,1,4) {
if(op(OP(a,op1,b)*c,op3,d)==24 && !(op3==3 && c<d)) //(a±b)*c±d,(a±b)*c*d,(a±b)*c/d
print("(%d%c%d)%c%d%c%d=24\n",a,os[op1],b,os[3],c,os[op3],d);
if(op(OP(OP(a,op1,b),4,c),op3,d)==24 && op3<3) //(a±b)/c±d
print("(%d%c%d)%c%d%c%d=24\n",a,os[op1],b,os[4],c,os[op3],d);
}
DO(op1,3,4, op2,1,4, op3,1,2) {//a*b±c±d, a/b±c±d, a*b*c±d, a*b/c±d
if(op(op(OP(a,op1,b),op2,c),op3,d)==24 && !(op2==op3 && c<d) && !(op2==2 && op3==1)
&& !(op1*op2==9 && b<c) && !(op1==4 && op2==3)){
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
if(b==1 && op2<3||c==1 && op1==3)goto next; }
}
next:
if(op(op(OP(a,3,b),1,c),4,d)==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[1],c,os[4],d); //(a*b+c)/d
if(op(op(OP(a,3,b),2,c),4,d)==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[2],c,os[4],d); //(a*b-c)/d
if(op(OP(c,2,OP(a,3,b)),3,d)==24)print("(%d%c%d%c%d)%c%d=24\n",c,os[2],a,os[3],b,os[3],d); //(c-a*b)*d
DO(op1,1,2, op2,1,2, op3,0,0) {
if(OP(OP(a,op1,b),3,OP(c,op2,d))==24) //(a±b)*(c±d)
print("(%d%c%d)%c(%d%c%d)=24\n",a,os[op1],b,os[3],c,os[op2],d);
if(OP(OP(a,op1,b),op2,OP(c,4,d))==24 && op2==2) //(a±b)-(c/d)
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[4],d);
}
DO(op1,0,0, op2,1,2, op3,3,4) {
if(OP(OP(a,3,b),op2,OP(c,op3,d))==24) //(a*b)±(c*d), (a*b)±(c/d)
print("%d%c%d%c%d%c%d=24\n",a,os[3],b,os[op2],c,os[op3],d);
if(op3==4 && OP(OP(a,3,b),op3,OP(c,op2,d))==24) //(a*b)/(c±d)
print("%d%c%d%c(%d%c%d)=24\n",a,os[3],b,os[op3],c,os[op2],d);
}
// 以下涉及实型除法
for(op2=1;op2<=2;op2++) //(a/b±c)*d
if(op(a,op2,b*c)*d==24*b && b-1)
print("(%d%c%d%c%d)%c%d=24\n",a,os[4],b,os[op2],c,os[3],d);
if((b*c-a)*d==24*b && b-1) //(c-a/b)*d
print("(%d%c%d%c%d)%c%d=24\n",c,os[2],a,os[4],b,os[3],d);
if(d*b==(c*b-a)*24) //d/(c-a/b)
print("%d%c(%d%c%d%c%d)=24\n",d,os[4],c,os[2],a,os[4],b);
if(d*b==(a-c*b)*24) //d/(a/b±c)
print("%d%c(%d%c%d%c%d)=24\n",d,os[4],a,os[4],b,os[2],c);
}
while(quan_pai_lie(A+1,4));
if(!way)printf("failure(%d)\n",++noslv);//无效组合编号 458 for K
}
return(0);
}
#include<stdio.h>
int MAX=13;//扑克牌的最大点数
int way;
void print(char *format,int a,char o1,int b,char o2,int c,char o3,int d)
{ way++;
if(way==1)printf("\n");
printf(format,a,o1,b,o2,c,o3,d);
}
int OP(int x,int iop,int y)
{ if(iop==1)return x>=y ? x+y:-9999;
if(iop==2)return x>=y ? x-y:-9999;
if(iop==3)return x>=y ? x*y:-9999;
if(iop==4)if(y && y-1 && x%y==0)return x/y;
return -9999;
}
int op(int x,int iop,int y)
{ if(iop==1)return x+y;else
if(iop==3)return x*y;else
return OP(x,iop,y);
}
int quan_pai_lie(int a[],int n)
{ //from 54321 to 12345
int i,j,k,temp,t;
for(k=n-1;k>0;k--)
if(a[k-1]>a[k])break;
if(k==0)return 0;
temp=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(temp>a[j]&&a[j]>a[i])i=j;
a[k-1]=a[i];a[i]=temp;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j+1]>a[j])
{t=a[j];a[j]=a[j+1];a[j+1]=t;}
return 1;
}
#define DO(I,a1,a2, J,m1,m2, K,z1,z2) for(K=z1;K<=z2;K++)for(J=m1;J<=m2;J++)for(I=a1;I<=a2;I++)
int main(void)
{ int p[5],A[5],noslv=0;
int a,b,c,d,op1,op2,op3;
char os[]=" +-*/";
for(p[1]= 1 ;p[1]<=MAX;p[1]++) //全
for(p[2]=p[1];p[2]<=MAX;p[2]++) //面
for(p[3]=p[2];p[3]<=MAX;p[3]++) //搜
for(p[4]=p[3];p[4]<=MAX;p[4]++) //索
{
A[4]=p[1],A[3]=p[2],A[2]=p[3],A[1]=p[4];
a=A[1];b=A[2];c=A[3];d=A[4]; way=0;
printf("%d,%d,%d,%d: ",p[1],p[2],p[3],p[4]);
if(a==13 && b==13 && c==12 && d==12) //K-K+Q+Q
print("%d%c%d%c%d%c%d=24\n",a,os[2],b,os[1],c,os[1],d);
DO(op1,1,2, op2,1,2, op3,1,2) {//此法唯一遗漏K-K+Q+Q
if(OP(OP(OP(a,op1,b),op2,c),op3,d)==24) //a+b+c+d,a+b+c-d,a+b-c-d
if( !(op2==2 && op3==1 && c==d) )
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
}
DO(op1,3,4, op2,3,4, op3,3,4) {//abcd, abc/d, ab/c/d
if(OP(OP(OP(a,op1,b),op2,c),op3,d)==24) {
if( !(op2==4 && op3==3 && c==d) &&
!(op1==4 && op3==3 && d==b) &&
!(op1==4 && op2==3 && b==c) )
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
}
else if(b-c && OP(OP(OP(a,op1,c),op2,d),op3,b)==24 && op3==4)
print("%d%c%d%c%d%c%d=24\n",a,os[op1],c,os[op2],d,os[op3],b);
else if(a-b && OP(OP(OP(b,op1,c),op2,d),op3,a)==24 && op3==4)
print("%d%c%d%c%d%c%d=24\n",b,os[op1],c,os[op2],d,os[op3],a);
}
do
{ a=A[1];b=A[2];c=A[3];d=A[4];
DO(op1,1,2, op2,1,2, op3,0,0) {//(a±b±c)*d
if(OP(OP(a,op1,b),op2,c)*d==24 && !(op1==2 && op2==1) && !(op1==op2 && b<c))
print("(%d%c%d%c%d)%c%d=24\n",a,os[op1],b,os[op2],c,os[3],d);
}
if(op(OP(a,3,b),1,c)*d==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[1],c,os[3],d); //(a*b+c)*d
if(op(OP(a,3,b),2,c)*d==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[2],c,os[3],d); //(a*b-c)*d
DO(op1,1,2, op2,0,0, op3,1,4) {
if(op(OP(a,op1,b)*c,op3,d)==24 && !(op3==3 && c<d)) //(a±b)*c±d,(a±b)*c*d,(a±b)*c/d
print("(%d%c%d)%c%d%c%d=24\n",a,os[op1],b,os[3],c,os[op3],d);
if(op(OP(OP(a,op1,b),4,c),op3,d)==24 && op3<3) //(a±b)/c±d
print("(%d%c%d)%c%d%c%d=24\n",a,os[op1],b,os[4],c,os[op3],d);
}
DO(op1,3,4, op2,1,4, op3,1,2) {//a*b±c±d, a/b±c±d, a*b*c±d, a*b/c±d
if(op(op(OP(a,op1,b),op2,c),op3,d)==24 && !(op2==op3 && c<d) && !(op2==2 && op3==1)
&& !(op1*op2==9 && b<c) && !(op1==4 && op2==3)){
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[op3],d);
if(b==1 && op2<3||c==1 && op1==3)goto next; }
}
next:
if(op(op(OP(a,3,b),1,c),4,d)==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[1],c,os[4],d); //(a*b+c)/d
if(op(op(OP(a,3,b),2,c),4,d)==24)print("(%d%c%d%c%d)%c%d=24\n",a,os[3],b,os[2],c,os[4],d); //(a*b-c)/d
if(op(OP(c,2,OP(a,3,b)),3,d)==24)print("(%d%c%d%c%d)%c%d=24\n",c,os[2],a,os[3],b,os[3],d); //(c-a*b)*d
DO(op1,1,2, op2,1,2, op3,0,0) {
if(OP(OP(a,op1,b),3,OP(c,op2,d))==24) //(a±b)*(c±d)
print("(%d%c%d)%c(%d%c%d)=24\n",a,os[op1],b,os[3],c,os[op2],d);
if(OP(OP(a,op1,b),op2,OP(c,4,d))==24 && op2==2) //(a±b)-(c/d)
print("%d%c%d%c%d%c%d=24\n",a,os[op1],b,os[op2],c,os[4],d);
}
DO(op1,0,0, op2,1,2, op3,3,4) {
if(OP(OP(a,3,b),op2,OP(c,op3,d))==24) //(a*b)±(c*d), (a*b)±(c/d)
print("%d%c%d%c%d%c%d=24\n",a,os[3],b,os[op2],c,os[op3],d);
if(op3==4 && OP(OP(a,3,b),op3,OP(c,op2,d))==24) //(a*b)/(c±d)
print("%d%c%d%c(%d%c%d)=24\n",a,os[3],b,os[op3],c,os[op2],d);
}
// 以下涉及实型除法
for(op2=1;op2<=2;op2++) //(a/b±c)*d
if(op(a,op2,b*c)*d==24*b && b-1)
print("(%d%c%d%c%d)%c%d=24\n",a,os[4],b,os[op2],c,os[3],d);
if((b*c-a)*d==24*b && b-1) //(c-a/b)*d
print("(%d%c%d%c%d)%c%d=24\n",c,os[2],a,os[4],b,os[3],d);
if(d*b==(c*b-a)*24) //d/(c-a/b)
print("%d%c(%d%c%d%c%d)=24\n",d,os[4],c,os[2],a,os[4],b);
if(d*b==(a-c*b)*24) //d/(a/b±c)
print("%d%c(%d%c%d%c%d)=24\n",d,os[4],a,os[4],b,os[2],c);
}
while(quan_pai_lie(A+1,4));
if(!way)printf("failure(%d)\n",++noslv);//无效组合编号 458 for K
}
return(0);
}