/** * g = # groups * p = product of key[0]...key[3] * for each i from 0 to 3: * find the inverse of (p/key[i]) modulo key[i], store it in inv[i] * * for each i from 0 to g-1: * break group[i] up into four remainders rem[0], ..., rem[3] * find the integer sol[i] that has those remainders using * Chinese remainder theorem: * sol[i] = sum_i{rem[i]*inv[i]*p/key[i]} mod p * * Since sol[i] is not unique, search for a value of k such that * sol[i]+kp is a concatenation of four integers from 01 through 27 * * Split sol[i]+kp back up into characters. */ import java.util.*; public class Remainder { public static long group[], key[], rem[], inv[], ans[], sol[]; public static int n, g; public static Scanner in; public static void main(String[] args) { String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "; in = new Scanner(System.in); n = in.nextInt(); for (int caseNum = 1; caseNum <= n; caseNum++) { g= in.nextInt(); key = new long[4]; rem = new long[4]; inv = new long[4]; group = new long[g]; sol = new long[g]; ans = new long[3*g]; for (int i = 0; i < 4; i++) key[i] = in.nextInt(); long p = key[0]*key[1]*key[2]*key[3]; for (int i = 0; i < g; i++) { group[i] = in.nextInt(); } for (int i = 0; i < 4; i++) { long ptemp = p/key[i]; inv[i] = inverse(ptemp,key[i]); } for (int i = 0; i < g; i++) { // extract the remainders for (int j = 0; j < 4; j++) { rem[3-j] = group[i]%100; group[i] = group[i]/100; } long solution = 0; for (int j = 0; j < 4; j++) { solution = (solution + p/key[j]*rem[j]*inv[j])%p; } sol[i] = solution; boolean ok = false; while (! ok) { ok = true; solution = sol[i]; for (int k = 0; k < 3; k++) { long r = solution%100; if (r < 1 || r > 27) { ok = false; break; } else { solution = solution/100; } } if (!ok) { sol[i] += p; } } } // decode the solution: int j = 0; for (int i = 0; i < g; i++) { for (int k = 0; k < 3; k++) { ans[j+2-k] = sol[i]%100-1; sol[i] = sol[i]/100; } j += 3; } int stop = 3*g; while (ans[stop-1] == 26) stop--; for (int i = 0; i < stop; i++) { System.out.print(letters.charAt((int)ans[i])); } System.out.println(); } } public static long inverse(long x, long m) { long p = 1; for (int i = 0; i < m-1; i++){ if ((p*x)%m ==1) return p; p = (p*x)%m; } return 0; } }