Advertisement
Guest User

Untitled

a guest
Dec 16th, 2019
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4.  
  5. std::string s = "59766299734185935790261115703620877190381824215209853207763194576128635631359682876612079355215350473577604721555728904226669021629637829323357312523389374096761677612847270499668370808171197765497511969240451494864028712045794776711862275853405465401181390418728996646794501739600928008413106803610665694684578514524327181348469613507611935604098625200707607292339397162640547668982092343405011530889030486280541249694798815457170337648425355693137656149891119757374882957464941514691345812606515925579852852837849497598111512841599959586200247265784368476772959711497363250758706490540128635133116613480058848821257395084976935351858829607105310340";
  6. std::vector<int> pattern {0, 1, 0, -1};
  7.  
  8. void solve(std::string message, int offset, int repeat) {
  9.   int n = s.length();
  10.   std::vector<int> v(n * repeat);
  11.   for (int j = 0; j < repeat; j++) {
  12.     for (int i = 0; i < n; i++) {
  13.       v[j * n + i] = s[i] - '0';
  14.     }
  15.   }
  16.  
  17.   int N = v.size();
  18.   std::vector<int> v2(N);
  19.   std::vector<int> cumsum(N + 1);
  20.   for (int phase = 0; phase < 100; phase++) {
  21.     // Precompute cumulative sums in O(N) so we can do fast range sums
  22.     cumsum[0] = 0;
  23.     for (int i = 0; i < N; i++) {
  24.       cumsum[i + 1] = cumsum[i] + v[i];
  25.     }
  26.     // O(N / 1 + N / 2 + N / 3 + ... + N / N) which is harmonic, O(N log N)
  27.     for (int i = 0; i < N; i++) {
  28.       int total = 0;
  29.       int w = i + 1;
  30.       // Sum intervals of width w (special casing the first and last interval) in O(N/w)
  31.       for (int j = -1, p = 0; j < N; j += w, p = (p + 1) % 4) {
  32.         int start = j;
  33.         if (start < 0) {
  34.           start = 0;
  35.         }
  36.         int end = j + w;
  37.         if (end >= N + 1) {
  38.           end = N;
  39.         }
  40.         total += pattern[p] * (cumsum[end] - cumsum[start]);
  41.       }
  42.       v2[i] = std::abs(total) % 10;
  43.     }
  44.     std::swap(v, v2);
  45.   }
  46.  
  47.   std::cout << message << " ";
  48.   for (int i = offset; i < offset + 8; i++) {
  49.     std::cout << v[i];
  50.   }
  51.   std::cout << std::endl;
  52. }
  53.  
  54. int main() {
  55.   solve("Part1", 0, 1);
  56.   int offset = std::stoi(s.substr(0, 7));
  57.   solve("Part2", offset, 10000);
  58. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement