int countNumbersWithUniqueDigits(int n) { if(n<0 || n >= 11) return 0; int count[11]; memset(count, 0, sizeof(count)); count[0] = 1; int fact[11]; memset(fact, 0, sizeof(fact)); fact[0] = 1; for(int i=1;i<=10;i++){ fact[i] = fact[i-1]*i; } return countUnique(n,count,fact); }
int countUnique(int n, int count[], int fact[]) { if(count[n] != 0) return count[n]; //the only cases are 1 to 10. //e.g, for n = 5, the numbers have to be <= 99999 //all the numbers in n=4,3,2,1 are counted. //thus f[n] = f[0]+f[1]+...+f[n-1], and then some. //in the case of n = 5, the numbers start from 10000-99999. //so the answer is, choose 5 digits //if the first digit is a 0, remove those from the count. //i.e. 10 choose 5 - 9 choose 5. count[n] = countUnique(n-1, count, fact) + (fact[9]*9)/(fact[10-n]); return count[n]; }
int main(int argc, char **argv) { argc = AS_configure(argc, argv); merylArgs *args = new merylArgs(argc, argv); gkpStoreFile::registerFile(); gkpStoreChain::registerFile(); switch (args->personality) { case 'P': estimate(args); break; case 'B': build(args); break; case 'd': dumpDistanceBetweenMers(args); break; case 't': dumpThreshold(args); break; case 'p': dumpPositions(args); break; case 'c': countUnique(args); break; case 'h': plotHistogram(args); break; case PERSONALITY_MIN: case PERSONALITY_MINEXIST: case PERSONALITY_MAX: case PERSONALITY_MAXEXIST: case PERSONALITY_ADD: case PERSONALITY_AND: case PERSONALITY_NAND: case PERSONALITY_OR: case PERSONALITY_XOR: multipleOperations(args); break; case PERSONALITY_SUB: case PERSONALITY_ABS: case PERSONALITY_DIVIDE: binaryOperations(args); break; case PERSONALITY_LEQ: case PERSONALITY_GEQ: case PERSONALITY_EQ: unaryOperations(args); break; default: args->usage(); fprintf(stderr, "%s: unknown personality. Specify -P, -B, -S or -M!\n", args->execName); exit(1); break; } delete args; return(0); }
// test_function_countUnique // Test suite for function template countUnique // Pre: None. // Post: // Pass/fail status of tests have been registered with t. // Appropriate messages have been printed to cout. // Does not throw (No-Throw Guarantee) void test_function_countUnique(Tester & t) { std::cout << "Test Suite: function template countUnique (Exercise C)" << std::endl; std::deque<int> di { 1, 1, 2, 1, 2, 2, 3, -1, -1, -1, 5, 3, 3, 3, 2, 2, 1, 1, 1 }; std::deque<int> dic; // Check return type of countUnique dic = di; t.test(TypeCheck<std::size_t>::check( countUnique(dic.begin(), dic.end())), "countUnique: return type"); dic = di; t.test(countUnique(dic.rbegin(), dic.rbegin()) == 0, "Empty range"); dic = di; t.test(countUnique(dic.rbegin()+3, dic.rbegin()+4) == 1, "Size 1"); dic = di; t.test(countUnique(dic.rbegin()+3, dic.rbegin()+5) == 1, "Size 2, equal integers"); dic = di; t.test(countUnique(dic.rbegin()+4, dic.rbegin()+6) == 2, "Size 2, distinct integers"); dic = di; t.test(countUnique(dic.rbegin()+9, dic.rbegin()+12) == 1, "Size 3, equal integers"); dic = di; t.test(countUnique(dic.rbegin()+7, dic.rbegin()+10) == 3, "Size 3, distinct integers"); dic = di; t.test(countUnique(dic.rbegin()+8, dic.rbegin()+11) == 2, "Size 3, two values"); dic = di; t.test(countUnique(dic.rbegin()+5, dic.rbegin()+13) == 3, "Longer test #2"); dic = di; t.test(countUnique(dic.rbegin()+3, dic.rbegin()+15) == 4, "Longer test #2"); dic = di; t.test(countUnique(dic.rbegin(), dic.rend()) == 5, "Longer test #3"); { std::deque<int> di2(100000, 3); t.test(countUnique(di2.rbegin(), di2.rend()) == 1, "Very long test #1"); } { std::deque<int> di2(100000, 4); di2[40000] = 3; t.test(countUnique(di2.rbegin(), di2.rend()) == 2, "Very long test #2"); } { std::deque<int> di2(100000, 4); for (size_t i = 0; i != 100000; i += 2) di2[i] = 3; t.test(countUnique(di2.rbegin(), di2.rend()) == 2, "Very long test #3"); } { std::vector<std::string> vs { "abc", "abc" }; t.test(countUnique(vs.begin(), vs.end()) == 1, "Strings, equal"); } { std::vector<std::string> vs { "abc", "def" }; t.test(countUnique(vs.begin(), vs.end()) == 2, "Strings, distinct"); } }