Advertisement
Guest User

matrix

a guest
Aug 29th, 2015
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.86 KB | None | 0 0
  1. import java.math.BigInteger;
  2. import java.util.Arrays;
  3.  
  4. public class div7 {
  5.   // main idea taken from here: https://www.math.hmc.edu/funfacts/ffiles/10005.5.shtml
  6.   public static int MAXD = 10000;
  7.   public static int[] res = {1,3,2,6,4,5}; // 10^i modulo 7, repeating
  8.   public static BigInteger[] nums;
  9.   static {
  10.     nums = new BigInteger[11];
  11.     for (int i = 0; i <= 10; i++)
  12.       nums[i] = new BigInteger(String.valueOf(i));
  13.   }
  14.  
  15.   public static void main (String[] args) {
  16.     long start = System.currentTimeMillis();
  17.     BigInteger sum = count(MAXD);
  18.     int x = 0;
  19.     for (char c : sum.toString().toCharArray()) x += c-'0';
  20.     System.out.println("Sum digits: " + x);
  21.     if (sum.toString().length() < 1000) System.out.println("Sum: " + sum);
  22.     System.out.println("Time: " + (System.currentTimeMillis()-start) + "ms");
  23.   }
  24.  
  25.   public static BigInteger count(int lim) {
  26.     int bf = 0, ff = (lim - 1) % res.length;
  27.  
  28.     BigInteger[][] dp = new BigInteger[2][49];
  29.     BigInteger[][] count = new BigInteger[2][49];
  30.     for (int i = 0; i < 2; i++) {
  31.       Arrays.fill(dp[i], BigInteger.ZERO);
  32.       Arrays.fill(count[i], BigInteger.ZERO);
  33.     }
  34.    
  35.     BigInteger[][][] trans = new BigInteger[res.length][98][98];
  36.     for (int r = 0; r < res.length; r++) {
  37.       for (BigInteger[] x : trans[r]) Arrays.fill(x, BigInteger.ZERO);
  38.       for (int i = 0; i < 49; i++) {
  39.         int k = i/7, m = i%7;
  40.         for (int j = 0; j <= 9; j++) {
  41.           int nk = (k+res[bf]*j)%7, nm = (m+res[ff]*j)%7, nc = nk*7+nm;
  42.           trans[r][i][nc] = trans[r][i][nc].add(BigInteger.TEN);
  43.           trans[r][i+49][nc] = trans[r][i+49][nc].add(nums[j]);
  44.           trans[r][i+49][nc+49] = trans[r][i+49][nc+49].add(BigInteger.ONE);
  45.         }
  46.       }
  47.       bf++; if (bf >= res.length) bf -= res.length;
  48.       ff--; if (ff < 0) ff += res.length;
  49.     }
  50.     BigInteger[][] x = new BigInteger[98][98];
  51.     for (int i = 0; i < 98; i++) {
  52.       Arrays.fill(x[i], BigInteger.ZERO);
  53.       x[i][i] = BigInteger.ONE;
  54.     }
  55.     for (int r = 0; r < res.length; r++) x = mat_mult(x, trans[r]);
  56.     x = mat_exp(x, lim/res.length);
  57.     for (int r = 0; r < lim % res.length; r++) x = mat_mult(x, trans[r]);
  58.     return x[49][0];
  59.   }
  60.  
  61.   public static BigInteger[][] mat_mult(BigInteger[][] a, BigInteger[][] b) {
  62.     int n = a.length;
  63.     BigInteger[][] c = new BigInteger[n][n];
  64.     for (BigInteger[] x : c) Arrays.fill(x, BigInteger.ZERO);
  65.     for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) for (int k = 0; k < n; k++)
  66.       c[i][j] = c[i][j].add(a[i][k].multiply(b[k][j]));
  67.     return c;
  68.   }
  69.  
  70.   private static BigInteger[][] mat_exp(BigInteger[][] A, int e) {
  71.     if (e == 1)
  72.       return A;
  73.     else if (e % 2 == 0) {
  74.       BigInteger[][] A1 = mat_exp(A, e / 2);
  75.       return mat_mult(A1, A1);
  76.     } else
  77.       return mat_mult(A, mat_exp(A, e - 1));
  78.   }
  79.  
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement