project euler 118

Pandigital prime sets

Using all of the digits 1 through 9 and concatenating them freely to form decimal integers, different sets can be formed. Interestingly with the set {2,5,47,89,631}, all of the elements belonging to it are prime.

How many distinct sets containing each of the digits one through nine exactly once contain only prime elements?


全數字素數集合

使用1至9的全部數字,並自由連接起來組成十進制整數,可以構造不同的集合。其中一個集合{2,5,47,89,631}非常有趣,因爲它的所有元素都是素數。

有些集合包含數字1至9恰好各一次,且所有元素都是素數,這樣的集合有多少個?

package projecteuler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

public class Prj118 extends TestCase {

	public static final int LIMIT = (int) Math.pow(10, 9);

	public void testPandigitalPrimeSets() {

		Map<Integer, List<Integer>> dataMap = new HashMap<Integer, List<Integer>>();
		List<Integer> set1 = new ArrayList<Integer>();
		List<Integer> set2 = new ArrayList<Integer>();
		List<Integer> set3 = new ArrayList<Integer>();
		List<Integer> set4 = new ArrayList<Integer>();
		List<Integer> set5 = new ArrayList<Integer>();
		List<Integer> set6 = new ArrayList<Integer>();
		List<Integer> set7 = new ArrayList<Integer>();
		List<Integer> set8 = new ArrayList<Integer>();
		List<Integer> set9 = new ArrayList<Integer>();
		// set1.add(13);
		// set2.add(2);
		// set3.add(3);
		// set4.add(47);
		// set5.add(5);
		// set6.add(631);
		// set7.add(7);
		// set8.add(89);
		// set9.add(91);
		set1 = getSet(1);
		set2 = getSet(2);
		set3 = getSet(3);
		set4 = getSet(4);
		set5 = getSet(5);
		set6 = getSet(6);
		set7 = getSet(7);
		set8 = getSet(8);
		set9 = getSet(9);
		dataMap.put(1, set1);
		dataMap.put(2, set2);
		dataMap.put(3, set3);
		dataMap.put(4, set4);
		dataMap.put(5, set5);
		dataMap.put(6, set6);
		dataMap.put(7, set7);
		dataMap.put(8, set8);
		dataMap.put(9, set9);

		int[] arr = new int[9];
		List<int[]> resultList = new ArrayList<int[]>();
		dfSearch(arr, 0, dataMap, resultList, 0);
		System.out.println("count=" + count);

	}

	static long count = 0;

	/**
	 * [a1,a2,...,an], a1<a2<a3<...<an;
	 * @param arr
	 * @param depth
	 * @param dataMap
	 * @param resultList
	 * @param digitSize
	 */
	void dfSearch(int[] arr, int depth, Map<Integer, List<Integer>> dataMap,
			List<int[]> resultList, int digitSize) {

		if (digitSize >= 9 && isFind(arr, depth)) {

			int[] tp = Arrays.copyOfRange(arr, 0, depth);
			String str = "";
			for (int i = 0; i < tp.length; i++) {
				System.out.print(tp[i] + ",");
				str += Integer.toString(tp[i]);
			}

			System.out.println("=" + str);
			count++;

			return;
		}

		if (depth >= arr.length) {
			return;
		}

		for (int i = 1; i <= 9; i++) {
			if (depth == 0) {
				List<Integer> dataList = dataMap.get(i);
				for (int j = 0; j < dataList.size(); j++) {
					arr[depth] = dataList.get(j);
					dfSearch(arr, depth + 1, dataMap, resultList, Integer
							.toString(arr[depth]).length());
				}

				continue;
			}

			if (isCandidateId(arr, depth, i)) {
				List<Integer> dataList = dataMap.get(i);
				for (int j = 0; j < dataList.size(); j++) {
					int intVal = dataList.get(j);
					int digit = Integer.toString(intVal).length() + digitSize;
					if (digit <= 9 && isCandidateVal(arr, depth, intVal)) {
						arr[depth] = intVal;
						dfSearch(arr, depth + 1, dataMap, resultList, digit);
					}

					if (digit > 9) {
						break;
					}
				}
			}

		}
	}

	boolean isCandidateId(int[] arr, int depth, int id) {
		String str = "";
		for (int i = 0; i < depth; i++) {
			str += Integer.toString(arr[i]);
		}

		return !str.contains(Integer.toString(id));
	}

	boolean isCandidateVal(int[] arr, int depth, int intVal) {

		if (intVal < arr[depth - 1]) {
			return false;
		}

		String str = "";
		for (int i = 0; i < depth; i++) {
			str += Integer.toString(arr[i]);
		}

		String valStr = Integer.toString(intVal);

		for (int i = 0; i < valStr.length(); i++) {
			if (str.contains(String.valueOf(valStr.charAt(i)))) {
				return false;
			}
		}
		return true;

	}

	boolean isFind(int[] arr, int depth) {

		String str = "";
		for (int i = 0; i < depth; i++) {
			str += Integer.toString(arr[i]);
		}

		return str.length() == 9 && str.contains("1") && str.contains("2")
				&& str.contains("3") && str.contains("4") && str.contains("5")
				&& str.contains("6") && str.contains("7") && str.contains("8")
				&& str.contains("9");
	}

	List<Integer> getSet(int init0) {
		List<Integer> set = new ArrayList<Integer>();
		int[] arr = new int[9];
		dfs(arr, 0, init0, set);
		Collections.sort(set);
		// System.out.println(Arrays.toString(set.toArray()));
		System.out.println("id=" + init0 + ",size=" + set.size());
		return set;
	}

	void dfs(int[] arr, int startIndex, int init0, List<Integer> set) {

		if (startIndex >= 9) {
			int[] tmp = Arrays.copyOfRange(arr, 0, startIndex);
			int v = arr2Int(tmp);
			if (isPrime(v) && !set.contains(v)) {
				set.add(v);
				System.out.println(Arrays.toString(tmp));
			}
			return;
		}

		for (int i = 1; i <= 9; i++) {

			if (startIndex == 0) {
				arr[0] = init0;
				dfs(arr, startIndex + 1, init0, set);

			} else {
				if (isValid(arr, startIndex, i)) {
					int[] tmp = Arrays.copyOfRange(arr, 0, startIndex);
					int v = arr2Int(tmp);
					if (isPrime(v) && !set.contains(v)) {
						set.add(v);
					}
					arr[startIndex] = i;
					dfs(arr, startIndex + 1, init0, set);
				} else {
					continue;
				}
			}

		}

	}

	int arr2Int(int[] arr) {
		int v = 0;
		for (int i = 0; i < arr.length; i++) {
			v = v * 10 + arr[i];
		}
		return v;
	}

	boolean isValid(int[] arr, int startIndex, int v) {
		for (int i = 0; i < startIndex; i++) {
			if (v == arr[i]) {
				return false;
			}
		}
		return true;
	}

	boolean isPrime(int v) {
		if (v <= 10) {
			if (v == 2 || v == 3 || v == 5 || v == 7) {
				return true;
			}
			return false;
		}

		if (v % 2 == 0) {
			return false;
		}

		for (int i = 3; i * i <= v; i++) {
			if (v % i == 0) {
				return false;
			}
		}
		return true;
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章