Problem 49
Prime permutations
The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.
There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.
What 12-digit number do you form by concatenating the three terms in this sequence?
素数重排
公差为3330的三项等差序列1487、4817、8147在两个方面非常特别:其一,每一项都是素数;其二,两两都是重新排列的关系。
一位素数、两位素数和三位素数都无法构成满足这些性质的数列,但存在另一个由四位素数构成的递增序列也满足这些性质。
将这个数列的三项连接起来得到的12位数是多少?
@Test
public void test(){
Combination cb = new Combination(4);
List<int[]> cbs = cb.generateCom();
for( int i = 1000 ; i <= 3333 ; i ++){
if( isPrime(i) && checkOk( i, cbs)){
System.out.println("num=" + i + ( i + 3330) + ( i + 2 * 3330));
}
}
}
private boolean checkOk(int i, List<int[]> cbs) {
Set<Integer> set = new HashSet<Integer>();
int [] arr = new int[4];
arr[0] = Integer.valueOf( String.valueOf( Integer.toString(i).charAt(0)));
arr[1] = Integer.valueOf( String.valueOf( Integer.toString(i).charAt(1)));
arr[2] = Integer.valueOf( String.valueOf( Integer.toString(i).charAt(2)));
arr[3] = Integer.valueOf( String.valueOf( Integer.toString(i).charAt(3)));
for( int j = 0 ; j < cbs.size(); j ++){
int val = getCbVal(arr, cbs.get(j));
if( val >= 1000 && val < 9999 && isPrime(val)){
set.add(val);
}
}
return set.contains(i) && set.contains(i + 3330) && set.contains(i + 2 * 3330);
}
private int getCbVal(int[] arr, int[] id) {
int sum = 0;
for( int i = 0 ; i < id.length ; i ++){
sum += Math.pow(10, id[i]) * arr[i];
}
return sum;
}
public static boolean isPrime(int val) {
int num = Math.abs(val);
if (num < 10) {
if (num == 2 || num == 3 || num == 5 || num == 7) {
return true;
}
return false;
} else {
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
}
public static class Combination {
private int[] startArr;
public Combination(int size) {
startArr = new int[size];
for (int i = 0; i < size; i++) {
startArr[i] = i ;
}
}
public List<int[]> generateCom() {
List<int[]> ret = new ArrayList<int[]>();
ret.add(Arrays.copyOf(startArr, startArr.length));
while (true) {
int lastAsc = findLastAsc(startArr);
if (lastAsc == -1) {
break;
}
int lasBigThanAsc = findBigThanAsc(startArr, lastAsc);
exchangeEach(lastAsc, lasBigThanAsc, startArr);
ret.add(Arrays.copyOf(startArr, startArr.length));
}
return ret;
}
private int findBigThanAsc(int[] startArr2, int lastAsc) {
int i = 0;
for (i = startArr2.length - 1; i > lastAsc; i--) {
if (startArr2[i] > startArr2[lastAsc]) {
return i;
}
}
assert (i > lastAsc);
return i;
}
private void exchangeEach(int lastAsc, int lasBigThanAsc,
int[] startArr2) {
int temp = startArr2[lastAsc];
startArr2[lastAsc] = startArr2[lasBigThanAsc];
startArr2[lasBigThanAsc] = temp;
int[] sortArr = getCopyArr(lastAsc + 1, startArr2);
for (int i = 0; i < sortArr.length / 2; i++) {
temp = sortArr[sortArr.length - 1 - i];
sortArr[sortArr.length - 1 - i] = sortArr[i];
sortArr[i] = temp;
}
for (int i = lastAsc + 1; i < startArr2.length; i++) {
startArr2[i] = sortArr[i - lastAsc - 1];
}
}
private int[] getCopyArr(int start, int[] startArr2) {
int[] ret = new int[startArr2.length - start];
for (int i = start; i < startArr2.length; i++) {
ret[i - start] = startArr2[i];
}
return ret;
}
private int findLastAsc(int[] startArr2) {
for (int i = startArr2.length - 1; i > 0; i--) {
if (startArr2[i] > startArr2[i - 1]) {
return i - 1;
}
}
return -1;
}
public int getIntVal(int[] arr) {
int sum = arr[0];
for (int i = 1; i < arr.length; i++) {
sum = sum * 10 + arr[i];
}
return sum;
}
}