import java.util.*; /** * Solution to "Foldy but Goody" * * We observe that, after the initial folding but just before the * unfolding stage begins, the even numbered points 0, 2, ... are * at (0,0) and the odd-numbered points 1, 3, ... are at (1,0). * Points 0 and 1 never move throughout the entire unfolding process; * the centers of rotation at successive unfoldings are points * 1, 2, 4, 8, ..., 2^(l-1) where l is the number of folds made. * * The problem boils down to determining on which steps the points * corresponding to the powers of 2 and m are affected by the * unfolding and on which steps they are not. * * Rotating a point (a,b) 90 degrees clockwise around a point (c,d) * takes it to the point (b-d+c,-a+c+d) as follows: * translate center to (0,0): * (a-c,b-d) * rotate 90 deg. clockwise: * (b-d,-a+c) * undo translation: * (b-d+c,-a+c+d) * * Counterclockwise is similar: (a,b) counterclockwise around (c,d) goes * to the point (-b+d+c,a-c+d). */ public class Foldy { public static Scanner in = new Scanner(System.in); public static int n; // number of test cases public static int m; // goal crease public static String crease; // crease directions public static int x[],y[]; // centers of rotation public static int xm, ym; // location of point m // int-valued power of 2 function: public static int pow(int i) { return (int) Math.pow(2,i); } public static void main(String[] args) { n = in.nextInt(); for (int i = 0; i < n; i++) { crease = in.next(); m = in.nextInt(); x = new int[crease.length()+2]; // x[i] = x-coord of point 2^(i-1) y = new int[crease.length()+2]; // y[i] = y-coord of point 2^(i-1) for (int j = 0; j < crease.length()+2; j++) { x[j] = 0; y[j] = 0; } x[1] = 1; y[1] = 0; xm = m % 2; ym = 0; // Special easy cases: m = 0 and m = 1: if (m == 0) { System.out.println("(0,0)"); } else if (m == 1) { System.out.println("(1,0)"); } // The hard case else { // Count down from last crease to first as we unfold: for (int j = crease.length(); j > 0; j--) { // Constants used for determining whether a vertex // gets moved by this unfolding: int left = pow(crease.length()-j); int incr = pow(crease.length()-j+1); char dir = crease.charAt(j-1); // rotation point, 2^(length - j): int c = x[crease.length()-j+1]; int d = y[crease.length()-j+1]; // Search through all the possible future rotation points // to see which ones are affected by this unfolding: for (int l = 1; l <= crease.length(); l++) { // checking to see if 2^l gets moved: int pt = pow(l); for (int k = 0; k < pow(j-1); k += 2) { if (pt > left + k*incr && pt < left + (k+1)*incr) { int a = x[l+1], b = y[l+1]; if (dir == 'L') { // "lower", so do counterclockwise x[l+1] = -b+d+c; y[l+1] = a-c+d; } else { // "upper", so do clockwise x[l+1] = b-d+c; y[l+1] = -a+c+d; } } } } // Search to see if m gets rotated by this unfolding: int a = xm, b = ym; for (int k = 0; k < pow(j-1); k += 2) { if (m > left + k*incr && m < left + (k+1)*incr) { if (dir == 'L') { xm = -b+d+c; ym = a-c+d; } else { xm = b-d+c; ym = -a+c+d; } break; } } } } System.out.println("("+xm+","+ym+")"); } } }