1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#include <iostream>
#include <math.h>
#include <string>
//THE PROBLEM: Write a program that outputs all possibilities to put + or - or nothing between the numbers 1, 2, ..., 9 (in this order) such that the result is always 100.
//For example: 1 + 2 + 34 – 5 + 67 – 8 + 9 = 100.
//(from http://www.shiftedup.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour)
//OUTPUT OF THIS PROGRAM (only prints lines that total 100):
//1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 a a a a a
//1 + 2 + 34 - 5 + 67 - 8 + 9 a a a a a a a
//(plus 9 more for 11 total... I would paste all but don't know how to copy paste from output window which is annoying)
//MY DESCRIBED SOLUTION (I'm new to c++ so show me what to do better)
//9 numbers: 1,2,3,4,5,6,7,8,9 have 8 gaps between them. Fill gaps with every possible permutation of either a minus sign, a plus sign or a "concatenate sign". Since those are 3 choices and 8 gaps, that means
//you need all possible 8 digit ternary (base 3) numbers... 00000000,00000001,00000002,00000010 etc.. to fill gaps every possible way. 0 will represent +, 1 will be -, and 3 will be concatenate (means fuse like 3,4 becomes 34 etc)
//calculate every total this way and only print ones that = 100
//this function adds 1 to the base-3 number, 00000012 becomes 00000020 etc. it was annoying that "tris" array in this function had a name conflict with external "tris" array, so named external "ttris"
//8 nested ifs is probably dumb but I'm new to c++
int triinc(int tris[8]){
tris[7]++;
if (tris[7]==3){
tris[7]=0;
tris[6]++;
if (tris[6]==3){
tris[6]=0;
tris[5]++;
if (tris[5]==3){
tris[5]=0;
tris[4]++;
if (tris[4]==3){
tris[4]=0;
tris[3]++;
if (tris[3]==3){
tris[3]=0;
tris[2]++;
if (tris[2]==3){
tris[2]=0;
tris[1]++;
if (tris[1]==3){
tris[1]=0;
tris[0]++;
if (tris[0]==3){
tris[0]=0;
}
}
}
}
}
}
}
}
}
//again annoying to name parameters different to avoid name conflicts.
int process(int ops[8],int ns[9]){
//ops will be the 8 long list of base 3 numbers (0=+, 1=-, 2=concatenate)
//ns is {1,2,3,4,5,6,7,8,9}
//nstrs stands for number strings (because you can concatenate strings easily by adding them). I "pack" it full of letter "a"s to represent emptiness, before I fill it with numbers like 1, 2 or concatenated 34, etc
//addsubs is another a packed empty list that will be left packed with list of ordered + or - operations only
std::string nstrs[10]={std::to_string(ns[0]),"a","a","a","a","a","a","a","a","a"};
std::string addsubs[10]={"a","a","a","a","a","a","a","a","a","a"};
//these are indexes of above arrays respectively
int nstrsi=0;
int addsubsi=0;
int i;
for (i=0;i<8;i++){
//concatenate to previous number if 2
if (ops[i]==2){
nstrs[nstrsi]+=std::to_string(ns[i+1]);
}
//if 0 or 1 add appropriate + or - symbol to addsubs, and add string number to next index of nstrs
else if (ops[i]==1){
addsubs[addsubsi]='-';
addsubsi++;
nstrsi++;
nstrs[nstrsi]=std::to_string(ns[i+1]);
}
else if (ops[i]==0){
addsubs[addsubsi]='+';
addsubsi++;
nstrsi++;
nstrs[nstrsi]=std::to_string(ns[i+1]);
}
}
//now nstrs and addsubs lists are created, so see if they total 100
int total=std::stoi(nstrs[0]);
i=0;
while (addsubs[i]!="a"){
if(addsubs[i]=="+"){
total+=std::stoi(nstrs[i+1]);
}
else if(addsubs[i]=="-"){
total-=std::stoi(nstrs[i+1]);
}
i++;
}
//print out if total==100
if (total==100){
for(i=0;i<10;i++){
std::cout<<nstrs[i]<<" "<<addsubs[i]<<" ";
}
std::cout<<"\n";
}
}
int main(){
int i;
//8 digit ternary (base 3) numbers... 00000000,00000001,00000002,00000010 etc.. 0 will represent +, 1 will be -, and 3 will be concatenate (means fuse like 3,4 becomes 34 etc)
int ttris[8]={0,0,0,0,0,0,0,0};
int nums[9]={1,2,3,4,5,6,7,8,9};
bool running=true;
int ccount=0;
while(running){
process(ttris,nums);
triinc(ttris);
//was annoying I couldn't easily compare equality of 2 arrays in below line
//if (tris=={2,2,2,2,2,2,2,2}){
ccount++;
if (ccount>=pow(3,8)-1){
running=false;
}
}
}
|