import java.util.Scanner; public class Solution5 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long N = scanner.nextLong(); // System.out.println(getCount(N)); System.out.println(better(N)); scanner.close(); } private static long getCount(long N) { long i, j, k; long SUM = (N - 1) * (N - 1); for (i = 2; i <= Math.sqrt(N); i++) { for (j = 2; j <= Math.log(N) / Math.log(i) + 1; j++) { k = (long) Math.pow(i, j); if (k > N) { continue; } // cout << "i=" << i << " j=" << j << " k=" << k << endl; int factor = (int) (Math.log(k) / Math.log(j)); long minus = (long) (N / j) - 1; if (minus < 0) { minus = 0; } SUM -= minus; System.out.println("i=" + i + " j=" + j + " k=" + k + " minus=" + minus); } } return SUM; } private static long better(long M) { int maxPow = (int) Math.floor(Math.log(M) / Math.log(2)); long[] dupesPerPow = new long[maxPow + 1]; long[] numOfPow = new long[maxPow + 1]; long totDupes = 0; // Step one: find dupes per power. for (int i = 2; i <= maxPow; i++) { boolean[] powOverlap = new boolean[(int) (M + 1)]; for (int k = 1; k <= i - 1; k++) { int spacing = lcm(k, i) / i; for (int n = 0; n <= k * M / i; n += spacing) { powOverlap[n] = true; } } long count = 0; for (int j = 2; j <= M; j++) { if (powOverlap[j]) count++; } dupesPerPow[i] = count; } // Step two: find actual number of powers. int sqrtN = (int) Math.pow(M, 0.5); boolean[] powersNotToRepeat = new boolean[sqrtN + 1]; for (int i = 2; i <= sqrtN; i++) { if (!powersNotToRepeat[i]) { for (int p = 2; Math.pow(i, p) <= M; p++) { numOfPow[p]++; if (Math.pow(i, p) <= sqrtN) powersNotToRepeat[(int) Math.pow(i, p)] = true; } } } for (int p = 2; p <= maxPow; p++) { totDupes += numOfPow[p] * dupesPerPow[p]; } return (M - 1) * (M - 1) - totDupes; } public static int lcm(int k, int i) { // Use Euclidean algo for GCD to get LCM. // assert k < i if (i % k == 0) return i; else { int i_ = i; int k_ = k; // store original values int r = i % k; while (r != 0) { i = k; k = r; r = i % k; } return i_ * k_ / k; } } } // 2^2 2^3 2^4 2^5 2^6 2^7 2^8 2^9 2^10 // 3^2 3^3 3^4 3^5 3^6 3^7 3^8 3^9 3^10 // 4^2 4^3 4^4 4^5 4^6 4^7 4^8 4^9 4^10 // 5^2 5^3 5^4 5^5 5^6 5^7 5^8 5^9 5^10 // 6^2 6^3 6^4 6^5 6^6 6^7 6^8 6^9 6^10 // 7^2 7^3 7^4 7^5 7^6 7^7 7^8 7^9 7^10 // 8^2 8^3 8^4 8^5 8^6 8^7 8^8 8^9 8^10 // 9^2 9^3 9^4 9^5 9^6 9^7 9^8 9^9 9^10 // 10^2 10^3 10^4 10^5 10^6 10^7 10^8 10^9 10^10 // 10 // 2 - 4 4 // 2 - 8 2 // 3 - 9 4
Thursday, March 3, 2016
Project Euler #29 Distinct powers
Of course brute force is easy, but for the 'right' solution, I failed to complete this, and found help from stackoverflow here as well as Project Euler forum.
Here is the implementation of both approach:
Wednesday, March 2, 2016
MathJax test
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$ \(F_n = \lfloor\frac{\psi^n}{\sqrt{5}}\rfloor\), where \(\psi\) is \(\frac{1-\sqrt(5)}{2}\).
To find minimum D-digit \(F_n\) we can set \(F_n = \lfloor\frac{phi^n}{\sqrt(5)}\rfloor < 10^D\).
By taking log on both side, and we get \(n \cdot log(\psi) - log(\sqrt(5)) < D \cdot log(10)\)
Tuesday, March 1, 2016
Project Euler #28 Number spiral diagonals
First I solved with O(n), but I found O(1) and below is implementation of both:
import java.math.BigInteger; import java.util.Scanner; public class Solution4 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int T = scanner.nextInt(); while (T-- > 0) { long N = scanner.nextLong(); // System.out.println(bruteForce(N)); System.out.println(muchBetter(N)); } scanner.close(); } private static String muchBetter(long n) { BigInteger bi = BigInteger.valueOf((n - 1) / 2); BigInteger bi1 = bi.pow(3).multiply(BigInteger.valueOf(16)); BigInteger bi2 = bi.pow(2).multiply(BigInteger.valueOf(30)); BigInteger bi3 = bi.multiply(BigInteger.valueOf(26)).add(BigInteger.valueOf(3)); BigInteger answer = bi1.add(bi2).add(bi3).divide(BigInteger.valueOf(3)).mod(BigInteger.valueOf(1000000007L)); return answer.toString(); } private static long bruteForce(long n) { long SUM = 1; long end = 1; for (long i = 1; i <= n / 2; i++) { SUM += (4 * end + 20 * i); end = end + 8 * i; if (SUM > 1000000007L) { SUM %= 1000000007L; } } return SUM; } }
Labels:
General
Project Euler #27 Quadratic primes
Just try with the given condition. Self explanatory.
Used C++:
Used C++:
#include <iostream> #include <cmath> using namespace std; int isPrime(int N); int main() { int i; int N, F, a, b, count; int MAX_COUNT=0, MAX_A=0, MAX_B=0; cin >> N; for (b=N; b>=-1*N; b--) { if (!isPrime(b)) { continue; } for (a=N; a>=-1*N; a--) { for(i=0; ;i++) { F = i * i + a*i + b; if (!isPrime(F)) { if (i > MAX_COUNT) { MAX_COUNT = i; MAX_A = a; MAX_B = b; } break; } } } } cout << MAX_A << " " << MAX_B << endl; } int isPrime(int N) { int i; if (N < 2) return 0; if (N == 2) return 1; for (i=3; i<=sqrt(N); i+=2) { if (N%i == 0) { return 0; } } return 1; }
Labels:
General
Project Euler #25 1000-digit Fibonacci number
First I attempted to solve this problem using BigInteger & BigDecimal using bruteforce method, but come on! We know Euler didn't know how to import such classes.
Asymptotically, and precisely, we can get n-th term of Fibonacci number using following formular. Again, I am not going to talk about how to prove this, but for those of who are interested, please take a look at Wikipedia here and Wolfram Alpha here
Basic idea is as follows. I will use LaTex format for mathematical formula from now on.
Asymptotically, and precisely, we can get n-th term of Fibonacci number using following formular. Again, I am not going to talk about how to prove this, but for those of who are interested, please take a look at Wikipedia here and Wolfram Alpha here
Basic idea is as follows. I will use LaTex format for mathematical formula from now on.
- \(F_n = \lfloor\frac{\psi^n}{\sqrt{5}}\rfloor\), where \(\psi\) is \(\frac{1-\sqrt(5)}{2}\).
- To find minimum D-digit \(F_n\) we can set \(F_n = \lfloor\frac{phi^n}{\sqrt(5)}\rfloor < 10^D\).
- By taking log on both side, and we get \(n \times \log{\psi} - \log{\sqrt{5}} < D \times \log{10}\)
import java.math.BigDecimal; import java.math.BigInteger; import java.util.Scanner; public class Solution3 { private static int DATA[] = new int[5002]; private static int DATA2[] = new int[5002]; private static void bruteForce() { BigInteger bi1 = BigInteger.valueOf(1); BigInteger bi2 = BigInteger.valueOf(1); BigInteger bi3; int term = 3; int digit = 1; int cur; DATA[1] = 1; while (digit <= 5000) { bi3 = bi1.add(bi2); cur = bi3.toString().length(); if (cur > digit) { System.out.println(term); ; digit = cur; DATA[digit] = term; } bi1 = bi2; bi2 = bi3; term++; } int T, N; Scanner scanner = new Scanner(System.in); T = scanner.nextInt(); while (T-- > 0) { N = scanner.nextInt(); System.out.println(DATA[N]); } scanner.close(); } public static void main(String[] args) { // bruteForce(); approximate(); } private static void approximate() { int T, N; final double OMEGA = (1 + Math.sqrt(5)) / 2; // F_n <= Omega^n / sqrt(5) + 0.5 < 10^digit // log (F_N) <= n * log(Omega) - log(sqrt(5)) < digit * log 10 // For digit 1 ... 5000, find n argmax (n * log(Omega) - log(sqrt(5))) int term = 1; double fn; for (int i = 1; i <= 5000; i++) { double l = (i * Math.log(10)); // System.out.println("L=" + l); do { fn = term * Math.log(OMEGA) - Math.log(Math.sqrt(5)); // System.out.println("F_" + term + "= " + fn); term++; } while (l > fn); DATA2[i] = term - 1; } Scanner scanner = new Scanner(System.in); T = scanner.nextInt(); while (T-- > 0) { N = scanner.nextInt(); System.out.println(DATA2[N - 1]); } scanner.close(); } }
Labels:
General
Subscribe to:
Posts (Atom)