Archive for the 'Problems' Category

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: 7% [?]

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: 16% [?]

Project Euler : Largest N Digit Pandigital Prime Number

Well, I did a brute force for problem 41 for Project Euler. There’s a smarter way of course, but I still haven’t implemented a Permutation Generator. That later.

I already have a good enough prime number generator. So all I did was to generate all the prime number till 7 digits long. Why did I not go any further?

8 digit pandigital numbers will sum up to 36, and the 9 digit numbers will sum up to 45. So all the pandigital 8 and 9 digit numbers will be non-prime. So we need to check till atmost the 7 digit prime numbers.

Now apart from a prime generator, I also have a prime number iterator, which can iterate forwards as well as backwards. So all I had to do was to ask my iterator to iterate backwards and check if the prime number is pandigital or not.

Obviously, my prime number iterator internally calls my sieve of Eratosthenes to generate prime numbers using java.util.BitSet.

Surprisingly, the code runs in just a few seconds! I was expecting it to take atleast a minute.

Here is my prime number iterator:


public class PrimeNumbersIterator implements Iterator<Integer> {
	private PrimeNumbers m_pNumber;
	private int m_currentIndex;
	private boolean m_reverse;

	public PrimeNumbersIterator(int upperLimit) {
		m_pNumber = new PrimeNumbers(upperLimit);
		m_reverse = false;
	}

	public boolean hasNext() {
		if (!m_reverse)
			return m_currentIndex < m_pNumber.getNumberOfPrimes() ? true : false;
		else
			return m_currentIndex >= 0 ? true : false;
	}

	public Integer next() {
		Integer prime = hasNext() ? m_pNumber.getPrime(m_currentIndex) : null;
		if (m_reverse)
			m_currentIndex--;
		else
			m_currentIndex++;

		return prime;
	}

	public void remove() {
		throw new UnsupportedOperationException();
	}

	public void reverseOrder() {
		m_reverse = !m_reverse;
		m_currentIndex = m_pNumber.getNumberOfPrimes() - 1;
	}
}

And here is a small unoptimized method to check if the number is pandigital or not:


	public static boolean isNPandigital(int number) {
		int numberOfDigits = NumberUtil.numberOfDigits(number);
		int[] digits = new int[numberOfDigits];
		Arrays.fill(digits, 0);

		while (number > 0) {
			int digit = number % 10;
			if (digit == 0 || digit > numberOfDigits || digits[digit - 1]++ == 1)
				return false;
			number /= 10;
		}

		return true;
	}

Popularity: 32% [?]

Project Euler : Numbers That Are Fifth Powers Of Their Digits

The idea in solving this problem was pretty simple. If you consider the digits a, b, c, d, e and f, the sum of their 5th powers will always be the same irrespective of their ordering. So, instead of iterating over all the numbers, I chose to iterate over all the collection of the digits. For each collection, find the sum of the fifth powers of the digits, get the digits of the sum ordered in ascending order and if the digits of the sum and the collection are the same, then the sum is a number that we wanted.

For example, consider the digits 0, 0, 0, 1, 4, 5. Now the sum of their fifth powers is 4150. I retrieve the digits of the sum in ascending order – 0, 0, 0, 1, 4, 5. See, the two are the same. Thus 4150 is the number we were looking for.

It takes just some 5000 iterations to complete the search.

The main class:

package problems_21_30;

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

public class Problem_30 {
	private int[] m_fifthPowers;

	public Problem_30() {
		m_fifthPowers = new int[] { 0, 1, 32, 243, 1024, 3125, 7776, 16807, 32768, 59049 };
	}

	private int[] getDigits(int number) {
		int[] digits = new int[6];
		int i = 0;

		while (number > 0) {
			digits[i++] = number % 10;
			number /= 10;
		}
		Arrays.sort(digits);

		return digits;
	}

	public List<Integer> getSillyNumbers() {
		List<Integer> sillyNumbers = new ArrayList<Integer>();

		for (int a = 0; a < 10; a++)
			for (int b = a; b < 10; b++)
				for (int c = b; c < 10; c++)
					for (int d = c; d < 10; d++)
						for (int e = d; e < 10; e++)
							for (int f = e; f < 10; f++) {
								int sum = m_fifthPowers[a] + m_fifthPowers[b] + m_fifthPowers[c] + m_fifthPowers[d]
								        + m_fifthPowers[e] + m_fifthPowers[f];
								int[] digits = getDigits(sum);
								if (a == digits[0] &amp;&amp; b == digits[1] &amp;&amp; c == digits[2] &amp;&amp; d == digits[3]
								        &amp;&amp; e == digits[4] &amp;&amp; f == digits[5])
									sillyNumbers.add(sum);
							}

		return sillyNumbers;
	}

	public static void main(String[] args) {
		List<Integer> sillyNumbers = new Problem_30().getSillyNumbers();

		int sum = -1;
		for (int number : sillyNumbers)
			sum += number;

		System.out.println(sum);
	}

}

Popularity: 31% [?]

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: 13% [?]

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: 10% [?]

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: 48% [?]

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: 16% [?]

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: 18% [?]

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: 17% [?]