#define FMAX 20 #define BMAX 100 #include #include #include int Ofs; // Offset=Minwert Bereich int RecursionF;//Anzeige der Rekursivaufrufe int NoOutF; //Anzeige ohne Ergebnisausgabe int DownF; //Richtung abwärts int PrintFastF=1; //schnellere Ausgabe char CArr[FMAX]; // Array für jeweilige Kombination int Fields; unsigned long CCounter; //Zähler für Anzahl Kombinationen unsigned long RCounter; //Zähler für Anzahl Rekursionen //-------------- char * appendNum(char *t,int n){ if(n<0){*t++='-';n=-n;} if(n>9){*t++='0'+(n/10);n%=10;} *t++='0'+n; *t++=','; *t=0; return t; } //-------------- void printfast(){ int f; char buf[4*FMAX+1]; char*t; t=buf; f=Fields; while (f){ t=appendNum(t,CArr[f]-'0'+Ofs); f--; } // *t++=10; *t=0; puts(buf); } //-------------- void printout(){ int f; CCounter++; if(NoOutF)return; if(PrintFastF){printfast();return;} f=Fields; while (f){ printf("%d,",CArr[f]-'0'+Ofs); f--; } printf("\n"); } //-------------- void listQCombis(int f,int q, int b){ int fr,qr,br; // Parameter für Rekursion int i,n,c; // Zählvariablen RCounter++; if(RecursionF){ printf(" f:%d q:%d b:%d \n ",f,q,b);} for(i=0;i <= b;i++){ n=(DownF)?b-i:i; CArr[f] ='0'+n; //eintragen if(n==q){ c=f; while(--c)CArr[c] ='0'; printout(); if(!DownF || f==1)return; } if(f==1){ //tiefste Rekursion erreicht if(n==q){ printout(); return;} } else{ qr=q-n; br=b; fr=f-1; if(!DownF && br > qr) br=qr; if(DownF && qr > (br*fr))continue; if( qr>0 )listQCombis(fr, qr, br); // Rekursion } }// for i } //-------------- int main(int argc,char **argv){ int f,q,b; char *s; if (argc<5){printf("Zu wenig Parameter: 1.Anzahl Felder 2.Minwert 3.Maxwert 4.gewünschte Quersumme\n"); return 5;} Fields=strtol(argv[1],0,10); //Anzahl Felder Ofs=strtol(argv[2],0,10); // Min Wert b=strtol(argv[3],0,10)-Ofs; //Maxwert q=strtol(argv[4],0,10)-(Ofs*Fields); // gewünschte Quersumme if(Fields > FMAX){printf("Zuviele Felder\n");return 1;} if(b > BMAX){printf("Zu großer Zahlenbereich\n");return 2;} if(q<0 || q > b*Fields ){printf("Quersumme muss zwischen %d und %d liegen \n",Ofs*Fields,(b+Ofs)*Fields);return 3;} if( b<0 || Fields<0){printf("b:%d Fields:%d negative Zahlen unzulässig \n",b,Fields);return 4;} if(q > b*Fields/2)DownF=1; if(argc==6){ s=argv[5]; if(strchr(s,'r')!=NULL){ RecursionF=1;} //Anzeige der Rekursivaufrufe if(strchr(s,'o')!=NULL){ NoOutF=1;} //Anzeige ohne Ergebnisausgabe if(strchr(s,'d')!=NULL){ DownF=1;} //Richtung abwärts if(strchr(s,'u')!=NULL){ DownF=0;} //Richtung aufwärts if(strchr(s,'s')!=NULL){ PrintFastF=0;} //slow = Ausgabe über printf } listQCombis(Fields, q, b); fprintf(stderr,"%lu Kombinationen mit %lu Rekursionen gefunden \n",CCounter,RCounter); return 0; }