Archive for the 'Problems' Category

Page 2 of 4

Project Euler : Sum Of Both Diagonals In A 1001 By 1001 Spiral

This one I solved using just paper and pencil, and am happy about it. All that was required was a keen observation on how the numbers along the diagonal form out of the previous number. Lets take a look at one of the diagonals of the 5 x 5 spiral

21     22     23     24     25
20     07     08     09     10
19     06     01     02     11
18     05     04     03     12
17     16     15     14     13

Consider the numbers along the diagonal originating in the center at 01 moving towards the upper right corner. The numbers are 01, 09, 25. Let me tell you that the next number along this diagonal will be 49. Do you see any pattern emerging yet?

Well, all these number are squares -

1^2 = 1

3^2 = 9

5^2 = 25

7^2 = 49

Considering the distance of the number from the center of the spiral as a parameter, this series can be written as:

d_1 = (2n + 1) ^2

\implies d_1 = 4n^2 + 4n + 1

The numbers along the other diagonals are simply derived from d_1 by subtracting certain values.

d_2 = d_1 - 2n

\implies d_2 = 4n^2 + 2n + 1

d_3 = d_2 - 2n

\implies d_3 = 4n^2 + 1

d_4 = d_3 - 2n

\implies d_4 = 4n^2 - 2n + 1

Now, all that the problem asks us to do is to sum up the numbers d_1, d_2, d_3, d_4 for n = 1, 2, \ldots 500.

sum = \Sigma(16n^2 + 4n + 4) for n = 1, 2 \ldots 500

This is a simple summing up exercise. Solved !!

Popularity: 12% [?]

Project Euler : Digits Of Sum of 1^1 + 2^2 + 3 ^ 3 …

Nothing to talk about here. Simple implementation.

Main class:

package problems_40_50;

public class Problem_48 {
	private static final long MAX_LENGTH = 10000000000L;

	/**
	 * Multiplies two long numbers and truncates the sum length to the MAX_LENGTH
	 *
	 * @return
	 */
	private long multiply(long a, long b) {
		return a * b % Problem_48.MAX_LENGTH;
	}

	public long sumOfSeries(int maxNumber) {
		long[] numberGrid = new long[maxNumber];
		for (int i = 0; i < maxNumber; i++)
			numberGrid[i] = i + 1;

		for (int i = 1; i < maxNumber; i++)
			for (int j = i; j < maxNumber; j++) {
				if ((j + 1) % 10 == 0)
					continue;
				numberGrid[j] = multiply(numberGrid[j], j + 1);
			}

		long sum = 0;
		for (int i = 0; i < maxNumber; i++) {
			if ((i + 1) % 10 == 0)
				continue;
			sum += numberGrid[i];
		}

		return sum;
	}

	public static void main(String[] args) {
		Problem_48 p = new Problem_48();
		System.out.println(p.sumOfSeries(1000) % Problem_48.MAX_LENGTH);
	}
}

Popularity: 8% [?]

Project Euler : First Triangle Number To Have Over Five Hundred Divisors

This was solved by brute force. I implemented a method to find the number of factors of a number by its prime factorization. Having already built up a sieve method to quickly get primes, the number of factors can be found faster this way.

PrimeNumber class:

package pba.common.number;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

public class PrimeNumbers {
	private List<Integer> m_primeNumbers;

	/**
	 * @param sizeOfSieve The upper bound to the determination of prime numbers.
	 */
	public PrimeNumbers(int sizeOfSieve) {
		m_primeNumbers = new ArrayList<Integer>();
		sieveOfEratosthenes(sizeOfSieve);
	}

	/**
	 * Calculates the number of factors for a given number by prime factorization. For example, <br>
	 * 28 = 2^2 * 7 <br>
	 * Thus the number of factors of 28 are (2+1)*(1+1) = 6.
	 *
	 * @param number The number whose number of factors are required
	 * @return The number of factors the given number has
	 */
	public int getNumberOfFactors(int number) {
		int numberOfFactors = 1;
		for (int prime : m_primeNumbers) {
			int exponent = 0;
			while (number % prime == 0) {
				exponent++;
				number /= prime;
			}
			numberOfFactors *= exponent + 1;
		}

		return numberOfFactors;
	}

	/**
	 * Finds the primes using the SieveOfEratosthenes method
	 *
	 * @param sizeOfSieve The upper bound till which the primes are to be calculated
	 */
	private void sieveOfEratosthenes(int sizeOfSieve) {
		m_primeNumbers.add(2);
		BitSet primeBits = new BitSet(sizeOfSieve / 2);
		int primeNumberIndex = primeBits.nextClearBit(0);
		int primeNumber = 2 * primeNumberIndex + 3;
		while (primeNumber < sizeOfSieve) {
			m_primeNumbers.add(primeNumber);
			for (int i = primeNumberIndex; i < sizeOfSieve / 2; i += primeNumber)
				primeBits.set(i);
			primeNumberIndex = primeBits.nextClearBit(primeNumberIndex);
			primeNumber = 2 * primeNumberIndex + 3;
		}
	}
}

Main class:

package problems_11_20;

import pba.common.number.PrimeNumbers;

public class Problem_12 {
	public static void mainAnuvrat(String[] args) {
		PrimeNumbers p = new PrimeNumbers(1000000);

		int triangleNumber = 1;
		int step = 1;
		while (p.getNumberOfFactors(triangleNumber) < 500)
			triangleNumber += ++step;

		System.out.println(triangleNumber);
	}

	public static void mainProjectEuler(String[] args) {
		PrimeNumbers p = new PrimeNumbers(1000000);

		boolean odd = true;
		int n = 1;
		int numberOfFactors = 0;
		int memoization = 1;
		do {
			if (odd) {
				int temp = p.getNumberOfFactors((n + 1) / 2);
				numberOfFactors = memoization * temp;
				memoization = temp;
			} else {
				int temp = p.getNumberOfFactors(n + 1);
				numberOfFactors = memoization * temp;
				memoization = temp;
			}
			odd = !odd;
			n++;
		} while (numberOfFactors < 500);
		n--;

		System.out.println(n * (n + 1) / 2);
	}
}

Project Euler did suggest an improvement on this. It says that since

t = \frac{n \times (n+1)}{2}

and n, n+1 being co-primes, the number of divisors can be found as

D(t) = D(n) \times D(\frac{n+1}{2}) if n is odd

D(t) = D(\frac{n}{2}) \times D(n+1) if n is even

This provides a lot of advantage over the previous implementation. The first being that we are now looking to find the number of factors for a smaller numbers. Secondly, the value for the n+1 can be used in the next triangle number, thus saving more computations.

Popularity: 45% [?]

Project Euler : Evaluate Sum Of All Amicable Pairs

Once the task of finding sum of all divisors was taken care of, this problem held little challenge. I have mentioned how to compute the sum of all the divisors in an earlier post:

Sum Of Divisors

Take a number, find the sum of its divisors. If the sum is greater than the number itself, then find the sum of divisors of this sum. If the two sums are equal, then the two are amicable numbers.

Pair class:

package pba.common.tools;

/**
 * A data object to manage pair of objects
 *
 * @author AnuvratSingh
 * @param <A>
 * @param <B>
 */
public class Pair<A, B> {
	private A m_first;
	private B m_second;

	public Pair(A first, B second) {
		m_first = first;
		m_second = second;
	}

	public A getFirst() {
		return m_first;
	}

	public B getSecond() {
		return m_second;
	}

	@SuppressWarnings("unchecked")
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || o.getClass() != this.getClass())
			return false;

		Pair<Integer, Integer> test = (Pair<Integer, Integer>) o;
		return this.getFirst() == test.getFirst() && this.getSecond() == test.getSecond();
	}
}

Amicable Number class:

package pba.common.number;

import java.util.ArrayList;
import java.util.List;

import pba.common.tools.Pair;

public class AmicableNumber {
	/**
	 * Does an exhaustive search for all the pairs of amicable numbers
	 *
	 * @param startIndex The first number from which the search commences
	 * @param endIndex The number up to which the search needs to be performed
	 * @return A list of all pairs of amicable numbers
	 */
	public static List<Pair<Integer, Integer>> getAmicableNumbers(int startIndex, int endIndex) {
		List<Pair<Integer, Integer>> amicableNumbers = new ArrayList<Pair<Integer, Integer>>();

		PrimeNumber p = new PrimeNumber(2 * endIndex);
		for (int i = startIndex; i <= endIndex; i++) {
			int sumOfFactors = p.getSumOfDivisors(i) - i;
			if (sumOfFactors <= i)
				continue;

			if (p.getSumOfDivisors(sumOfFactors) - sumOfFactors == i)
				amicableNumbers.add(new Pair<Integer, Integer>(i, sumOfFactors));
		}

		return amicableNumbers;
	}
}

Popularity: 14% [?]

Sum Of Divisors

Let n be an integer factorized as following:

n = {p_1}^{e_1} \times {p_2}^{e_2} \times \ldots \times {p_k}^{e_k}

The sum of divisors of n is:

\sigma(n) = a_1 \times a_2 \times \ldots \times a_k

where,

a_k = \frac{{p_k}^{e_k + 1} - 1}{p_k - 1} = {p_k}^{e_k} \times \ldots \times {p_k}^{2} \times {p_k}^{1}

In the simpler case of n = p^e, the sum is

\sigma(n) = p^e \times \ldots \times p^2 \times p

This I learned from the article written by Hisanori Mishima found here. The idea translates into a nice little loop to find the sum of divisors. The Java implementation of it has been done by me and is thus:

package pba.common.number;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

public class PrimeNumber {
	private List<Integer> m_primeNumbers;

	/**
	 * @param sizeOfSieve The upper bound to the determination of prime numbers.
	 */
	public PrimeNumber(int sizeOfSieve) {
		m_primeNumbers = new ArrayList<Integer>();
		sieveOfEratosthenes(sizeOfSieve);
	}

	/**
	 * @param number The number whose sum of divisors is required
	 * @return The sum of divisors of the given number
	 */
	public int getSumOfDivisors(int number) {
		int sum = 1;
		while (number > 1) {
			int temp = 1;
			int primeFactor = getSmallestPrimeFactor(number);
			while (number % primeFactor == 0) {
				temp = temp * primeFactor + 1;
				number /= primeFactor;
			}
			sum *= temp;
		}

		return sum;
	}

	/**
	 * @param number The number whose smallest prime factor is required
	 * @return The smallest rpime factor for the given number
	 */
	public int getSmallestPrimeFactor(int number) {
		for (int prime : m_primeNumbers)
			if (number % prime == 0)
				return prime;

		return Integer.MIN_VALUE;
	}
}

Note that the list of prime numbers can be quickly found by using the Sieve of Eratosthenes.

Popularity: 15% [?]

Project Euler : Sum Total Of All Name Scores

Problem 22 of Project Euler defines name score as the word value of a name multiplied by its position when a list of names is sorted. So, we need to sort the array first. I used Radix Sort for it. Simple implementation, it has been written below:

RadixComparator class:

package pba.common.text;

import java.util.Comparator;

/**
 * This is the Comparator class to be used for Radix Sorting.
 *
 * @author AnuvratSingh
 */
public class RadixComparator implements Comparator<String> {
	int columnNum;

	/**
	 * @param col Sorting takes place by considering the value at this column as the key
	 */
	public RadixComparator(int col) {
		columnNum = col;
	}

	/**
	 * This method compares two strings
	 *
	 * @param s1 The first string
	 * @param s2 The second string
	 * @return If length of both the strings is less than the column value, return 0. Else, if s1 is of smaller length
	 *         than column, then return -1. Else if s1 is of length greater than column, but s2 is smaller then return
	 *         1. If both are of length greater than column, then return the difference between the characters at
	 *         column. Please note, no conversion to lower case is done.
	 */
	public int compare(String s1, String s2) {
		int l2 = s2.length();

		if (s1.length() < columnNum + 1)
			return l2 < columnNum + 1 ? 0 : -1;
		else if (l2 < columnNum + 1)
			return 1;
		else
			return s1.charAt(columnNum) - s2.charAt(columnNum);
	}
}

RadixSort class:

package pba.common.tools.sort;

import java.util.Arrays;

import pba.common.text.RadixComparator;

/**
 * This class performs Radix Sort
 *
 * @author AnuvratSingh
 */
public class RadixSort {
	/**
	 * @param words The array of words which need to be sorted
	 * @param maxLength The length of the longest word in the array
	 * @return A sorted array of the words
	 */
	public static String[] sort(String[] words, int maxLength) {
		for (int i = maxLength - 1; i > -1; --i)
			Arrays.sort(words, new RadixComparator(i));
		return words;
	}

	/**
	 * @param words The array of words which need to be sorted
	 * @return A sorted array of words
	 */
	public static String[] sort(String[] words) {
		int maxLength = 0;
		for (String word : words) {
			int length = word.length();
			if (length > maxLength)
				maxLength = length;
		}

		return RadixSort.sort(words, maxLength);
	}
}

EnglishWordUtil class:

package pba.common.text;

/**
 * A class which allows manipulations with the English Words
 *
 * @author AnuvratSingh
 */
public class EnglishWordUtil {
	/**
	 * Returns the numerical value of a word which is found by summing the alphabetical position of each character in
	 * the word. For example, the word value for SKY is 19 + 11 + 25 = 55
	 *
	 * @param word the word whose numerical value is required
	 * @return the numerical value of the given word
	 */
	public static int getNumericalValue(String word) {
		String lowerCaseWord = word.toLowerCase();

		int sum = 0;
		for (int i = 0; i < lowerCaseWord.length(); i++)
			sum += lowerCaseWord.charAt(i) - 'a' + 1;

		return sum;
	}
}

Main class:

package problems_21_30;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import pba.common.text.EnglishWordUtil;
import pba.common.tools.sort.RadixSort;

public class Problem_22 {
	private static final String fileName = "problem_22.in";

	public static void main(String[] args) throws IOException {
		// Read all the names from the input file
		BufferedReader bufferedReader = new BufferedReader(new FileReader(Problem_22.fileName));
		String[] words = bufferedReader.readLine().split("\",\"");

		// Correct the first and the last word which have "
		words[0] = words[0].substring(1);
		int numberOfWords = words.length;
		String lastWord = words[numberOfWords - 1];
		words[numberOfWords - 1] = lastWord.substring(0, lastWord.length() - 1);

		// Sort all the names
		String[] sortedWords = RadixSort.sort(words);

		// Find the name score sum
		int sum = 0;
		for (int i = 0; i < sortedWords.length; i++)
			sum += (i + 1) * EnglishWordUtil.getNumericalValue(sortedWords[i]);

		System.out.println(sum);
	}
}

Popularity: 19% [?]

Project Euler : Palindromic In Base 10 And 2

All the numbers which are palindromic in both base 10 and 2 were needed by the Problem 36 of Project Euler. One obvious thing which comes immediately is that since the number needs to be a palindrome in base as well, it as to be odd. So we check for only the odd numbers which reduces the effort by half.

I went ahead and made a method which reverses a given  number. If the number and its reverse are the same then the number is a palindrome. If the number is a palindrome in one base, check for the same property in the other base.

However, Project Euler has provided a better solution to this problem. In this particular question, palindromes up to 1 million were needed to be checked. So using my method, there would be a need to check 500000 numbers. A simpler thing to do would be to generate palindromes in one base and check for their property in the other base. Take for instance the number xyz, two possible palindromes are xyzyx and xyzzyx. Going by this method, the effort reduces to generating approximately 2000 palindromes in one base and checking for their validity in the other base!

Below are the classes I used to get the work done. I have mentioned both the solutions – anuvratSolution and projectEulerSolution. anuvratSolution uses the checkIfPalindrome method with respective bases from the PalindromeUtil class, while the projectEulerSolution uses makePalindrome from the same class to make a palindrome in base 2, and then checkIfPalindrome with base as 10 to get the solution.

The Radix enum class:

package pba.common.enums.number;

public enum Radix {
	DECIMAL("Decimal - Base 10", 10), BINARY("Binary - Base 2", 2);

	private final String m_name;
	private final int m_base;

	Radix(String name, int base) {
		m_name = name;
		m_base = base;
	}

	public String getName() {
		return m_name;
	}

	public int getBase() {
		return m_base;
	}
}

The NumberUtil class:

package pba.common.number;

import pba.common.enums.number.Radix;

public class NumberUtil {
	/**
	 * Given a number, reverse it.
	 *
	 * @param number The number, in base 10, which needs to be reversed without any leading zeroes.
	 * @return The reversed number, in base 10, without any leading zeroes
	 */
	public static long reverse(long number, Radix base) {
		long reversed = 0;
		while (number > 0) {
			reversed = base.getBase() * reversed + number % base.getBase();
			number /= base.getBase();
		}
		return reversed;
	}
}

The PalindromeUtil class:

package pba.common.tools;

import pba.common.enums.number.Radix;
import pba.common.number.NumberUtil;

public class PalindromeUtil {
	/**
	 * @param number The number which needs to be checked in base 10
	 * @param base The base in which the number is to be checked for palindrome property
	 * @return True if the number is a palindrome, false otherwise
	 */
	public static boolean checkIfPalindrome(long number, Radix base) {
		return number == NumberUtil.reverse(number, base);
	}

	/**
	 * Given a number, it forms a palindrome out of it. For example, for the number xyz, the possible palindromes are
	 * xyzzyx and xyzyx.
	 *
	 * @param number The number out of which a palindrome needs to be made
	 * @param base The base in which the construction is done, for example, decimal, binary, octal, etc.
	 * @param oddLength Specifies whether the constructed number is to be of odd length or even length. For the example
	 *            mentioned above, if oddLength was true, the the number returned would be xyzyx.
	 * @return A palindrome formed using the number provided and having length parity as specified
	 */
	public static long makePalindrome(long number, Radix base, boolean oddLength) {
		long palin = number;
		if (oddLength)
			number /= base.getBase();

		while (number > 0) {
			palin = base.getBase() * palin + number % base.getBase();
			number /= base.getBase();
		}

		return palin;
	}
}

The Problem_36 class:

package problems_31_40;

import pba.common.enums.number.Radix;
import pba.common.tools.PalindromeUtil;

public class Problem_36 {
	private static final int MAX_NUMBER = 1000000;

	public static void anuvratSolution(String[] args) {
		long sum = 0;
		for (int i = 1; i < Problem_36.MAX_NUMBER; i += 2)
			if (PalindromeUtil.checkIfPalindrome(i, Radix.DECIMAL) &amp;amp;&amp;amp; PalindromeUtil.checkIfPalindrome(i, Radix.BINARY))
				sum += i;
		System.out.println(sum);
	}

	public static void projectEulerSolution(String[] args) {
		long sum = 0;
		for (int iter = 0; iter < 2; iter++) {
			boolean oddLength = iter == 0 ? true : false;
			for (int i = 1;; i++) {
				long palin = PalindromeUtil.makePalindrome(i, Radix.BINARY, oddLength);
				if (palin > Problem_36.MAX_NUMBER)
					break;
				if (PalindromeUtil.checkIfPalindrome(palin, Radix.DECIMAL))
					sum += palin;
			}
		}
		System.out.println(sum);
	}

	public static void main(String[] args) {
		Problem_36.projectEulerSolution(args);
		// Problem_36.anuvratSolution(args);
	}
}

Popularity: 16% [?]

Project Euler : The Millionth Lexicographic Permutation Of The Digits

The 24th problem of Project Euler wanted the one-millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012   021   102   120   201   210

This was yet another problem which I solved with paper and pencil.

We determine one digit at a time. Say the most significant digit is x, then the remaining 9 digits can fill up the remaining places of the 10 digit number. This can be done in 9! = 362880 ways.

362880 X 2 < 1000000 < 362880 X 3

This implies that all the numbers with 0 and 1 as the most significant digits make up 362880 X 2 numbers, which is less than a million, and when we start with 2 as the most significant digit, the one millionth number comes before the series is over. Thus our first digit is 2.

Now with that fixed, we need to find the 1000000 – 2 X 362880 = 274240th number arranged lexicographically using digits 0, 1, 3, 4, 5, 6, 7, 8 and 9. This time we need to consider 8! = 40320.

40320 X 6 < 274240 < 40320 X 7

Thus we need the 7th digit which is 7. So our number starts with 27.

The same step is to be repeated over and over again. In a condensed notation, the digits found are:

9! X 2 < 1000000 < 9! X 3 => digit is 2; 1000000 – 725760 = 274240

8! X 6 < 27420 < 8! X 7 => digit is 7; 27420 – 241920 = 32320

7! X 6 < 32320 < 7! X 7 => digit is 8; 32320 – 30240 = 2080

6! X 2 < 2080 < 6! X 3 => digit is 3; 2080 – 1440 = 640

5! X 5 < 640 < 5! X 6 => digit is 9; 640 – 600 = 40

4! X 1 < 40 < 4! X 2 => digit is 1; 40 – 24 = 16

3! X 2 < 16 < 3! X 3 => digit is 5; 16 – 12 = 4

At this point the digits left are 0, 4 and 6. The 4th number ordered lexicographically will be 460.The number we set out to find is thus 2783915460.

Popularity: 43% [?]

Project Euler : A 1000 Digit Fibonacci Number

The 25th problem in Project Euler asks the user to find the first fibonacci number which has 1000 digits. I brute forced the solution using the BigInteger class of java to find the solution. Here’s the code:

package problems_21_30;

import java.math.BigInteger;

public class Problem_25 {
	public static void main(String[] args) {
		BigInteger[] number = new BigInteger[3];
		number[0] = BigInteger.ONE;
		number[1] = BigInteger.ONE;
		int index = 1;
		int count = 2;
		while (number[index].toString().length() < 1000) {
			index = (index + 1) % 3;
			number[index] = number[(index + 2) % 3].add(number[(index + 1) % 3]);
			count++;
		}
		System.out.println(count);
	}
}

Popularity: 22% [?]

Project Euler : Finding The nth Digit Of The Fractional Part Of Irrational Number

The Problem 40 of Project Euler required just a pencil and a paper to get the answer. We are given an irrational decimal fraction by concatenating consecutive integers:

0.123456789101112131415 …

The 12^{th} digit of this irrational number is 1 and is denoted as d_{12}. The problem requires us to determine the product:

d_1 x d_{10} x d_{100} x d_{1000} x d_{10000} x d_{100000} x d_{1000000}

A simple enumeration of digits and their positions works out easily.

To begin with, there are only 9 single digit numbers, namely, 1 – 9. So the first 9 places are occupied by single digit numbers. Next, there are 90 double digit numbers from 10 – 99. So these occupy a total of 180 places. We have now accounted for 189 places in out irrational number.

Determine the digits d_{100} and d_{1000} are as simple as illustrated below:

For d_{100}:

Excess from last known digit position = 100 – 9 = 91

Numbers crossed in 91 positions = 91 / 2 = 45

Since the remainder is 1, we want the 1st digit of the 46th number from the one that appeared on position 9.

Thus the number we seek is 9 + 46 = 54, and the digit is therefore 5.

For d_{1000}:

Excess from last known digit position = 1000 – 189 =18 1

Numbers crossed in 811 positions = 811 / 3 = 270

Since the remainder is 1, we want the 1st digit of the 271st number from the one that appeared on position 189.

Thus the number we seek is 99 + 271 = 370, and the digit is therefore 3.

Repeating the same for all the digits we needed, the result is:

d_{1} = 1

d_{10} = 1

d_{100} = 5

d_{1000} = 3

d_{10000} = 7

d_{100000} = 2

d_{1000000} = 1

Thus the product is 210

Popularity: 7% [?]