public static ModulusNumber F(int w, int h) { if (w == 0 || h == 0) { return(ModulusNumber.One); } ModulusEvenOdd[] previous = new ModulusEvenOdd[w]; ModulusEvenOdd[] current = new ModulusEvenOdd[w]; for (int i = 0; i < w; i++) { current[i] = ModulusEvenOdd.OneEven; } for (int i = 1; i < h; i++) { if (i % 10 == 0) { Console.WriteLine(i); } ModulusEvenOdd[] temp = previous; previous = current; current = temp; for (int j = 1; j <= w; j++) { ModulusEvenOdd result = Get(current, j - 1) + Get(previous, j).Swap; for (int k = 1; k < j; k++) { ModulusEvenOdd subResult0 = Get(previous, k).Swap; ModulusEvenOdd subResult1 = Get(current, j - k - 1); ModulusEvenOdd total = subResult0 * subResult1; result += total; } Set(current, j, result); } } return(current[w - 1].Odd - previous[w - 1].Odd); }
static void Set(ModulusEvenOdd[] values, int w, ModulusEvenOdd value) { values[w - 1] = value; }
private static ModulusNumber Solve(BigInteger w, int h) { int size = h * 2; ModulusMatrix matrix = new ModulusMatrix(size, size); ModulusMatrix initial = new ModulusMatrix(size, 1); ModulusMatrix temp = new ModulusMatrix(size, 1); // matrix loop for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if (j == i) { initial[j, 0] = ModulusNumber.One; } else { initial[j, 0] = ModulusNumber.Zero; } temp[j, 0] = ModulusNumber.Zero; } // temp loop for (int j = 0; j < h; j++) { ModulusEvenOdd total = new ModulusEvenOdd(); // initial loop for (int k = 0; k < h; k++) { ModulusEvenOdd value = Get(initial, k); if (k >= j) { total += value; } else { if (((j - k) % 2) == 1) { total += value.Swap; } else { total += value; } } } Set(temp, j, total); } matrix.SetColumn(i, temp.GetColumn(0)); } for (int i = 0; i < h; i++) { if (i % 2 == 0) { Set(initial, i, ModulusEvenOdd.OneEven); } else { Set(initial, i, ModulusEvenOdd.OneOdd); } } ModulusMatrix powerMatrix = ModulusMatrix.Power(matrix, w - 1); ModulusMatrix result = powerMatrix * initial; ModulusNumber sum = ModulusNumber.Zero; for (int i = 0; i < h; i++) { sum += result[i * 2 + 1, 0]; } return(sum); }
private static void Set(ModulusMatrix values, int index, ModulusEvenOdd value) { values[index * 2, 0] = value.Even; values[index * 2 + 1, 0] = value.Odd; }
private static ModulusEvenOdd Get(ModulusMatrix values, int index) { ModulusEvenOdd result = new ModulusEvenOdd(values[index * 2, 0], values[index * 2 + 1, 0]); return(result); }
private static ModulusNumber Solve(int w, int h) { ModulusEvenOdd[] previous = new ModulusEvenOdd[h]; ModulusEvenOdd[] current = new ModulusEvenOdd[h]; for (int i = 0; i < h; i++) { if (i % 2 == 0) { current[i] = ModulusEvenOdd.OneEven; } else { current[i] = ModulusEvenOdd.OneOdd; } } for (int i = 1; i < w; i++) { Console.WriteLine(i); ModulusEvenOdd[] temp = previous; previous = current; current = temp; for (int j = 0; j < h; j++) { ModulusEvenOdd total = new ModulusEvenOdd(); for (int k = 0; k < h; k++) { ModulusEvenOdd value = previous[k]; if (k >= j) { total += value; } else { if (((j - k) % 2) == 1) { total += value.Swap; } else { total += value; } } } current[j] = total; } } ModulusNumber sum = ModulusNumber.Zero; for (int i = 0; i < h; i++) { sum += current[i].Odd; } return(sum); }