Project Euler/53
From charlesreid1
Problem Statement
Problem 53 asks about values of the binomial coefficient, a.k.a. n-choose-k. For some values of n and k, the resulting n-choose-k value can exceed 1 million. This question asks how many binomial coefficients n-choose-k exceed 1 million, for n = 1 to 100.
https://projecteuler.net/problem=53
Solution Explanation
The solution here creates a matrix of values. We know that if n = k, the binomial coefficient is 1, so we can think of a square matrix, one dimension being n and the other being k, where the values along the diagonal are 1. We now have a discrete set of values on a grid, 100 x 100, and we wish to count how many squares where the n-choose-k value will exceed 1 million.
My clever solution, which enabled me to save a loooot of time that would otherwise be wasted finding factorials, was to use the fact that if n-choose-k is bigger than 1 million, then LOG(n-choose-k) should be bigger than LOG(1 million).
Taking the log of the binomial expression gives:
Now applying log properties simplifies this to:
Further simplifying turns this into a trivial sum:
thus reducing the problem of marking a "square" on our 100 x 100 n vs. k grid reduces to adding numbers that are O(10), instead of multiplying numbers that are O(100000000...)
The final comparison being done is:
If this is true, n-choose-k is less than 1 million; if it is false, n-choose-k is greater than 1 million.
Solution Code
public class CombinatoricSelections { public static void main(String[] args) { doit(); } /** Nice easy test. This should be bigger than 1 million - should return true. */ public static void test() { System.out.println("isBigger(23,10) = "+isBigger(23,10)); } /** Solve the problem. */ public static void doit() { int MAX = 100; int count = 0; boolean[][] isBig = new boolean[MAX][MAX]; for(int nm1=0; nm1<MAX; nm1++) { for(int rm1=0; rm1<MAX; rm1++) { // determine if n C r > 1M int n = nm1+1; int r = rm1+1; boolean big = isBigger(n,r); isBig[nm1][rm1] = big; if(big) count++; } } System.out.println("Total number of n Choose r values that are greater than 1M: "+count); } /** Boolean: is n choose r bigger than 1 million? */ public static boolean isBigger(int n, int r) { int d = (n-r); double LHS = 0.0; for(int j=0; j<d; j++) { LHS += Math.log(r+d-j) - Math.log(d-j); } double RHS = Math.log(1000000); return LHS > RHS; } }
Flags
Project Euler project euler notes
Round 1: Problems 1-20 Problem 1 · Problem 2 · Problem 3 · Problem 4 · Problem 5 · Problem 6 · Problem 7 · Problem 8 · Problem 9 · Problem 10 Problem 11 · Problem 12 · Problem 13 · Problem 14 · Problem 15 · Problem 16 · Problem 17 · Problem 18 · Problem 19 · Problem 20 Round 2: Problems 50-70 Problem 51 · Problem 52 · Problem 53 · Problem 54 · Problem 55 · Problem 56 · Problem 57 · Problem 58 · ... · Problem 61 · Problem 62 · Problem 63 · Problem 64 · Problem 65 · Problem 66 · Problem 67 Round 3: Problems 100-110 Problem 100 · Problem 101 · Problem 102 Round 4: Problems 500-510 Problem 500 · Problem 501 * · Problem 502 * Round 5: Problems 150-160 Round 6: Problems 250-260 Round 7: Problems 170-180
|