Code:
//1. Write a function that given a string of digits and a target value, prints where to put +'s and *'s between the digits so they combine exactly to the target value. Note there may be more than one answer, it doesn't matter which one you print.
//Examples:
//"1231231234",11353 -> "12*3+1+23*123*4"
//"3456237490",1185 -> "3*4*56+2+3*7+490"
//"3456237490",9191 -> "no solution"
//
//Solution:
#include <stdio.h>
#include <string.h>
const char symb[3]= {'+','*',' '};
void print_sequence(FILE* file, char* deststr, int nchar)
{
int i;
for(i=0; i<nchar && deststr[i]!='\0'; i++) {
if(deststr[i]==' ') continue;
fprintf(file, "%c", deststr[i]);
}
return;
}
void transform_n_check(char* deststr, const int ndigs, const int target, short *done) {
char strcopy[ndigs*2];
char* add[ndigs];
char *p;
int i= 0;
int total= 0;
for(i=0; i<ndigs*2; i++)
strcopy[i]= deststr[i];
// find all the addends
i= 0;
add[i]= strtok(strcopy, "+");
while( (p=strtok(NULL,"+")) != NULL ) {
add[++i]= p;
}
int na= i+1;
char *mult[ndigs];
int totmult;
for(i=0; i<na; i++) {
// find all the multiplications composing this addend
int j= 0;
mult[j]= strtok(add[i],"*");
while( (p=strtok(NULL,"*")) != NULL ) {
mult[++j]= p;
}
int nm= j+1;
// multiply the multiplicands of this addend together
totmult= 1;
for(j=0; j<nm; j++) {
int k;
int temp= 0;
for(k=0; k<strlen(mult[j]); k++) { // atoi skipping spaces indicating "no operator"
if(mult[j][k]==' ') continue;
temp*= 10;
temp+= mult[j][k]-'0';
}
totmult*= temp;
}
total+= totmult;
}
*done= (total==target);
return;
}
void build(int level, char *deststr, const int ndigs, const int target, short* done) {
if(level==ndigs-1) {
transform_n_check(deststr, ndigs, target, done);
// if(*done) {
// print_sequence(stdout,deststr,ndigs*2-1);
// }
return;
}
int ns;
for(ns=0; ns<3 && !*done; ns++) { // !*done avoids printing multiple solutions
deststr[level2pos(level)]= symb[ns];
build(level+1,deststr,ndigs,target,done);
}
// if(level==0 && !*done)
// strcpy(deststr,"no solution");
return;
}
int level2pos(const int level) {
return level*2+1;
}
void calculus(char* str, const int target) {
const int ndigs= strlen(str);
int totdlen= ndigs*2-1;
char deststr[totdlen+1];
int i;
for(i=0; i<ndigs; i++) {
deststr[i*2]= str[i];
deststr[i*2+1]= '!';
}
deststr[totdlen]= '\0';
int ncombs= 3^(ndigs-1);
// str= "1234"
// deststr= "1+2+3+4"
printf("\"%s\", %d -> \"", str, target);
short done= 0;
build(0, deststr, ndigs, target, &done);
if(done)
print_sequence(stdout,deststr,totdlen*2);
else
printf("no solution");
printf("\"\n");
return;
}
int main() {
calculus("1234",408);
calculus("1231231234",11353); // "12*3+1+23*123*4"
calculus("3456237490",1185); // "3*4*56+2+3*7+490"
calculus("3456237490",9191); // "no solution"
}
Bookmarks