今さらJavaをおぼえなければいけないみたいなので、とりあえず10問解いてみた。
Problem 1
C++とほぼ同じ。
public class e001 { public static void main(String args[]) { int s = 0; int N = 1000; for(int n = 1; n < N; ++n) { if(n % 3 == 0 || n % 5 == 0) s += n; } System.out.println(s); } }
Problem 2
Fibonacci数列の生成と偶数の分離と和を取る部分が切り離せない。すなわちコードの再利用ができない。
public class e002 { public static void main(String args[]) { int s = 0; int N = 4000000; int a = 1; int b = 1; while(a <= N) { if(a % 2 == 0) s += a; int tmp = b; b += a; a = tmp; } System.out.println(s); } }
Problem 3
デフォルト引数は使えない。
public class e003 { static long max_factor(long n) { return max_factor(n, 2); } static long max_factor(long n, long p0) { for(long p = p0; p * p <= n; ++p) { if(n % p == 0) return max_factor(n / p, p); } return n; } public static void main(String args[]) { long N = 600851475143L; System.out.println(max_factor(N)); } }
Problem 4
とにかく長い。タプルがあれば短くなるのに。ComparatorはなぜGenericが使えないのか。Genericの意味もよくわかっていないが。
public class cMul { int m; int n; int p; // m * n cMul(int a, int b) { m = a; n = b; p = a * b; } int get_m() { return m; } int get_n() { return n; } int get_p() { return p; } }
import java.util.Comparator; public class MulComparator implements Comparator { public int compare(Object o1, Object o2) { cMul m1 = (cMul)o1; cMul m2 = (cMul)o2; if(m1.get_p() < m2.get_p()) return 1; else if(m1.get_p() > m2.get_p()) return -1; else return 0; } }
import java.util.PriorityQueue; public class e004 { static int reverse(int n) { int s = 0; while(n > 0) { s = s * 10 + n % 10; n /= 10; } return s; } static boolean is_palindromic(int n) { return reverse(n) == n; } static int get_max_palindromic(int N) { PriorityQueue<cMul> pq = new PriorityQueue<cMul>(1, new MulComparator()); pq.add(new cMul(N - 1, N - 1)); while(pq.size() > 0) { cMul a = pq.poll(); if(is_palindromic(a.get_p())) return a.get_p(); if(a.get_m() == a.get_n()) pq.add(new cMul(a.get_m() - 1, a.get_m() - 1)); pq.add(new cMul(a.get_m(), a.get_n() - 1)); } return 0; } public static void main(String args[]) { final int N = 1000; System.out.println(get_max_palindromic(N)); } }
Problem 5
public class e005 { static int gcd(int n, int m) { return m == 0 ? n : gcd(m, n % m); } static int lcm(int n, int m) { return n / gcd(n, m) * m; } public static void main(String args[]) { final int N = 20; int s = 1; for(int n = 1; n <= N; ++n) s = lcm(s, n); System.out.println(s); } }
Problem 6
public class e006 { public static void main(String args[]) { final int N = 100; int s1 = 0; for(int n = 1; n <= N; ++n) s1 += n; int s2 = 0; for(int n = 1; n <= N; ++n) s2 += n * n; System.out.println(s1 * s1 - s2); } }
Problem 7
エラトステネスのふるい。素数定理使って手抜き。
import java.util.ArrayList; public class e007 { static ArrayList make_primes(int N) { boolean[] a = new boolean[N+1]; for(int k = 2; k <= N; ++k) a[k] = true; for(int p = 2; p * p <= N; ++p) { for(int k = p * p; k <= N; k += p) a[k] = false; } ArrayList b = new ArrayList(); for(int k = 2; k <= N; ++k) { if(a[k]) b.add(k); } return b; } public static void main(String args[]) { final int N = 10001; final int M = (int)(N * Math.log((double)N) * 2); final ArrayList primes = make_primes(M); System.out.println(primes.get(N-1)); } }
Problem 8
import java.util.ArrayList; public class e008 { public static void main(String args[]) { final String s = "73167176531330624919225119674426574742355349194934" + "96983520312774506326239578318016984801869478851843" + "85861560789112949495459501737958331952853208805511" + "12540698747158523863050715693290963295227443043557" + "66896648950445244523161731856403098711121722383113" + "62229893423380308135336276614282806444486645238749" + "30358907296290491560440772390713810515859307960866" + "70172427121883998797908792274921901699720888093776" + "65727333001053367881220235421809751254540594752243" + "52584907711670556013604839586446706324415722155397" + "53697817977846174064955149290862569321978468622482" + "83972241375657056057490261407972968652414535100474" + "82166370484403199890008895243450658541227588666881" + "16427171479924442928230863465674813919123162824586" + "17866458359124566529476545682848912883142607690042" + "24219022671055626321111109370544217506941658960408" + "07198403850962455444362981230987879927244284909188" + "84580156166097919133875499200524063689912560717606" + "05886116467109405077541002256983155200055935729725" + "71636269561882670428252483600823257530420752963450"; final int N = s.length(); int max = 0; int a[] = new int[N]; for(int k = 0; k < N; ++k) a[k] = Integer.parseInt(s.substring(k, k + 1)); for(int k = 0; k < N - 4; ++k) { int m = 1; for(int l = k; l < k + 5; ++l) m *= a[l]; max = Math.max(max, m); } System.out.println(max); } }
Problem 9
素因数分解から約数を生成。
ものすごく書きにくい。
import java.util.ArrayList; public class e009 { static ArrayList factorize(int n) { ArrayList fs = new ArrayList(); for(int p = 2; p * p <= n; ++p) { if(n % p == 0) { int e = 1; n /= p; while(n % p == 0) { ++e; n /= p; } fs.add(new Fact(p, e)); } } if(n > 1) fs.add(new Fact(n, 1)); return fs; } static int pow(int p, int e) { return e == 0 ? 1 : p * pow(p, e - 1); } static int value_f(ArrayList fs) { int n = 1; for(Object o : fs) { Fact f = (Fact)o; n *= pow(f.get_p(), f.get_e()); } return n; } static ArrayList tail(ArrayList a) { ArrayList b = new ArrayList(a.size() - 1); for(int k = 1; k < a.size(); ++k) { b.add(a.get(k)); } return b; } static ArrayList cons(Fact f, ArrayList a) { ArrayList b = new ArrayList(); b.add(f); for(Object o : a) b.add((Fact)o); return b; } static ArrayList sub_f(ArrayList a, ArrayList b) { if(b.size() == 0) return a; ArrayList c = new ArrayList(); int l = 0; for(int k = 0; k < a.size(); ++k) { final Fact f1 = (Fact)a.get(k); final Fact f2 = (Fact)b.get(Math.min(l, b.size() - 1)); if(f1.get_p() == f2.get_p()) { if(f1.get_e() > f2.get_e()) c.add(new Fact(f1.get_p(), f1.get_e() - f2.get_e())); ++l; } else { c.add(f1); } } return c; } static ArrayList divides(ArrayList fs) { if(fs.size() <= 0) { ArrayList divs = new ArrayList(); divs.add(new ArrayList()); return divs; } else { ArrayList divs = new ArrayList(); Fact f = (Fact)fs.get(0); final int p = f.get_p(); final int e = f.get_e(); for(Object o : divides(tail(fs))) { ArrayList div = (ArrayList)o; divs.add(div); for(int e1 = 1; e1 <= e; ++e1) { divs.add(cons(new Fact(p, e1), div)); } } return divs; } } static int gcd(int n, int m) { return m == 0 ? n : gcd(m, n % m); } static boolean is_right_triangle(int n1, int n2, int n3) { return n3 % 2 == 1 && n2 < n3 && n3 < n2 * 2 && gcd(n2, n3) == 1; } public static void main(String args[]) { final int N = 1000; ArrayList fs = factorize(N / 2); ArrayList divs = divides(fs); for(Object o : divs) { ArrayList fs1 = (ArrayList)o; ArrayList fs2 = sub_f(fs, fs1); final int n1 = value_f(fs1); ArrayList divs2 = divides(fs2); for(Object o2 : divs2) { ArrayList fs3 = (ArrayList)o2; ArrayList fs4 = sub_f(fs2, fs3); final int n2 = value_f(fs3); final int n3 = value_f(fs4); if(is_right_triangle(n1, n2, n3)) { final int l = n1; final int m = n2; final int n = n3 - n2; final int a = l * (m * m - n * n); final int b = 2 * l * m * n; final int c = l * (m * m + n * n); System.out.println(a * b * c); } } } } }
Problem 10
Generic版のListを使ってエラトステネスのふるい。
import java.util.ArrayList; import java.util.List; public class e010 { static List<Integer> make_primes(int N) { boolean[] a = new boolean[N+1]; for(int k = 2; k <= N; ++k) a[k] = true; for(int p = 2; p * p <= N; ++p) { for(int k = p * p; k <= N; k += p) a[k] = false; } List<Integer> b = new ArrayList<Integer>(); for(int k = 2; k <= N; ++k) { if(a[k]) b.add(k); } return b; } static long sum(List<Integer> a) { long s = 0; for(int k = 0; k < a.size(); ++k) s += a.get(k); return s; } public static void main(String args[]) { final int N = 2000000; final List<Integer> primes = make_primes(N); System.out.println(sum(primes)); } }