Archive for the 'Problems' Category

Page 2 of 5

Project Euler : Finding Largest 9-Pandigital Number Formed As A Concatenated Product

Problem 38 of Project Euler states the problem of finding the largest 1-9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1, 2, .. ,n) where n > 1. As an example, take the number 192 and its products with 1, 2 and 3.

192 * 1 = 192

192 * 2 = 384

192 * 3 = 576

The concatenated number 192384576 is a 9-digit pandigital number. Another example is that of multiplying 9 with (1, 2, 3, 4, 5) to yield the number 918273645.

The above serves as a hint. We now know that the required answer is at least greater than 918273645. Let us try to eliminate a few options.

Consider all 2 digit numbers in the interval [91, 98]. Their multiplication with 1, 2 and 3 will yield 2, 3 and 3 digit numbers respectively. Concatenating these numbers will result in a 8 digit number. But we need a 9-digit number. So we can rule out this case.

Consider all 3 digit numbers in the interval [918, 987]. Their multiplication with 1 and 2 will yield 3 and 4 digit numbers respectively. With the same logic as the previous case, we can rule out these numbers.

Consider all 4 digit numbers in the interval [9182, 9876]. Their multiplication with 1 and 2 will yield 4 and 5 digit numbers respectively. This is the range we are looking for.

After reducing the search space to 694 numbers, a simple java code did the work. It makes a call to NumberUtil.isNPandigital(int) which returns true if the number is pandigital and false otherwise.

public class Problem_38 {
    public static int getValue() {
        for (int i = 9876; i > 9183; i--) {
            int val = i * 100002;
            if (NumberUtil.isNPandigital(val)) return val;
        }

        return -1;
    }
}

Popularity: 10% [?]

Project Euler : Compute ( p * a^b + q ) mod c

The problem 97 of Project Euler required one to find the value of:

28433×27830457+1.

Anshumali Srivastava and I spent a lot of time on time, trying to factor the expression into smaller numbers which could make the computation easier. We tried a few things but got stuck every time.

Finally giving up on it, I decided to brute force it using the BigInteger class of Java. Amazingly, it took just a few seconds to get the answer. Looking at the solutions posted in the forum I realized that everyone had done the same and even the Project Euler admin called this one as a freebie. There was one suggestion to improve the solution. You can read about it here:

http://www.osix.net/modules/article/?id=696

The Java implementation for the same would be:

    public static final BigInteger TWO = BigInteger.valueOf(2);

    /**
     * Computes the value of a^b mod c
     *
     * @param a The base
     * @param b The exponent
     * @param c The mod number
     * @return The value of a^b mod c
     */
    public static final BigInteger aPowbModc(BigInteger a, BigInteger b, BigInteger c) {
        long longValue = b.longValue();
        if (longValue < 0) throw new IllegalArgumentException("Exponent should be non negative");
        if (longValue == 0) return BigInteger.ONE;
        if (a.longValue() == 0) return BigInteger.ZERO;

        BigInteger v = NumberUtil.aPowbModc(a, b.divide(NumberUtil.TWO), c).modPow(NumberUtil.TWO, c);

        return longValue % 2 == 1 ? v.multiply(a).mod(c) : v;
    }

The recursive exponentiation function:

    public static BigInteger getVal() {
        BigInteger mod = new BigInteger("10").pow(10);
        BigInteger val = NumberUtil.aPowbModc(new BigInteger("2"), new BigInteger("7830457"), mod)
                .multiply(new BigInteger("28433")).add(BigInteger.ONE);
        return val.mod(mod);
    }

Popularity: 5% [?]

Project Euler : Fractions With Unorthodox Cancelling Method

Problem 33 in Project Euler says there are 4 non-trivial curious fractions which satisfy the following properties:

\frac{ax}{xb} = \frac{a}{b}

where a, b and x are all single digit numbers and a < b

The solution was pretty simple.

\frac{ax}{xb} = \frac{a}{b}

\Rightarrow b [10a + x] = a [10x + b]

\Rightarrow x = \frac{9ab}{10a - b}

Similarly solving for the other form \frac{xa}{bx} = \frac{a}{b} gives the answer x = \frac{9ab}{10b - a}.

Implementing this solution in java:

public class Problem_33 {
	/**
	 * @return All the proper non-trivial curious fractions having numerator, denominator < 100
	 */
	public static List<Fraction> getCuriousFractions() {
		List<Fraction> curiousFractions = new ArrayList<Fraction>();

		for (int a = 1; a < 10; a++)
			for (int b = a + 1; b < 10; b++)
				if (Problem_33.checkCondition(a, b))
					curiousFractions.add(new Fraction(a, b));

		return curiousFractions;
	}

	/**
	 * Checks if the number is of the form xa/bx = a/b or ax/xb = a/b
	 *
	 * @param a The numerator of the fraction
	 * @param b The denominator of the fraction
	 * @return true if it can be formed into a curious fraction, false otherwise
	 */
	private static boolean checkCondition(int a, int b) {
		int numerator = 9 * a * b;
		int denominatorA = 10 * b - a;
		int denominatorB = 10 * a - b;
		return numerator % denominatorA == 0 && numerator / denominatorA < 10 || numerator % denominatorB == 0
		        && numerator / denominatorB < 10 ? true : false;
	}
}

Popularity: 11% [?]

Project Euler : Find Hexagonal Pentagonal Number

Problem 45 of Project Euler required one to find numbers which are triangular, pentagonal and hexagonal together. Checking for triangularity is redundancy as all hexagonal numbers are also triangular. So it boils down to solving the equation:

n(3n – 1) / 2 = m(2m – 1)

Using the Diophantine Equation solver at http://www.alpertron.com.ar/QUAD.HTM, we get the solution as

n_{i+1} = 97 \times n_i + 112 \times m_i - 44

m_{i+1} = 84 \times n_i + 97 \times m_i - 38

The solution comes very easily from here.

public class Problem_45 {
	/**
	 * Find a number which is Pentagonal and also Hexagonal
	 *
	 * @param index The nth number which is required
	 * @return The nth number which is both Pentagonal and Hexagonal
	 */
	public static int findPentaHexaNumber(int index) {
		int p = 1;
		int h = 1;
		do {
			// This is the solution to the Diophantine Equation
			// p(3p-1)/2 = h(2h-1)
			int p2 = 97 * p + 112 * h - 44;
			h = 84 * p + 97 * h - 38;
			p = p2;
			index--;
		} while (index != 0);

		return h * (2 * h - 1);
	}
}

Popularity: 9% [?]

Project Euler : Quadratic Producing Longest Prime Sequence

Problem 27 done! Ah well, nothing spectacular as such, but solved none the less. It’s a happy feeling.

The problem required one to find a quadratic of the form x^2 + a \times x + b, with the condition |a| < 1000, |b| < 1000 which produces the longest sequence of primes starting with x = 0.

Let us call f(x) = x^2 + a \times x + b

The first thing you notice is that the values of b must belong to the set of primes and they must always be positive.

f(0) = b, and hence b has to be a prime

The next thing to notice is that the values of a are influenced by that of b.

f(1) = 1 + a + b is a prime \Rightarrow a = [prime] – (1+b)

So all I did was to generate primes. Set b as one of the primes. Let a iterate over the other primes and form a polynomial function for each combination. This polynomial function was evaluated for ascending values of x and the longest sequence of primes recorded in each case. I used the commons-math-2.1 library by Apache commons to evaluate the quadratic function.

I did one additional thing. The problem mentions that the quadratic function n^2 + n + 41 generates a sequence of 40 primes. You must have noted that these polynomials cannot produce a sequence longer than the value of the constant term, which is b in our case (to see this, evaluate the expression with x = b). So for 0 < b < 41 the above is the best quadratic there is. Thus we need to begin at 41.

Below is my solution which runs in 1600ms on my laptop. Not good enough though :( .

public class Problem_27 {
	public static UnivariateRealFunction getPrimeNumberFunction() throws FunctionEvaluationException {
		PrimeNumbers primeGenerator = new PrimeNumbers(100000);
		List<Integer> primes = primeGenerator.getPrimeNumbers();
		int upperLimit = primeGenerator.getPrimeIndex(997);
		int lowerLimit = primeGenerator.getPrimeIndex(41);

		double[] coefficients = new double[3];
		coefficients[2] = 1;
		MaxObject<UnivariateRealFunction> maxLength = MaxObject.init();

		Stopwatch sw = new Stopwatch();
		sw.start();
		for (int i = upperLimit; i >= lowerLimit; i--) {
			coefficients[0] = primes.get(i);
			for (int j = 0; j < upperLimit; j++) {
				coefficients[1] = primes.get(j) - coefficients[0] - 1;
				UnivariateRealFunction quadratic = new PolynomialFunction(coefficients);
				maxLength.compare(quadratic, Problem_27.getSeriesLength(quadratic, primes));
			}
		}
		sw.stop();
		System.out.println(sw);

		return maxLength.getMaxObject();
	}

	private static int getSeriesLength(UnivariateRealFunction function, List<Integer> primes)
	        throws FunctionEvaluationException {
		for (int i = 0; true; i++) {
			int value = (int) function.value(i);
			if (value < 0 || !primes.contains(value))
				return i;
		}
	}
}

Popularity: 9% [?]

Project Euler : Sundays Falling On First Day Of Month In Twentieth Century

To solve the Project Euler Problem 19, I did initially search around a bit and found the wiki article which explains how to determine the day for any given date by consulting tables of centuries and months. Also I found a list of corresponding months for normal and leap years. By corresponding, I mean that two dates in these months will fall on the same day.

But when I started implementing this, I realized that the sun already provides us the GregorianCalendar class which has methods to do all this built in itself. And then the task was very simple:

public class Problem_19 {
	/**
	 * @return The number of times a Sunday appears as the first day of the month for the interval January 1901 -
	 *         December 2000
	 */
	public static int countNumberOfSundays() {
		int numberOfSundays = 0;

		Calendar cal = new GregorianCalendar();

		// We have been told that 1st of January, 1900 was a Monday
		cal.set(1900, Calendar.JANUARY, 1);
		int sundayValue = cal.get(Calendar.DAY_OF_WEEK) - 1;

		for (int year = 1901; year < 2001; year++)
			for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
				cal.set(year, month, 1);
				if (cal.get(Calendar.DAY_OF_WEEK) == sundayValue)
					numberOfSundays++;
			}

		return numberOfSundays;
	}
}

Popularity: 6% [?]

Project Euler : d For Which 1/d Has Longest Recurring Cycle

Problem 26 in Project Euler is a very simple question. There are two options – check the periodicity of numbers in quotient, or check the periodicity of remainders. Yup! The periodicity of remainders implies periodicity in quotient.

Here is my Java solution. It runs in 125ms on my Latitude D630 laptop.

public class Problem_26 {
	/**
	 * @return The number which has the highest recurring decimal periodicity
	 */
	public int getLargestPeriodicityNumber() {
		PrimeNumbersIterator primes = new PrimeNumbersIterator(1000);
		primes.reverseOrder();
		MaxObject<Integer> maxNumber = MaxObject.init();

		Stopwatch sw = new Stopwatch();
		sw.start();
		while (primes.hasNext()) {
			int i = primes.next();
			maxNumber.compare(i, getPeriodicity(i));
		}
		sw.stop();
		System.out.println(sw);

		return maxNumber.getMaxObject();
	}

	/**
	 * Get the periodicity of recurring decimals by checking the remainders
	 *
	 * @param number The number for which the periodicity is required
	 * @return The periodicity of recurring decimal
	 */
	private int getPeriodicity(int number) {
		List<Integer> remainders = new ArrayList<Integer>();

		int remainder = 10;
		remainders.add(remainder);
		while (true) {
			remainder = remainder % number * 10;
			if (remainders.contains(remainder))
				return remainders.size() - remainders.indexOf(remainder);
			remainders.add(remainder);
		}
	}

	public static void main(String[] args) {
		System.out.println(new Problem_26().getLargestPeriodicityNumber());
	}
}

Popularity: 9% [?]

What Does Evenly Divisible Mean?

I thought it meant the quotient should be even!!

But no! It means dividing a group of objects into subgroups of even size, i.e; same size.  Simply put, A is evenly divisible by B if it leaves no remainder.

Popularity: 6% [?]

Project Euler : Pascal Triangle To Find nCr

Problem 53 required one to find all the generated numbers of nCr, 1 <= n <= 100, which are greater than a million. And the solution was all too simple – Pascal Triangle.

Each row of the Pascal Triangle is a series of nCr. So all that was needed to be done was to generate a triangle to a depth of 100, and find all the large numbers.

One small modification that I could have done is – not all numbers needed to be calculated. Once a number greater than a million is found, all successive number in that series till the halfway mark will be greater than million. Remembering just the smallest number greater than a million should have sufficed.

public class Problem_53 {
	public static int solve() {
		int count = 0;

		Map<Settings, Object> settings = new HashMap<Settings, Object>();
		settings.put(Settings.ONLY_RIGHT_HALF_GENERATION, true);

		PascalTriangle pascalTriangle = new PascalTriangle(settings);
		for (int i = 1; i <= 100; i++) {
			int sum = 0;
			for (double num : pascalTriangle.constructNextLevel()) {
				if (num < 1000000)
					break;
				sum++;
			}
			count += sum > 0 ? (i % 2 == 0 ? 2 * sum - 1 : 2 * sum) : 0;
		}

		return count;
	}

	public static void main(String[] args) {
		System.out.println(Problem_53.solve());
	}
}

The Pascal Triangle Generator

public class PascalTriangle {
	private List<List<Double>> m_triangle;
	private int m_currentLevel;
	private boolean m_onlyRightHalfGeneration;

	public PascalTriangle(Map<Settings, Object> settings) {
		m_currentLevel = 0;
		initTree();
		m_onlyRightHalfGeneration = isOnlyRightHandGenerationEnabled(settings);
	}

	/**
	 * Create a new tree and initialize the Level 0
	 */
	private void initTree() {
		m_triangle = new ArrayList<List<Double>>();
		List<Double> levelZero = new ArrayList<Double>();
		levelZero.add(new Double(1));
		m_triangle.add(levelZero);
	}

	/**
	 * Check if the property ONLY_RIGHT_HALF_GENERATION is enabled by the user
	 *
	 * @param settings The settings provided by the user
	 * @return true if the ONLY_RIGHT_HALF_GENERATION is set to true
	 */
	private boolean isOnlyRightHandGenerationEnabled(Map<Settings, Object> settings) {
		return !settings.containsKey(Settings.ONLY_RIGHT_HALF_GENERATION) ? false : (Boolean) settings
		        .get(Settings.ONLY_RIGHT_HALF_GENERATION);
	}

	/**
	 * Construct the next level of the Pascal Triangle.
	 *
	 * @return the new level added to the Pascal Triangle
	 */
	public List<Double> constructNextLevel() {
		return m_onlyRightHalfGeneration ? constructRightHaflTreeNextLevel() : constructLeftHaflTreeNextLevel();
	}

	/**
	 * Construct the left half of the tree
	 */
	private List<Double> constructLeftHaflTreeNextLevel() {
		List<Double> nextLevel = new ArrayList<Double>();
		Double prevNum = new Double(0);
		for (Double num : m_triangle.get(m_currentLevel)) {
			nextLevel.add(prevNum + num);
			prevNum = num;
		}
		if (m_currentLevel % 2 != 0)
			nextLevel.add(2 * prevNum);

		m_triangle.add(nextLevel);
		m_currentLevel++;

		return nextLevel;
	}

	/**
	 * Construct the right half of the tree
	 */
	private List<Double> constructRightHaflTreeNextLevel() {
		List<Double> prevLevel = m_triangle.get(m_currentLevel);
		List<Double> nextLevel = new ArrayList<Double>();

		Double prevNum = prevLevel.get(0);
		if (m_currentLevel % 2 != 0)
			nextLevel.add(2 * prevNum);

		for (int i = 1; i < prevLevel.size(); i++) {
			Double num = prevLevel.get(i);
			nextLevel.add(prevNum + num);
			prevNum = num;
		}
		nextLevel.add(new Double(1));

		m_triangle.add(nextLevel);
		m_currentLevel++;

		return nextLevel;
	}

	/**
	 * Settings for the Pascal Triangle Generator
	 *
	 * @author AnuvratSingh
	 */
	public enum Settings {
		ONLY_RIGHT_HALF_GENERATION
	}
}

Popularity: 10% [?]

Project Euler : Problem 32 – All Round Pandigital

The problem requires one to find a product of two numbers such that the multiplicand/multiplier/product can be written as a 1 through 9 pandigital.

An example would be: 39 * 186 = 7254

Working with paper and a pencil, one can discover that the two form of solution are:

a * bbbb = cccc

aa * bbb = cccc

So all that was required to be done was generate all 9 digit permutations of 1-9 and then check if the arrangement satisfies any of the two cases mentioned above.

public class Problem_32<I extends Integer> {
	public static void main(String[] args) {
		System.out.println(new Problem_32<Integer>().computeSum());
	}

	public int computeSum() {
		int sum = 1;
		Set<Integer> products = new HashSet<Integer>();

		Iterator<CombinatoricsVector<I>> permutationIterator = getPermutationGenerator();
		while (!permutationIterator.isDone()) {
			permutationIterator.next();
			CombinatoricsVector<I> permutation = permutationIterator.getCurrentItem();
			products.add(checkCaseA(permutation));
			products.add(checkCaseB(permutation));
		}

		for (Integer i : products)
			sum += i;

		return sum;
	}

	/**
	 * Case A :: a x bbbb = cccc
	 *
	 * @return cccc if above equality holds, -1 otherwise
	 */
	private int checkCaseA(CombinatoricsVector<I> permutation) {
		int a = permutation.getValue(0);
		int b = get4Number(permutation, 1);
		int c = get4Number(permutation, 5);

		return a * b == c ? c : -1;
	}

	/**
	 * Case B :: aa x bbb = cccc
	 *
	 * @return cccc if above equality holds, -1 otherwise
	 */
	private int checkCaseB(CombinatoricsVector<I> permutation) {
		int a = get2Number(permutation, 0);
		int b = get3Number(permutation, 2);
		int c = get4Number(permutation, 5);

		return a * b == c ? c : -1;
	}

	private int get2Number(CombinatoricsVector<I> permutation, int startIdx) {
		return permutation.getValue(startIdx) * 10 + permutation.getValue(startIdx + 1);
	}

	private int get3Number(CombinatoricsVector<I> permutation, int startIdx) {
		return permutation.getValue(startIdx) * 100 + permutation.getValue(startIdx + 1) * 10
		        + permutation.getValue(startIdx + 2);
	}

	private int get4Number(CombinatoricsVector<I> permutation, int startIdx) {
		return permutation.getValue(startIdx) * 1000 + permutation.getValue(startIdx + 1) * 100
		        + permutation.getValue(startIdx + 2) * 10 + permutation.getValue(startIdx + 3);
	}

	private Iterator<CombinatoricsVector<I>> getPermutationGenerator() {
		ArrayList<I> array = new ArrayList<I>();
		for (int i = 1; i < 10; i++)
			array.add((I) new Integer(i));

		Iterator<CombinatoricsVector<I>> permutationIterator = new PermutationGenerator<I>(new CombinatoricsVector<I>(
		        array)).createIterator();
		permutationIterator.first();

		return permutationIterator;
	}
}

Popularity: 14% [?]