All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.cotelab.euler.Problem29 Maven / Gradle / Ivy

package net.sf.cotelab.euler;

import java.util.Arrays;
import java.util.LinkedList;

import net.sf.cotelab.util.math.Primes;

/**
 * A solution for Project Euler Problem 29.
 * The problem statement is
 * here.
 * @author Al Cote'
 */
public class Problem29 {
	private class Facts implements Comparable {
		private long[] factorCounts = null;
		private long n = -1;
		private long[] primeFactors = null;
		private Primes primes = null;
		private long[] uniqueFactors = null;
		
		public Facts(Primes primes, long n) {
			this.n = n;
			this.primes = primes;
		}

		private long[] calcFactorCounts() {
			long[] uf = getUniqueFactors();
			long[] pf = getPrimeFactors();
			long[] fc = new long[uf.length];
			int pfc = 0;
			
			for (int i = 0; i < uf.length; ++i) {
				long f = uf[i];
				fc[i] = 0;
				
				for (; pfc < pf.length && f == pf[pfc]; ++pfc) {
					++fc[i];
				}
			}
			
			return fc;
		}

		private long[] calcUniqueFactors() {
			long[] result = null;
			long[] raw = getPrimeFactors();
			LinkedList clean = new LinkedList();
			long oldEntry = -1;
			int count;
			
			for (int i = 0; i < raw.length; ++i) {
				if (raw[i] != oldEntry) {
					oldEntry = raw[i];
					clean.add(oldEntry);
				}
			}
			
			count = clean.size();
			result = new long[count];
			for (int i = 0; i < count; ++i) {
				result[i] = clean.get(i);
			}
			
			return result;
		}

		@Override
		public int compareTo(Facts o) {
			long[] myUF = getUniqueFactors();
			long[] hisUF = o.getUniqueFactors();
			int compLen = Math.min(myUF.length, hisUF.length);
			int lengthDif = myUF.length - hisUF.length;
			
			for (int i = 0; i < compLen; ++i) {
				long diff = myUF[i] - hisUF[i];
				
				if (diff < 0) {
					return -1;
				}
				
				if (diff > 0) {
					return 1;
				}
			}
			
			return lengthDif;
		}

		public long[] getFactorCounts() {
			if (factorCounts == null) {
				factorCounts = calcFactorCounts();
			}
			
			return factorCounts;
		}

		public long getN() {
			return n;
		}

		public long[] getPrimeFactors() {
			if (primeFactors == null) {
				primeFactors = primes.primeFactors(n);
			}
			
			return primeFactors;
		}

		public long[] getUniqueFactors() {
			if (uniqueFactors == null) {
				uniqueFactors = calcUniqueFactors();
			}
			
			return uniqueFactors;
		}
	}
	
	/* Derivation:
	 * 
	 * This is all about factors. We know that if x = y ** z, then x can be
	 * factored into z copies of y. If we consider the prime factors of y, then
	 * each such factor of y appears z times as often in the prime factorization
	 * of x.
	 * 
	 * Another approach looks at w ** x = y ** z. Observe that w and y must have
	 * the same prime factors, ignoring repetition. If we then pay attention to
	 * the repetitions of them, the factorization of y must have x/z times the
	 * number of instances of any given prime factor as w does. Note that if w
	 * and y don't have the same prime factors in them, then no x and z can make
	 * the equation valid.
	 * 
	 * I'm baffled, so I'm inclined to go brute force. The hard thing, though,
	 * is that we can't actually calculate these beasts with longs; we'd have to
	 * use BigInteger. Bummer - that'd be slow. We can't accumulate in a Set,
	 * either; there'll be something like 100 ** 100 of them.
	 * 
	 * So, let's calculate it!
	 */
	/**
	 * @param args unused.
	 */
	public static void main(String[] args) {
		Problem29 prob = new Problem29();
		int result = prob.calc();
		
		// ???
		System.out.println("result = " + result);
	}
	
	public int calc() {
		Primes primes = new Primes();
		Facts[] facts = new Facts[99];
		
		for (int n = 2; n <= 100; ++n) {
			facts[n - 2] = new Facts(primes, n);
		}
		
		Arrays.sort(facts);
		
		for (int i = 0; i < facts.length; ++i) {
			System.out.println(
					"{" + facts[i].getN() + "} " + Arrays.toString(
							facts[i].getUniqueFactors()) + " " +
							Arrays.toString(facts[i].getFactorCounts()) + " " +
							Arrays.toString(facts[i].getPrimeFactors()));
		}
		
		return 0;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy