TEST(PermutationTest, OutputOperator) { std::stringstream ss; ss << Permutation(create_image(6, 0, 2, 3, 1, 5, 4)); EXPECT_STREQ("(1 2 3)(4 5)", ss.str().c_str()); ss.str(""); ss << Permutation(); EXPECT_STREQ("Id", ss.str().c_str()); }
TEST(PermutationTest, Multiplication) { Permutation p = Permutation(create_image(3, 1, 0, 2)); Permutation q = Permutation(create_image(3, 0, 2, 1)); Permutation product = p * q; EXPECT_EQ(1, product(0)); EXPECT_EQ(2, product(1)); EXPECT_EQ(0, product(2)); }
int FixedPointNoise::operator()(int x) { unsigned char gx = x >> 12; x &= I-1; int fx = MathUtils::Fade(x); unsigned char p0 = Permutation(gx); unsigned char p1 = Permutation(gx+1); return MathUtils::ILerp(fx,Grad(p0, x),Grad(p1, x-I)); }
BOOST_AUTO_TEST_CASE_TEMPLATE( inequality, Permutation, ptypes ) { // const auto& p = fixture<Permutation>().p; const auto& p201 = fixture<Permutation>().p201; const auto& p102 = fixture<Permutation>().p102; const auto& p120 = fixture<Permutation>().p120; const auto& p021 = fixture<Permutation>().p021; Permutation p0213({0,2,1,3}); // Check that different permutations are not equal BOOST_CHECK( p102 != p201 ); // Check that identical permutations are not, not equal BOOST_CHECK( ! (p102 != p102) ); BOOST_CHECK( ! (Permutation({1,0,2}) != p102) ); // Check that permutations of equal size with different elements are not equal BOOST_CHECK( p120 != p021); BOOST_CHECK( p021 != p120); // Compare permutations of different sizes with the same leading elements // TA::Permutation has fixed domain size, hence these are not equal if (std::is_same<Permutation,TiledArray::Permutation>::value) { BOOST_CHECK( p021 != p0213); BOOST_CHECK( p0213 != p021); } // TA::symmetry::Permutation does not fix the domain size, hence these are equal if (std::is_same<Permutation,TiledArray::symmetry::Permutation>::value) { BOOST_CHECK( not (p021 != p0213)); BOOST_CHECK( not (p0213 != p021)); } }
void Permutation(int columnIndex[], int length, int index, int* count) { int i, temp; if(index == length) { if(Check(columnIndex, length) != 0) { (*count)++; } } else { for(i = index; i < length; ++ i) { temp = columnIndex[i]; columnIndex[i] = columnIndex[index]; columnIndex[index] = temp; Permutation(columnIndex, length, index + 1, count); temp = columnIndex[index]; columnIndex[index] = columnIndex[i]; columnIndex[i] = temp; } } }
balazs::Permutation balazs::WeighedTree::getPairing() const { std::vector<std::size_t> pairing; pairing.reserve(2 * numEdges()); fillInPairing(pairing, m_root); return Permutation(pairing); }
TEST(PermutationTest, Inverse) { Permutation p = Permutation(create_image(3, 1, 2, 0)); Permutation inverse = p.inverse(); EXPECT_EQ(2, inverse(0)); EXPECT_EQ(0, inverse(1)); EXPECT_EQ(1, inverse(2)); }
int EightQueen() { int columnIndex[8] = {0, 1, 2, 3, 4, 5, 6, 7}; int count = 0; Permutation(columnIndex, 8, 0, &count); return count; }
TEST(PermutationTest, Base) { static const unsigned int max_base = 100; Permutation id; for (unsigned int n = 0; n < max_base; ++n) { EXPECT_EQ(n, id(n)); } Permutation p = Permutation(create_image(5, 1, 2, 3, 4, 0)); for (unsigned int n = 5; n < max_base; ++n) { EXPECT_EQ(n, p(n)); } }
StabChain_PermGroup(Obj _group, StabChainConfig _config, PartitionStack* ps, MemoryBacktracker* mb, MemoryBacktracker* rbase_mb) : AbstractConstraint(ps), config(_config), scc(_group), last_permutation(mb->makeRevertingStack<Permutation>()), last_depth(mb->makeReverting<int>()) { tracking_first_found_orbits = Reverting<int>(rbase_mb->makeReverting<int>(-2)); tracking_first_found_blocks = Reverting<int>(rbase_mb->makeReverting<int>(-2)); tracking_first_found_orbitals = Reverting<int>(rbase_mb->makeReverting<int>(-2)); // We set up our 'reverting' at the start last_depth.set(-1); last_permutation.push_back(Permutation()); debug_out(3, "scpg", "Setup"); }
// all elem should be swap with itself. For example, "abc" is swapped three times. void Permutation(char *pStr, char *pBegin) { static int cnt = 0; if (*pBegin == '\0') /// I miss the '*' here, then debug for a long time!!! { cnt++; printf("%4d: %s\n", cnt, pStr); } else { for (char *pCh = pBegin; *pCh != '\0'; ++pCh) { swap(*pCh, *pBegin); Permutation(pStr, pBegin + 1); /// the most important line swap(*pCh, *pBegin); } } }
// 此题看过答案后理解出来的 void Permutation(char *str, char *begin) { if (!str || *str == '\0') return; if (*begin == '\0') { printf("%s\n", str); } else { for (char *p = begin; *p != '\0'; ++p) { char temp = *p; *p = *begin; *begin = temp; Permutation(str, begin+1); temp = *p; *p = *begin; *begin = temp; } } }
///////////////////////////////////////////////////////////////////// //// // Print the permutation of a string, // Input: pStr - input string // pBegin - points to the begin char of string // which we want to permutate in this recursion ///////////////////////////////////////////////////////////////////// //// void Permutation(char* pStr, char* pBegin) { if (!pStr || !pBegin) return; // if pBegin points to the end of string, // this round of permutation is finished, // print the permuted string if (*pBegin == '\0') { printf("%s\n", pStr); } // otherwise, permute string else { for (char* pCh = pBegin; *pCh != '\0'; ++pCh) { // swap pCh and pBegin char temp = *pCh; *pCh = *pBegin; *pBegin = temp; std::cout << "swap1:pch--pbegin " << *pCh << "- " << *pBegin << std::endl; //test std::cout << "permutation1() : "<<*pStr<<" - "<<*(pBegin+1) << std::endl; Permutation(pStr, pBegin + 1); //test: std::cout << "swap2:pch--pbegin " << *pCh << "- " << *pBegin << std::endl; // restore pCh and pBegin temp = *pCh; *pCh = *pBegin; *pBegin = temp; } std::cout << "for()done" << std::endl; std::cout << std::endl; } }
// print the permutation of a string // input: pStr - input string // pBegin - points to the begin char of string // which we want to permutate in this recursion void Permutation(char* pStr, char* pBegin){ if(!pStr || !pBegin) return; // if pBegin points to the end of string, // this round of permutation is finished // print the permuted string if(*pBegin == '\0') printf("%s\n", pStr); // otherwise, permute string else{ for(char* pCh = pBegin; *pCh != '\0'; ++ pCh){ // swap pCh and pBegin char temp = *pCh; *pCh= *pBegin; *pBegin = temp; Permutation(pStr, pBegin + 1); // restore pCh and pBegin temp = *pCh; *pCh = *pBegin; *pBegin = temp; } } }
int FixedPointNoise::operator()(int x, int y) { unsigned char gx = x >> 12; unsigned char gy = y >> 12; x &= I-1; y &= I-1; int fx = MathUtils::Fade(x); int fy = MathUtils::Fade(y); unsigned char p0 = Permutation(gx)+gy; unsigned char p1 = Permutation(gx+1)+gy; unsigned char p00 = Permutation(p0); unsigned char p01 = Permutation(p0+1); unsigned char p10 = Permutation(p1); unsigned char p11 = Permutation(p1+1); return MathUtils::ILerp(fy, MathUtils::ILerp(fx,Grad(p00,x,y),Grad(p10, x-I, y)), MathUtils::ILerp(fx,Grad(p01, x, y-I),Grad(p11, x-I, y-I))); }
int main(int argc, char *argv[]) { vector<HeuristicChooseReversal *> hcr_seq; /* Set random seed */ unsigned long seed = mix(clock(), time(NULL), getpid()); /* Set random seed */ srand(seed); /* Exact Unitaty Parameters */ ofstream fout; /* Time results */ timestamp_t time_begin; timestamp_t time_end; time_begin = get_timestamp(); /* Log result file */ ostream *logOut = NULL; ostream *logTime = NULL; /* Check essential parameters */ // TODO: start to use parameter names instead of parameter sequence, ex: -p 1,2,4... if (argc < 7) { printf("Usage:\n"); printf("lwr_test_metaheuristic permutation number_of_iteration inversion_limit frame_limit is_signed cost_function {-r=[[...]]}.\n\n"); printf("Parameters description:\n"); printf(" 1. permutation: the input permutation.\n\n"); printf(" 2. number_of_iteration: number of iterations that will\n"); printf("be performed by the Metaheuristic.\n\n"); printf(" 3. inversion_limit: limit (upper bound) for the number of inversions\n"); printf("that will be selected at each iteration of the heuristic for building solutions.\n\n"); printf(" 4. frame_limit: percentege (in the interval (0,100]) of frames that \n"); printf("will be selected at each iteration of the Metaheuristic.\n\n"); printf(" 5. is_signed: 1 if the input permutation is signed, 0 otherwise.\n\n"); printf(" 6. cost_function: 1 for linear function, 2 for quadratic function and 3 logaritmic function.\n\n"); printf(" 7. -r=[[...]]: Optional parameter to give a seed solution as a input parameter\n"); return 0; } /* Seed result */ Result seed_result; /* Permutation parameters */ parameter perm_param; /* Exact Unitary parameters */ parameter exactP; /* Improve parameters */ parameter improveP; /* ChooseHeuristic parameters*/ parameter hcrP; /* list of solvers for choose reversals */ vector<Solver *> solver_hcr; string intervalMethod = "WINDOW"; string heuristicReversalsName = "BenefitLoss"; /* -------------------Read the parameters From terminal----------------- */ int p_read = 1; // Read the permutation's sequence vector<ll> perm_seq = read_seq(argv[p_read++]); int num_it; sscanf(argv[p_read++], "%d", &num_it); int inv_limit; sscanf(argv[p_read++], "%d", &inv_limit); double frame_limit; sscanf(argv[p_read++], "%lf", &frame_limit); int is_signed; sscanf(argv[p_read++], "%d", &is_signed); int cost_function; sscanf(argv[p_read++], "%d", &cost_function); /* Construct the permutation */ if (is_signed) { perm_param = getSignedParameters(); } else { perm_param = getUnsignedGraspParameters(); } Permutation perm = Permutation(perm_param, perm_seq); // makes a copy from the original input permutation and set the normal mode Permutation perm_orig = perm; // Look for a input solution Result input_seed_result; bool has_input_seed_result = false; if (p_read < argc) { string solution = string(argv[p_read++]); if (solution.substr(0, 2) == "-r") { // in this caseheuristicName is supposed to be like -r=[[...]] string str_result = solution.substr(3); // Alterado por Ulisses input_seed_result = Util::getResultFromStr(str_result.c_str(), cost_function); has_input_seed_result = true; Permutation perm_copy = perm; bool valid = Solver::validateResult(perm_copy, input_seed_result, cout); if (!valid) { cout<<"Invalid input solution."<<endl; exit(1); } } } /* -------------Check if the permutation is already sorted--------------- */ if (perm.isSorted(1, perm.size())) { Result::printResult(seed_result, cout); cout<<endl; return 0; } /* ----------------------- Set Default Parameters ----------------------- */ parameter default_parameters = getDefaultParameters(); /* Set the output for results logging */ if (p_read < argc) { logOut = new ofstream(argv[p_read++], std::ofstream::out|ofstream::app); } if (p_read < argc) { logTime = new ofstream(argv[p_read++], std::ofstream::out|ofstream::app); } /* Look for Parameters */ string type; parameter::iterator it; for (it = default_parameters.begin(); it != default_parameters.end(); it++) { pair<string, string> p = getParameterPair(it->F); string type = p.F; string name = p.S; double value = it->S; // get Num selected rev if (type == "HCR") { hcrP[name] = value; } else if (type == "IMP") { improveP[name] = value; } else if (type == "BUILD_SOLUTION") { exactP[name] = value; } p_read++; } /* Look for the unsigned mode */ improveP["UNSIGNED"] = !is_signed; /* Create log file */ //ofstream log_out("log_test_signed.txt",ios_base::app); /* ----------------------Set Parameters from terminal---------------------- */ hcrP["COST_FUNCTION"] = cost_function; improveP["COST_FUNCTION"] = cost_function; exactP["COST_FUNCTION"] = cost_function; improveP["NUM_ROUND"] = num_it; exactP["NUM_SELECTED_REV"] = inv_limit; if (frame_limit <= 0 || frame_limit > 100) { cerr<<"Error: frame_limit must be in the interval (0, 100]"<<endl; exit(1); } improveP["ROLETTE_PERCENT_DISCARD"] = (100.0 - frame_limit); /*---------------- Build the Choosen reversal Heuristic -------------------*/ hcr_seq = build_hcr_seq( intervalMethod, improveP, hcrP, exactP, heuristicReversalsName ); if (improveP["EXACT_UNITATY_LS"]) { solver_hcr.push_back(new ExactUnitary(exactP, hcr_seq)); } else if (improveP["GRASP_HEURISTIC_LS"]) { solver_hcr.push_back(new GRASPHeuristic(exactP, hcr_seq)); } /*---------------------- Build The seed solution -------------------------*/ if (has_input_seed_result) { seed_result = input_seed_result; } else if (is_signed){ // Alterado por Ulisses seed_result = sortByGRIMM(perm, true, cost_function); } else { seed_result = sortByGRIMMUnsigned(perm, NUM_IT_GRIMM_UNSIGNED, true, cost_function); } /*--------------------- Build Improvement Metaheuristic ------------------*/ ImproveReversals * ir = new ImproveReversals( solver_hcr, intervalMethod, improveP, logOut ); /*-------------------------- Try improve the result ----------------------*/ Result r_improved = tryImprove( seed_result, ir, perm_orig, cost_function ); /*----------------------- Validate result --------------------------------*/ bool valid = Solver::validateResult(perm_orig, r_improved, cout); Result seedR = seed_result; //seedR.reversals = seed_result; seedR = Solver::calcTotalCost(seedR, cost_function); /*------------------------- Print the result -----------------------------*/ if (valid) { Result::printResult(r_improved, cout); cout<<endl; } else { cout<<"ERROR"; return 1; } /*------------------------- Print time -----------------------------------*/ time_end = get_timestamp(); double time_sec = get_interval_time(time_begin, time_end); if (logTime != NULL) *(logTime)<<time_sec<<endl; /* Clean all resources */ for (size_t i = 0; i < solver_hcr.size(); i++) { delete solver_hcr[i]; } solver_hcr.clear(); if (logOut != NULL) delete logOut; delete ir; cleanResources(); return valid; }
Permutation<FromFrame, ToFrame> Permutation<FromFrame, ToFrame>::Identity() { return Permutation(XYZ); }
HDINLINE int operator()(int component) const { return Permutation().toRT()[component]; }
TEST(PermutationTest, Inequality) { Permutation p = Permutation(create_image(3, 1, 2, 0)).inverse(); EXPECT_NE(p, p.inverse()); }
TEST(PermutationTest, Equality) { Permutation p = Permutation(create_image(3, 1, 2, 0)).inverse(); Permutation q = Permutation(create_image(3, 2, 0, 1)); EXPECT_EQ(p, q); }
TEST(PermutationTest, Image10) { Permutation p = Permutation(create_image(2, 1, 0)); EXPECT_EQ(1, p(0)); EXPECT_EQ(0, p(1)); }
///////////////////////////////////////////////////////////////////// //// // Get the permutation of a string, // for example, input string abc, its permutation is // abc acb bac bca cba cab ///////////////////////////////////////////////////////////////////// //// void Permutation(char* pStr) { Permutation(pStr, pStr); }
/////////////////////////////////////////////////////////////// // 函 数 名 : des // 函数功能 : DES加解密 // 处理过程 : 根据标准的DES加密算法用输入的64位密钥对64位密文进行加/解密 // 并将加/解密结果存储到p_output里 // 时 间 : 2006年9月2日 // 返 回 值 : // 参数说明 : const char * p_data 输入, 加密时输入明文, 解密时输入密文, 64位(8字节) // const char * p_key 输入, 密钥, 64位(8字节) // char * p_output 输出, 加密时输出密文, 解密时输入明文, 64位(8字节) // uint8 mode DES_ENCRYPT 加密 DES_DECRYPT 解密 /////////////////////////////////////////////////////////////// void PP_Des(const char * p_data, const char * p_key, const char * p_output, PP_DES_MODE mode) { uint8 loop = 0; //16轮运算的循环计数器 uint8 key_tmp[8]={0}; //密钥运算时存储中间结果 uint8 sub_key[6]={0}; //用于存储子密钥 uint8 * p_left = (uint8 *)p_output; //L0 uint8 * p_right = (uint8 *)p_output+4; //R0 uint8 p_right_ext[8]={0}; //R[i]经过扩展置换生成的48位数据(6字节), 及最终结果的存储 uint8 p_right_s[4]={0}; //经过S_BOX置换后的32位数据(4字节) uint8 s_loop = 0; //S_BOX置换的循环计数器 g_index = 0; //密钥第一次缩小换位, 得到一组56位的密钥数据 Permutation((uint8 *)p_key, (uint8 *)key_tmp, Table_PC1, 56); //明文初始化置换 Permutation((uint8 *)p_data, (uint8 *)p_output, Table_IP, 64); for(loop = 0; loop < 16; loop++) { //把缩进小后的把这56位分为左28位和右28位, //对左28位和右28位分别循环左/右移, 得到一组新数据 //加解密操作时只在移位时有差异 move_bits(key_tmp, 0, 27, Table_Move[mode][loop]); move_bits(key_tmp, 28, 55, Table_Move[mode][loop]); //密钥第二次缩小换位,得到一组子48位的子密钥 Permutation((uint8 *)key_tmp, (uint8 *)sub_key, Table_PC2, 48); //R0扩展置换 Permutation((uint8 *)p_right, p_right_ext, Table_E, 48); //将R0扩展置换后得到的48位数据(6字节)与子密钥进行异或 PP_Xor(p_right_ext, sub_key, 6); //S_BOX置换 for(s_loop = 0; s_loop < 4; s_loop++) { uint8 s_line = 0; uint8 s_row = 0; uint8 s_bit = s_loop * 12; s_line = S_GetLine(p_right_ext, s_bit); s_row = S_GetRow(p_right_ext, s_bit); p_right_s[s_loop] = Table_SBOX[s_loop * 2][s_line][s_row]; s_bit += 6; s_line = S_GetLine(p_right_ext, s_bit); s_row = S_GetRow(p_right_ext, s_bit); p_right_s[s_loop] <<= 4; p_right_s[s_loop] += Table_SBOX[(s_loop * 2) + 1][s_line][s_row]; } //P置换 Permutation((uint8 *)p_right_s, (uint8 *)p_right_ext, Table_P, 32); PP_Xor(p_right_ext, p_left, 4); memcpy(p_left, p_right, 4); memcpy(p_right, p_right_ext, 4); } memcpy(&p_right_ext[4], p_left, 4); memcpy(p_right_ext, p_right, 4); //最后再进行一次逆置换, 得到最终加密结果 Permutation((uint8 *)p_right_ext, (uint8 *)p_output, Table_InverseIP, 64); }
int main() { char str[] = "abcd"; Permutation(str); return 0; }
Permutation<FromFrame, ToFrame> Permutation<FromFrame, ToFrame>::ReadFromMessage( serialization::Permutation const& message) { return Permutation(static_cast<CoordinatePermutation>( message.coordinate_permutation())); }
ThRightNormalForm::ThRightNormalForm(const crag::braidgroup::BraidGroup &G, const Word &w) : theRank(G.getRank()), theOmegaPower(0) { const Permutation omega = Permutation::getHalfTwistPermutation(theRank); // 1. compute permutation decomposition of a given braid word Permutation curMult(theRank); // bool trivialMult = true; for (Word::const_iterator w_it = w.end(); w_it != w.begin();) { // find the current block Word::const_iterator w_it2 = --w_it; for (; (*w_it2 < 0) == (*w_it < 0) && w_it2 != w.begin(); --w_it2) ; if ((*w_it2 < 0) != (*w_it < 0)) ++w_it2; w_it++; // cout << " ***** " << *w_it2 << endl; // check the sign of the block if (*w_it2 > 0) { // process the positive block for (Word::const_iterator w_it3 = w_it; w_it3 != w_it2;) { --w_it3; int gen = *w_it3; // cout << " +++++ " << gen << endl; if (curMult[gen - 1] > curMult[gen]) { theDecomposition.push_front(curMult); curMult = Permutation(theRank); } curMult.change(gen - 1, gen); // trivialMult = false; } theDecomposition.push_front(curMult); curMult = Permutation(theRank); // trivialMult = true; } else { // process the negative block list<Permutation> mult; for (Word::const_iterator w_it3 = w_it2; w_it3 != w_it; ++w_it3) { int gen = -*w_it3; // cout << " ------ " << gen << endl; if (curMult[gen - 1] > curMult[gen]) { mult.push_front(curMult); curMult = Permutation(theRank); } curMult.change(gen - 1, gen); // trivialMult = false; } mult.push_front(curMult); curMult = Permutation(theRank); // trivialMult = true; list<Permutation>::iterator it = mult.begin(); for (; it != mult.end(); ++it) { theDecomposition.push_front(omega); if (!((*it).inverse() * omega).isTrivial()) theDecomposition.push_front((*it).inverse() * omega); theOmegaPower -= 2; } } w_it = w_it2; } adjustDecomposition(theRank, theOmegaPower, theDecomposition); }
void Permutation(char *str) { if (str == nullptr) return; Permutation(str, str); }
Permutation find_canonical_permutation(Bits* bits) { int best_vals[81]; int best_map[9]; int best_row; int best_col; bool best_trans; for(int i=0; i < 81; i++) { best_vals[i] = 10; } for(int rowidx=0; rowidx < num_data_permutations; rowidx++) { for(int colidx=0; colidx < num_data_permutations; colidx++) { for(int i=0; i < 2; i++) { bool trans = (i==0); int curmap = 1; int map[10] = {0, -1, -1, -1, -1, -1, -1, -1, -1, -1}; bool is_best = false; for(int i=0; i < 81; i++) { Spot p = spot_of_idx(i); Spot px = p; px.row = permutation_data[rowidx][p.row]; px.col = permutation_data[colidx][p.col]; if(trans) { int temp = px.row; px.row = px.col; px.col = temp; } int preval = bits->get_value(px); int val; if(map[preval] == -1) { val = map[preval] = curmap; curmap++; } else { val = map[preval]; } if(is_best) { best_vals[i] = val; } else { if(val > best_vals[i]) { break; } if(val < best_vals[i]) { best_vals[i] = val; is_best = true; for(int i=0; i < 9; i++) { best_map[i] = map[i+1]; } best_row = rowidx; best_col = colidx; best_trans = trans; } } } if(is_best) { for(int i=0; i < 9; i++) { best_map[i] = map[i+1]; } } /*if(is_best) { for(int i=0; i < 81; i++) { std::cout << best_vals[i]; } std::cout << std::endl; }*/ } } } // replace possible -1 in best_map with remaining value /*for(int i=0; i < 9; i++) { std::cout << " " << best_map[i]; } std::cout << std::endl;*/ int idx_of_none = -1; std::vector<bool> has; for(int i=0; i < 9; i++) { has.push_back(false); } for(int i=0; i < 9; i++) { if(best_map[i] == -1) { idx_of_none = i; } else { has[best_map[i]-1] = true; } } if(idx_of_none != -1) { for(int i=0; i < 9; i++) { if(!has[i]) { best_map[idx_of_none] = i+1; } } } /*for(int i=0; i < 9; i++) { std::cout << " " << best_map[i]; } std::cout << std::endl;*/ /*std::cout << std::endl; for(int i=0; i < 9; i++) { for(int j=0; j < 9; j++) { std::cout << best_vals[i*9+j]; } std::cout << std::endl; } std::cout << std::endl;*/ /*std::cout << std::endl; for(int i=0; i < 9; i++) { for(int j=0; j < 9; j++) { int preval = bits->get_value(best_trans ? (Spot(permutation_data[best_col][j], permutation_data[best_row][i])) : (Spot(permutation_data[best_row][i], permutation_data[best_col][j]))); if(preval == 0) { std::cout << preval; } else { std::cout << best_map[preval - 1]; } } std::cout << std::endl; } std::cout << std::endl;*/ std::vector<int> labs; for(int i=0; i < 9; i++) { labs.push_back(best_map[i]); } return Permutation(labs, best_row, best_col, best_trans); }
int main(int argc, char** argv) { Permutation("abc"); return 1; }