void worker(int len, int lenc, int output_options, char* filename, char* filenamec, char* filenameA, int TC, int As, int GT, int Namps) { FILE* table=file_check(filename); // file is open to read if (table==NULL) exit(1); // if the file is not good we exit int i; gem* pool[len]; int pool_length[len]; pool[0]=malloc(2*sizeof(gem)); pool_length[0]=2; gem_init(pool[0] ,1,1.000000,1,0); // grade damage crit bbound gem_init(pool[0]+1,1,1.186168,0,1); // BB has more dmg int prevmax=pool_from_table(pool, pool_length, len, table); // killgem spec pool filling fclose(table); if (prevmax<len-1) { // if the killgems are not enough for (i=0;i<=prevmax;++i) free(pool[i]); // free if (prevmax>0) printf("Gem table stops at %d, not %d\n",prevmax+1,len); exit(1); } gem* poolf[len]; int poolf_length[len]; KGSPEC_COMPRESSION printf("Gem speccing pool compression done!\n"); FILE* tableA=file_check(filenameA); // fileA is open to read if (tableA==NULL) exit(1); // if the file is not good we exit int lena=len; // as long as the spec length gemY** poolY=malloc(lena*sizeof(gemY*)); int* poolY_length=malloc(lena*sizeof(int)); poolY[0]=malloc(sizeof(gemY)); poolY_length[0]=1; gem_init_Y(poolY[0],1,1,1); int prevmaxA=pool_from_table_Y(poolY, poolY_length, lena, tableA); // amps pool filling fclose(tableA); if (prevmaxA<lena-1) { for (i=0;i<=prevmaxA;++i) free(poolY[i]); // free if (prevmaxA>0) printf("Amp table stops at %d, not %d\n",prevmaxA+1,lena); exit(1); } gemY** poolYf=malloc(lena*sizeof(gemY*)); // if not malloc-ed 140k is the limit int poolYf_length[lena]; AMPS_COMPRESSION printf("Amp pool compression done!\n"); FILE* tablec=file_check(filenamec); // file is open to read if (tablec==NULL) exit(1); // if the file is not good we exit gem** poolc=malloc(lenc*sizeof(gem*)); int* poolc_length=malloc(lenc*sizeof(int)); poolc[0]=malloc(sizeof(gem)); poolc_length[0]=1; gem_init(poolc[0],1,1,1,1); int prevmaxc=pool_from_table(poolc, poolc_length, lenc, tablec); // killgem comb pool filling fclose(tablec); if (prevmaxc<lenc-1) { // if the killgems are not enough for (i=0;i<=prevmaxc;++i) free(poolc[i]); // free if (prevmaxc>0) printf("Gem table stops at %d, not %d\n",prevmaxc+1,lenc); exit(1); } gem bestc=(gem){0}; // choosing best combine for (i=0;i<poolc_length[lenc-1];++i) { if (gem_more_powerful(poolc[lenc-1][i], bestc)) { bestc=poolc[lenc-1][i]; } } double bestc_growth=log(gem_power(bestc))/log(lenc); printf("Combining pool compression done!\n\n"); int j,k,h; // let's choose the right gem-amp combo gem gems[len]; // for every speccing value gemY amps[len]; // we'll choose the best amps double powers[len]; gem_init(gems,1,1,1,0); gem_init_Y(amps,0,0,0); powers[0]=0; double crit_ratio =Namps*(0.15+As/3*0.004)*2*(1+0.03*TC)/(1.0+TC/3*0.1); double damage_ratio=Namps*(0.20+As/3*0.004) * (1+0.03*TC)/(1.2+TC/3*0.1); double NT=pow(2, GT-1); if (!(output_options & mask_quiet)) { printf("Killgem spec\n"); gem_print(gems); printf("Amplifier spec (x%d)\n", Namps); gem_print_Y(amps); printf("Spec base power: \t0\n\n\n"); } for (i=1;i<len;++i) { // for every gem value gems[i]=(gem){0}; // we init the gems amps[i]=(gemY){0}; // to extremely weak ones for (k=0;k<poolf_length[i];++k) { // first we compare the gem alone if (gem_power(poolf[i][k]) > gem_power(gems[i])) { gems[i]=poolf[i][k]; } } int NS=i+1; double C0 = pow(NT/(i+1), bestc_growth); // last we compute the combination number powers[i] = C0 * gem_power(gems[i]); // now we compare the whole setup for (j=0, NS+=Namps; j<i+1; ++j, NS+=Namps) { // for every amp value from 1 to to gem_value double Cg = pow(NT/NS, bestc_growth); // we compute the combination number for (k=0;k<poolf_length[i];++k) { // then in the gem pool double Pb2 = poolf[i][k].bbound * poolf[i][k].bbound; double Pdg = poolf[i][k].damage; double Pcg = poolf[i][k].crit ; for (h=0;h<poolYf_length[j];++h) { // and in the reduced amp pool double Pdamage = Pdg + damage_ratio* poolYf[j][h].damage ; double Pcrit = Pcg + crit_ratio * poolYf[j][h].crit ; double Pbase = Pb2 * Pdamage * Pcrit ; double power = Cg * Pbase; if (power>powers[i]) { powers[i]=power; gems[i]=poolf[i][k]; amps[i]=poolYf[j][h]; } } } } if (!(output_options & mask_quiet)) { printf("Killgem spec\n"); printf("Value:\t%d\n",i+1); if (output_options & mask_debug) printf("Pool:\t%d\n",poolf_length[i]); gem_print(gems+i); printf("Amplifier spec (x%d)\n", Namps); printf("Value:\t%d\n",gem_getvalue_Y(amps+i)); if (output_options & mask_debug) printf("Pool:\t%d\n",poolYf_length[gem_getvalue_Y(amps+i)-1]); gem_print_Y(amps+i); printf("Setup combine\n"); printf("Comb:\t%d\n",lenc); gem_print(&bestc); printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[i], amps[i], damage_ratio, crit_ratio)); printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[i]); } } if (output_options & mask_quiet) { // outputs last if we never seen any printf("Killgem spec\n"); printf("Value:\t%d\n",len); gem_print(gems+len-1); printf("Amplifier spec (x%d)\n", Namps); printf("Value:\t%d\n",gem_getvalue_Y(amps+len-1)); gem_print_Y(amps+len-1); printf("Setup combine\n"); printf("Comb:\t%d\n",lenc); printf("Growth:\t%f\n", bestc_growth); gem_print(&bestc); printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[len-1], amps[len-1], damage_ratio, crit_ratio)); printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[len-1]); } gem* gemf = gems+len-1; // gem that will be displayed gemY* ampf = amps+len-1; // amp that will be displayed gem* gemfc= &bestc; // gemc that will be displayed if (output_options & mask_upto) { double best_pow=0; int best_index=0; for (i=0; i<len; ++i) { if (powers[i] > best_pow) { best_index=i; best_pow=powers[i]; } } printf("Best setup up to %d:\n\n", len); printf("Killgem spec\n"); printf("Value:\t%d\n", gem_getvalue(gems+best_index)); gem_print(gems+best_index); printf("Amplifier spec (x%d)\n", Namps); printf("Value:\t%d\n", gem_getvalue_Y(amps+best_index)); gem_print_Y(amps+best_index); printf("Setup combine\n"); printf("Comb:\t%d\n",lenc); gem_print(gemfc); printf("Spec base power: \t%#.7g\n", gem_amp_power(gems[best_index], amps[best_index], damage_ratio, crit_ratio)); printf("Global power at g%d:\t%#.7g\n\n\n", GT, powers[best_index]); gemf = gems+best_index; ampf = amps+best_index; } gem* gem_array; gem red; if (output_options & mask_red) { if (len < 3) printf("I could not add red!\n\n"); else { int value = gem_getvalue(gemf); int valueA= gem_getvalue_Y(ampf); double NS = value + Namps*valueA; double amp_damage_scaled = damage_ratio * ampf->damage; double amp_crit_scaled = crit_ratio * ampf->crit; gemf = gem_putred(poolf[value-1], poolf_length[value-1], value, &red, &gem_array, amp_damage_scaled, amp_crit_scaled); printf("Setup with red added:\n\n"); printf("Killgem spec\n"); printf("Value:\t%d\n", value); // made to work well with -u gem_print(gemf); printf("Amplifier spec (x%d)\n", Namps); printf("Value:\t%d\n", valueA); gem_print_Y(ampf); printf("Setup combine\n"); printf("Comb:\t%d\n",lenc); gem_print(gemfc); printf("Spec base power with red:\t%#.7g\n", gem_amp_power(*gemf, *ampf, damage_ratio, crit_ratio)); double CgP = pow(NT/NS, bestc_growth); printf("Global power w. red at g%d:\t%#.7g\n\n\n", GT, CgP*gem_cfr_power(*gemf, amp_damage_scaled, amp_crit_scaled)); } } if (output_options & mask_parens) { printf("Killgem speccing scheme:\n"); print_parens_compressed(gemf); printf("\n\n"); printf("Amplifier speccing scheme:\n"); print_parens_compressed_Y(ampf); printf("\n\n"); printf("Setup combining scheme:\n"); print_parens_compressed(gemfc); printf("\n\n"); } if (output_options & mask_tree) { printf("Killgem speccing tree:\n"); print_tree(gemf, ""); printf("\n"); printf("Amplifier speccing tree:\n"); print_tree_Y(ampf, ""); printf("\n"); printf("Setup combining tree:\n"); print_tree(gemfc, ""); printf("\n"); } if (output_options & mask_table) print_omnia_table(gems, amps, powers, len); if (output_options & mask_equations) { // it ruins gems, must be last printf("Killgem speccing equations:\n"); print_equations(gemf); printf("\n"); printf("Amplifier speccing equations:\n"); print_equations_Y(ampf); printf("\n"); printf("Setup combining equations:\n"); print_equations(gemfc); printf("\n"); } for (i=0;i<len;++i) free(pool[i]); // free gems for (i=0;i<len;++i) free(poolf[i]); // free gems compressed for (i=0;i<lenc;++i) free(poolc[i]); // free gems free(poolc); free(poolc_length); for (i=0;i<lena;++i) free(poolY[i]); // free amps for (i=0;i<lena;++i) free(poolYf[i]); // free amps compressed free(poolY); free(poolY_length); free(poolYf); if (output_options & mask_red && len > 2) { free(gem_array); } }
void worker(int len, int output_options, char* filename) { FILE* table=file_check(filename); // file is open to read if (table==NULL) exit(1); // if the file is not good we exit int i; gem* gems=malloc(len*sizeof(gem)); // if not malloc-ed 230k is the limit gem* pool[len]; int pool_length[len]; pool[0]=malloc(sizeof(gem)); gem_init(gems,1,1,1); gem_init(pool[0],1,1,1); pool_length[0]=1; int prevmax=pool_from_table(pool, pool_length, len, table); // pool filling fclose(table); // close if (prevmax<len-1) { for (i=0;i<=prevmax;++i) free(pool[i]); // free free(gems); // free if (prevmax>0) printf("Table stops at %d, not %d\n",prevmax+1,len); exit(1); } if (!(output_options & mask_quiet)) gem_print(gems); for (i=1;i<len;++i) { int j; gems[i]=pool[i][0]; for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) { gems[i]=pool[i][j]; } if (!(output_options & mask_quiet)) { printf("Value:\t%d\n",i+1); if (output_options & mask_info) printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[i]); gem_print(gems+i); } } if (output_options & mask_quiet) { // outputs last if we never seen any printf("Value:\t%d\n",len); printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[len-1]); gem_print(gems+len-1); } gem* gemf=gems+len-1; // gem that will be displayed if (output_options & mask_upto) { double best_growth=-INFINITY; int best_index=0; for (i=0; i<len; ++i) { if (log(gem_power(gems[i]))/log(i+1) > best_growth) { best_index=i; best_growth=log(gem_power(gems[i]))/log(i+1); } } printf("Best gem up to %d:\n\n", len); printf("Value:\t%d\n",best_index+1); printf("Growth:\t%f\n", best_growth); gem_print(gems+best_index); gemf = gems+best_index; } gem* gem_array; gem red; if (output_options & mask_red) { if (len < 2) printf("I could not add red!\n\n"); else { int value=gem_getvalue(gemf); gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array); printf("Gem with red added:\n\n"); printf("Value:\t%d\n", value); // made to work well with -u printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value)); gem_print(gemf); } } if (output_options & mask_parens) { printf("Compressed combining scheme:\n"); print_parens_compressed(gemf); printf("\n\n"); } if (output_options & mask_tree) { printf("Gem tree:\n"); print_tree(gemf, ""); printf("\n"); } if (output_options & mask_table) print_table(gems, len); if (output_options & mask_equations) { // it ruins gems, must be last printf("Equations:\n"); print_equations(gemf); printf("\n"); } for (i=0;i<len;++i) free(pool[i]); // free free(gems); // free if (output_options & mask_red && len > 1) { free(gem_array); } }
void worker(int len, int output_options, int pool_zero) { printf("\n"); int i; int size; gem gems[len]; gem* pool[len]; int pool_length[len]; pool[0]=malloc(pool_zero*sizeof(gem)); pool_length[0]=pool_zero; if (pool_zero==1) { // combine gem_init(pool[0],1,1,1); gem_init(gems ,1,1,1); size=100; // reasonable comb sizing } else { // spec gem_init(pool[0] ,1,1,0); gem_init(pool[0]+1,1,0,1); gem_init(gems ,1,1,0); size=2000; // reasonable spec sizing } if (!(output_options & mask_quiet)) gem_print(gems); for (i=1; i<len; ++i) { int j,k,h,l; const int eoc=(i+1)/ (1+1); // end of combining const int j0 =(i+1)/(10+1); // value ratio < 10 int comb_tot=0; const int grade_max=(int)(log2(i+1)+1); // gems with max grade cannot be destroyed, so this is a max, not a sup gem* temp_pools[grade_max-1]; // get the temp pools for every grade int temp_index[grade_max-1]; // index of work point in temp pools gem* subpools[grade_max-1]; // get subpools for every grade int subpools_length[grade_max-1]; for (j=0; j<grade_max-1; ++j) { // init everything temp_pools[j]=malloc(size*sizeof(gem)); temp_index[j]=0; subpools[j]=NULL; // just to be able to free it subpools_length[j]=0; } for (j=j0; j<eoc; ++j) { // combine gems and put them in temp array for (k=0; k< pool_length[j]; ++k) { int g1=(pool[j]+k)->grade; for (h=0; h< pool_length[i-1-j]; ++h) { int delta=g1 - (pool[i-1-j]+h)->grade; if (abs(delta)<=2) { // grade difference <= 2 comb_tot++; gem temp; gem_combine(pool[j]+k, pool[i-1-j]+h, &temp); int grd=temp.grade-2; temp_pools[grd][temp_index[grd]]=temp; temp_index[grd]++; if (temp_index[grd]==size) { // let's skim a pool int length=size+subpools_length[grd]; gem* temp_array=malloc(length*sizeof(gem)); int index=0; for (l=0; l<temp_index[grd]; ++l) { // copy new gems temp_array[index]=temp_pools[grd][l]; index++; } temp_index[grd]=0; // temp index reset for (l=0; l<subpools_length[grd]; ++l) { // copy old gems temp_array[index]=subpools[grd][l]; index++; } free(subpools[grd]); // free gem_sort(temp_array,length); // work starts int broken=0; float lim_bbound=-1; for (l=length-1;l>=0;--l) { if ((int)(ACC*temp_array[l].bbound)<=(int)(ACC*lim_bbound)) { temp_array[l].grade=0; broken++; } else lim_bbound=temp_array[l].bbound; } // all unnecessary gems destroyed subpools_length[grd]=length-broken; subpools[grd]=malloc(subpools_length[grd]*sizeof(gem)); // pool init via broken index=0; for (l=0; l<length; ++l) { // copying to subpool if (temp_array[l].grade!=0) { subpools[grd][index]=temp_array[l]; index++; } } free(temp_array); // free } // rebuilt subpool[grd], work restarts } } } } int grd; for (grd=0; grd<grade_max-1; ++grd) { // let's put remaining gems on if (temp_index[grd] != 0) { int length=temp_index[grd]+subpools_length[grd]; gem* temp_array=malloc(length*sizeof(gem)); int index=0; for (l=0; l<temp_index[grd]; ++l) { // copy new gems temp_array[index]=temp_pools[grd][l]; index++; } for (l=0; l<subpools_length[grd]; ++l) { // copy old gems temp_array[index]=subpools[grd][l]; index++; } free(subpools[grd]); // free gem_sort(temp_array,length); // work starts int broken=0; float lim_bbound=-1; for (l=length-1;l>=0;--l) { if ((int)(ACC*temp_array[l].bbound)<=(int)(ACC*lim_bbound)) { temp_array[l].grade=0; broken++; } else lim_bbound=temp_array[l].bbound; } // all unnecessary gems destroyed subpools_length[grd]=length-broken; subpools[grd]=malloc(subpools_length[grd]*sizeof(gem)); // pool init via broken index=0; for (l=0; l<length; ++l) { // copying to subpool if (temp_array[l].grade!=0) { subpools[grd][index]=temp_array[l]; index++; } } free(temp_array); // free } // subpool[grd] is now full } pool_length[i]=0; for (grd=0; grd<grade_max-1; ++grd) pool_length[i]+=subpools_length[grd]; pool[i]=malloc(pool_length[i]*sizeof(gem)); int place=0; for (grd=0;grd<grade_max-1;++grd) { // copying to pool for (j=0; j<subpools_length[grd]; ++j) { pool[i][place]=subpools[grd][j]; place++; } } for (grd=0;grd<grade_max-1;++grd) { // free free(temp_pools[grd]); free(subpools[grd]); } gems[i]=pool[i][0]; // choosing gem (criteria moved to more_power def) for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) { gems[i]=pool[i][j]; } if (!(output_options & mask_quiet)) { printf("Value:\t%d\n",i+1); if (output_options & mask_info) printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1)); if (output_options & mask_debug) { printf("Raw:\t%d\n",comb_tot); printf("Pool:\t%d\n",pool_length[i]); } gem_print(gems+i); } } if (output_options & mask_quiet) { // outputs last if we never seen any printf("Value:\t%d\n",len); printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[len-1]); gem_print(gems+len-1); } gem* gemf=gems+len-1; // gem that will be displayed if (output_options & mask_upto) { double best_growth=-INFINITY; int best_index=0; for (i=0; i<len; ++i) { if (log(gem_power(gems[i]))/log(i+1) > best_growth) { best_index=i; best_growth=log(gem_power(gems[i]))/log(i+1); } } printf("Best gem up to %d:\n\n", len); printf("Value:\t%d\n",best_index+1); printf("Growth:\t%f\n", best_growth); gem_print(gems+best_index); gemf = gems+best_index; } gem* gem_array = NULL; gem red; if (output_options & mask_red) { if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n"); else { int value=gem_getvalue(gemf); gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0); printf("Gem with red added:\n\n"); printf("Value:\t%d\n", value); // made to work well with -u printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value)); gem_print(gemf); } } if (output_options & mask_parens) { printf("Compressed combining scheme:\n"); print_parens_compressed(gemf); printf("\n\n"); } if (output_options & mask_tree) { printf("Gem tree:\n"); print_tree(gemf, ""); printf("\n"); } if (output_options & mask_table) print_table(gems, len); if (output_options & mask_equations) { // it ruins gems, must be last printf("Equations:\n"); print_equations(gemf); printf("\n"); } for (i=0;i<len;++i) free(pool[i]); // free if (output_options & mask_red && len > 2 && pool_zero==2) { free(gem_array); } }
void worker(int len, int output_options, int pool_zero) { printf("\n"); int i; int size; const int ACC_TR=750; // 750 ACC_TR is for bbound comparisons inside tree gem gems[len]; gem* pool[len]; int pool_length[len]; pool[0]=malloc(pool_zero*sizeof(gem)); pool_length[0]=pool_zero; if (pool_zero==1) { // combine ACC=80; // ACC is for z-axis sorting and for the length of the interval tree gem_init(pool[0],1,1,1,1); // start gem does not matter gem_init(gems ,1,1,1,1); // grade damage crit bbound size=1000; // reasonable comb sizing } else { // spec ACC=60; // ACC is for z-axis sorting and for the length of the interval tree gem_init(pool[0] ,1,1.000000,1,0); gem_init(pool[0]+1,1,1.186168,0,1); // BB has more dmg gem_init(gems ,1,1.000000,1,0); // grade damage crit bbound size=20000; // reasonable spec sizing } if (!(output_options & mask_quiet)) gem_print(gems); for (i=1; i<len; ++i) { int j,k,h,l; const int eoc=(i+1)/ (1+1); // end of combining const int j0 =(i+1)/(10+1); // value ratio < 10 int comb_tot=0; int grade_max=(int)(log2(i+1)+1); // gems with max grade cannot be destroyed, so this is a max, not a sup gem* temp_pools[grade_max-1]; // get the temp pools for every grade int temp_index[grade_max-1]; // index of work point in temp pools gem* subpools[grade_max-1]; // get subpools for every grade int subpools_length[grade_max-1]; for (j=0; j<grade_max-1; ++j) { // init everything temp_pools[j]=malloc(size*sizeof(gem)); temp_index[j]=0; subpools[j]=NULL; // just to be able to free it subpools_length[j]=0; } for (j=j0; j<eoc; ++j) { // combine gems and put them in temp array for (k=0; k< pool_length[j]; ++k) { int g1=(pool[j]+k)->grade; for (h=0; h< pool_length[i-1-j]; ++h) { int delta=g1 - (pool[i-1-j]+h)->grade; if (abs(delta)<=2) { // grade difference <= 2 comb_tot++; gem temp; gem_combine(pool[j]+k, pool[i-1-j]+h, &temp); int grd=temp.grade-2; temp_pools[grd][temp_index[grd]]=temp; temp_index[grd]++; if (temp_index[grd]==size) { // let's skim a pool int length=size+subpools_length[grd]; gem* temp_array=malloc(length*sizeof(gem)); int index=0; float maxcrit=0; // this will help me create the minimum tree for (l=0; l<size; ++l) { // copy new gems temp_array[index]=temp_pools[grd][l]; maxcrit=max(maxcrit, (temp_array+index)->crit); index++; } temp_index[grd]=0; // temp index reset for (l=0; l<subpools_length[grd]; ++l) { // copy old gems temp_array[index]=subpools[grd][l]; maxcrit=max(maxcrit, (temp_array+index)->crit); index++; } free(subpools[grd]); // free gem_sort(temp_array,length); // work starts int broken=0; int crit_cells=(int)(maxcrit*ACC)+1; // this pool will be big from the beginning, but we avoid binary search int tree_length= 1 << (int)ceil(log2(crit_cells)); // this is pow(2, ceil()) bitwise for speed improvement int* tree=malloc((tree_length+crit_cells+1)*sizeof(int)); // memory improvement, 2* is not needed for (l=0; l<tree_length+crit_cells+1; ++l) tree[l]=-1; // init also tree[0], it's faster for (l=length-1;l>=0;--l) { // start from large z gem* p_gem=temp_array+l; int index=(int)(p_gem->crit*ACC); // find its place in x if (tree_check_after(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR))) { // look at y tree_add_element(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR)); } else { p_gem->grade=0; broken++; } } // all unnecessary gems destroyed free(tree); // free subpools_length[grd]=length-broken; subpools[grd]=malloc(subpools_length[grd]*sizeof(gem)); // pool init via broken index=0; for (l=0; l<length; ++l) { // copying to subpool if (temp_array[l].grade!=0) { subpools[grd][index]=temp_array[l]; index++; } } free(temp_array); // free } // rebuilt subpool[grd], work restarts } } } } int grd; for (grd=0; grd<grade_max-1; ++grd) { // let's put remaining gems on if (temp_index[grd] != 0) { int length=temp_index[grd]+subpools_length[grd]; gem* temp_array=malloc(length*sizeof(gem)); int index=0; float maxcrit=0; // this will help me create the minimum tree for (l=0; l<temp_index[grd]; ++l) { // copy new gems temp_array[index]=temp_pools[grd][l]; maxcrit=max(maxcrit, (temp_array+index)->crit); index++; } for (l=0; l<subpools_length[grd]; ++l) { // copy old gems temp_array[index]=subpools[grd][l]; maxcrit=max(maxcrit, (temp_array+index)->crit); index++; } free(subpools[grd]); // free gem_sort(temp_array,length); // work starts int broken=0; int crit_cells=(int)(maxcrit*ACC)+1; // this pool will be big from the beginning, but we avoid binary search int tree_length= 1 << (int)ceil(log2(crit_cells)); // this is pow(2, ceil()) bitwise for speed improvement int* tree=malloc((tree_length+crit_cells+1)*sizeof(int)); // memory improvement, 2* is not needed for (l=0; l<tree_length+crit_cells+1; ++l) tree[l]=-1; // init also tree[0], it's faster for (l=length-1;l>=0;--l) { // start from large z gem* p_gem=temp_array+l; int index=(int)(p_gem->crit*ACC); // find its place in x if (tree_check_after(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR))) { // look at y tree_add_element(tree, tree_length, index, (int)(p_gem->bbound*ACC_TR)); } else { p_gem->grade=0; broken++; } } // all unnecessary gems destroyed free(tree); // free subpools_length[grd]=length-broken; subpools[grd]=malloc(subpools_length[grd]*sizeof(gem)); // pool init via broken index=0; for (l=0; l<length; ++l) { // copying to subpool if (temp_array[l].grade!=0) { subpools[grd][index]=temp_array[l]; index++; } } free(temp_array); // free } // subpool[grd] is now full } pool_length[i]=0; for (grd=0; grd<grade_max-1; ++grd) pool_length[i]+=subpools_length[grd]; pool[i]=malloc(pool_length[i]*sizeof(gem)); int place=0; for (grd=0;grd<grade_max-1;++grd) { // copying to pool for (j=0; j<subpools_length[grd]; ++j) { pool[i][place]=subpools[grd][j]; place++; } } for (grd=0;grd<grade_max-1;++grd) { // free free(temp_pools[grd]); free(subpools[grd]); } gems[i]=pool[i][0]; // choosing gem (criteria moved to more_power def) for (j=1;j<pool_length[i];++j) if (gem_more_powerful(pool[i][j],gems[i])) { gems[i]=pool[i][j]; } if (!(output_options & mask_quiet)) { printf("Value:\t%d\n",i+1); if (output_options & mask_info) printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1)); if (output_options & mask_debug) { printf("Raw:\t%d\n",comb_tot); printf("Pool:\t%d\n",pool_length[i]); } gem_print(gems+i); } } if (output_options & mask_quiet) { // outputs last if we never seen any printf("Value:\t%d\n",len); printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[len-1]); gem_print(gems+len-1); } gem* gemf=gems+len-1; // gem that will be displayed if (output_options & mask_upto) { double best_growth=-INFINITY; int best_index=0; for (i=0; i<len; ++i) { if (log(gem_power(gems[i]))/log(i+1) > best_growth) { best_index=i; best_growth=log(gem_power(gems[i]))/log(i+1); } } printf("Best gem up to %d:\n\n", len); printf("Value:\t%d\n",best_index+1); printf("Growth:\t%f\n", best_growth); gem_print(gems+best_index); gemf = gems+best_index; } gem* gem_array; gem red; if (output_options & mask_red) { if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n"); else { int value=gem_getvalue(gemf); gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0, 0); printf("Gem with red added:\n\n"); printf("Value:\t%d\n", value); // made to work well with -u printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value)); gem_print(gemf); } } if (output_options & mask_parens) { printf("Compressed combining scheme:\n"); print_parens_compressed(gemf); printf("\n\n"); } if (output_options & mask_tree) { printf("Gem tree:\n"); print_tree(gemf, ""); printf("\n"); } if (output_options & mask_table) print_table(gems, len); if (output_options & mask_equations) { // it ruins gems, must be last printf("Equations:\n"); print_equations(gemf); printf("\n"); } for (i=0;i<len;++i) free(pool[i]); // free if (output_options & mask_red && len > 2 && pool_zero==2) { free(gem_array); } }
void worker(int len, int output_options, int pool_zero, char* filename) { FILE* table=file_check(filename); // file is open to read if (table==NULL) exit(1); // if the file is not good we exit int i; gem* gems=malloc(len*sizeof(gem)); // if not malloc-ed 230k is the limit gem** pool=malloc(len*sizeof(gem*)); int* pool_length=malloc(len*sizeof(int)); pool[0]=malloc(pool_zero*sizeof(gem)); pool_length[0]=pool_zero; if (pool_zero==1) { // combine gem_init(pool[0],1,1,1,1); // start gem does not matter gem_init(gems ,1,1,1,1); // grade damage crit bbound } else { // spec gem_init(pool[0] ,1,DAMAGE_CRIT ,1,0); gem_init(pool[0]+1,1,DAMAGE_BBOUND,0,1); // BB has more dmg gem_init(gems ,1,DAMAGE_CRIT ,1,0); // grade damage crit bbound } int prevmax=pool_from_table(pool, pool_length, len, table); // pool filling fclose(table); // close if (prevmax<len-1) { for (i=0;i<=prevmax;++i) free(pool[i]); // free free(pool); // free free(pool_length); // free free(gems); // free if (prevmax>0) printf("Table stops at %d, not %d\n",prevmax+1,len); exit(1); } int skip_computations = (output_options & mask_quiet) && !((output_options & mask_table) || (output_options & mask_upto)); int first = skip_computations ? len-1 : 0; for (i=first; i<len; ++i) { gems[i]=pool[i][0]; for (int j=1; j<pool_length[i]; ++j) { if (gem_more_powerful(pool[i][j],gems[i])) { gems[i]=pool[i][j]; } } if (!(output_options & mask_quiet)) { printf("Value:\t%d\n",i+1); if (output_options & mask_info) printf("Growth:\t%f\n", log(gem_power(gems[i]))/log(i+1)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[i]); gem_print(gems+i); } } if (output_options & mask_quiet) { // outputs last if we never seen any printf("Value:\t%d\n",len); printf("Growth:\t%f\n", log(gem_power(gems[len-1]))/log(len)); if (output_options & mask_debug) printf("Pool:\t%d\n",pool_length[len-1]); gem_print(gems+len-1); } gem* gemf=gems+len-1; // gem that will be displayed if (output_options & mask_upto) { double best_growth=-INFINITY; int best_index=0; for (i=0; i<len; ++i) { if (log(gem_power(gems[i]))/log(i+1) > best_growth) { best_index=i; best_growth=log(gem_power(gems[i]))/log(i+1); } } printf("Best gem up to %d:\n\n", len); printf("Value:\t%d\n",best_index+1); printf("Growth:\t%f\n", best_growth); gem_print(gems+best_index); gemf = gems+best_index; } gem* gem_array = NULL; gem red; if (output_options & mask_red) { if (len < 3 || pool_zero!=2) printf("I could not add red!\n\n"); else { int value=gem_getvalue(gemf); gemf = gem_putred(pool[value-1], pool_length[value-1], value, &red, &gem_array, 0, 0); printf("Gem with red added:\n\n"); printf("Value:\t%d\n", value); // made to work well with -u printf("Growth:\t%f\n", log(gem_power(*gemf))/log(value)); gem_print(gemf); } } if (output_options & mask_parens) { printf("Compressed combining scheme:\n"); print_parens_compressed(gemf); printf("\n\n"); } if (output_options & mask_tree) { printf("Gem tree:\n"); print_tree(gemf, ""); printf("\n"); } if (output_options & mask_table) print_table(gems, len); if (output_options & mask_equations) { // it ruins gems, must be last printf("Equations:\n"); print_equations(gemf); printf("\n"); } for (i=0;i<len;++i) free(pool[i]); // free free(pool); free(pool_length); free(gems); if (output_options & mask_red && len > 2 && pool_zero==2) { free(gem_array); } }