int test() { std::string s2 = "yabadabadoo"; SuffixArray sa2(s2); print_ranks(s2, sa2); print_suffix_array(s2, sa2); vpii_t slcp; sa2.lcp_across_sets(4, slcp); for (size_t i = 0; i < slcp.size(); ++i) { printf("slcp[%d] = (%d, %d)\n", i, slcp[i].INDEX, slcp[i].LENGTH); } print_pairwise_lcp(s2, sa2); // return 0; SuffixArray sa1("banana"); print_ranks("banana", sa1); SuffixArray sa3("mississippi"); print_ranks("mississippi", sa3); std::string s4 = "Regular expressions, or just regexes, are at the core of Perl's text processing, and certainly are one of the features that made Perl so popular. All Perl programmers pass through a stage where they try to program everything as regexes, and when that's not challenging enough, everything as a single regex. Perl's regexes have many more features than I can, or want, to present here, so I include those advanced features I find most useful and expect other Perl programmers to know about without referring to perlre, the documentation page for regexes."; SuffixArray sa4(s4); print_ranks(s4, sa4); print_suffix_array(s4, sa4); cout<<endl; print_pairwise_lcp(s4, sa4); return 0; }
int main(){ int cases; scanf("%d",&cases); while(cases--){ read_input(); find_ranks(); print_ranks(); } return 0; }
/* * "Guided" Random Walk implementation */ int solve_diffs_RW(timing_data * data, double diff_weight[KEY_LENGTH][KEY_LENGTH][256], key_data * key) { int i, j, k, u, v; unsigned char key_guess[KEY_LENGTH]; unsigned char new_key_guess[KEY_LENGTH]; double guess_weights[KEY_LENGTH][256]; short diffcounts[256]; int diffs_solved = 0; for(i = 1; i < KEY_LENGTH; i++) { for(j = 0; j < 256; j++) { guess_weights[i][j] = 0; guess_weights[i][j] += diff_weight[0][i][j]; for(u = 1; u < i; ++u) { double low_weight = 10000; for(v = 0; v < 256; v++) if(diff_weight[0][u][v] + diff_weight[u][i][v ^ j] < low_weight) low_weight = diff_weight[0][u][v] + diff_weight[u][i][v ^ j]; guess_weights[i][j] += low_weight; } for(u = i + 1; u < KEY_LENGTH; ++u) { double low_weight = 10000; for(v = 0; v < 256; v++) if(diff_weight[0][u][v] + diff_weight[i][u][v ^ j] < low_weight) low_weight = diff_weight[0][u][v] + diff_weight[i][u][v ^ j]; guess_weights[i][j] += low_weight; } } } printf("\nRW:"); print_ranks(guess_weights, key); //Make initial best guess for(i = 1; i < KEY_LENGTH; ++i) { double min_seen = guess_weights[i][0]; for(j = 0; j < 256; ++j) if(guess_weights[i][j] <= min_seen) { min_seen =guess_weights[i][j]; key_guess[i] = j; } } if(guess_key(key_guess, data, key)) return 1; int round = 1; double guess_weight; for(round = 0; round < RANDOM_WALK_LIMIT; round++) { for(i =1; i < KEY_LENGTH; i++) { for(j = 0; j < 256; j++) { guess_weight = diff_weight[0][i][j]; for(k = 1; k < i; k++) guess_weight +=diff_weight[k][i][j ^ key_guess[k]]; for(k = i +1; k < KEY_LENGTH; k++) guess_weight +=diff_weight[i][k][j ^ key_guess[k]]; guess_weights[i][j] = guess_weight; } } int best_byte = 1; double best_gain =0; //Make single best guess for(i = 1; i < KEY_LENGTH; ++i) { double min_seen = guess_weights[i][0]; for(j = 0; j < 256; ++j) if(guess_weights[i][j] <= min_seen) { min_seen =guess_weights[i][j]; } if(guess_weights[i][key_guess[i]] - min_seen > best_gain) { best_gain = guess_weights[i][key_guess[i]] - min_seen; best_byte = i; } } double min_seen = guess_weights[best_byte][0]; for(j = 0; j < 256; ++j) if(guess_weights[best_byte][j] <= min_seen) { min_seen =guess_weights[best_byte][j]; key_guess[best_byte] = j; } /* printf("\nUpdating byte #%d", best_byte); */ /* printf("\nRound #%d", round); */ /* print_ranks(guess_weights, key); */ if(guess_key(key_guess, data, key)) return 1; } return 0; }
/* * Belief propagation implementation */ int solve_diffs_BP(timing_data * data, double diff_prob[KEY_LENGTH][KEY_LENGTH][256], key_data * key) { int i, j, k, u, v; unsigned char key_guess[KEY_LENGTH]; unsigned char new_key_guess[KEY_LENGTH]; double guess_prob[KEY_LENGTH][256]; double next_guess_prob[KEY_LENGTH][256]; short diffcounts[256]; int diffs_solved = 0; for(i = 1; i < KEY_LENGTH; i++) { for(j = 0; j < 256; j++) { guess_prob[i][j] = 0; guess_prob[i][j] += diff_prob[0][i][j]; for(u = 1; u < i; ++u) { double high_prob = 0; for(v = 0; v < 256; v++) if(diff_prob[0][u][v] + diff_prob[u][i][v ^ j] > high_prob) high_prob = diff_prob[0][u][v] + diff_prob[u][i][v ^ j]; guess_prob[i][j] += high_prob; } for(u = i + 1; u < KEY_LENGTH; ++u) { double high_prob = 0; for(v = 0; v < 256; v++) if(diff_prob[0][u][v] + diff_prob[i][u][v ^ j] > high_prob) high_prob = diff_prob[0][u][v] + diff_prob[i][u][v ^ j]; guess_prob[i][j] += high_prob; } } } normalize(guess_prob); printf("\nBP:"); print_ranks(guess_prob, key); //Make initial best guess for(i = 1; i < KEY_LENGTH; ++i) { double max_seen = 0; for(j = 0; j < 256; ++j) if(guess_prob[i][j] >= max_seen) { max_seen =guess_prob[i][j]; key_guess[i] = j; } } if(guess_key(key_guess, data, key)) return 1; int round = 1; /* double guess_weight; */ for(round = 0; round < RANDOM_WALK_LIMIT; round++) { for(i = 1; i < KEY_LENGTH; i++) for(j = 0; j < 256; j++) { next_guess_prob[i][j] = 0; for(u = 1; u < i; ++u) { double high_prob = 0; for(v = 0; v < 256; v++) if(guess_prob[u][v] * diff_prob[u][i][v ^ j] > high_prob) high_prob = guess_prob[u][v] * diff_prob[u][i][v ^ j]; next_guess_prob[i][j] += high_prob; } for(u = i + 1; u < KEY_LENGTH; ++u) { double high_prob = 0; for(v = 0; v < 256; v++) if(guess_prob[u][v] * diff_prob[i][u][v ^ j] > high_prob) high_prob = guess_prob[u][v] * diff_prob[i][u][v ^ j]; next_guess_prob[i][j] += high_prob; } } for(i = 1; i < KEY_LENGTH; i++) for(j = 0; j < 256; j++) guess_prob[i][j] = next_guess_prob[i][j]; normalize(guess_prob); /* printf("\nRound #%d", round); */ /* print_ranks(guess_prob, key); */ for(i = 1; i < KEY_LENGTH; ++i) { double max_seen = 0; for(j = 0; j < 256; ++j) if(guess_prob[i][j] >= max_seen) { max_seen =guess_prob[i][j]; key_guess[i] = j; } } if(guess_key(key_guess, data, key)) return 1; } return 0; }