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;
}
}