project euler 41

Problem 41


Pandigital prime

We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.

What is the largest n-digit pandigital prime that exists?


全数字的素数

如果一个n位数恰好使用了1至n每个数字各一次,我们就称其为全数字的。例如,2143就是一个4位全数字数,同时它恰好也是一个素数。

最大的全数字的素数是多少?

@Test
	public void test() {
		for (int i = 9; i >= 2; i--) {

			Combination comb = new Combination(i);
			List<int[]> combinations = comb.generateCom();
			for (int j = combinations.size() - 1; j >= 0; j--) {
				int val = comb.getIntVal(combinations.get(j));
				if (isPrime(val)) {
					System.out.println("maxVal=" + val + ",bits=" + i);
					return;
				}
			}

		}
	}

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

		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;

		}
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值