project euler 90

Problem 90


Cube digit pairs

Each of the six faces on a cube has a different digit (0 to 9) written on it; the same is done to a second cube. By placing the two cubes side-by-side in different positions we can form a variety of 2-digit numbers.

For example, the square number 64 could be formed:

In fact, by carefully choosing the digits on both cubes it is possible to display all of the square numbers below one-hundred: 01, 04, 09, 16, 25, 36, 49, 64, and 81.

For example, one way this can be achieved is by placing {0, 5, 6, 7, 8, 9} on one cube and {1, 2, 3, 4, 8, 9} on the other cube.

However, for this problem we shall allow the 6 or 9 to be turned upside-down so that an arrangement like {0, 5, 6, 7, 8, 9} and {1, 2, 3, 4, 6, 7} allows for all nine square numbers to be displayed; otherwise it would be impossible to obtain 09.

In determining a distinct arrangement we are interested in the digits on each cube, not the order.

{1, 2, 3, 4, 5, 6} is equivalent to {3, 6, 4, 1, 2, 5}
{1, 2, 3, 4, 5, 6} is distinct from {1, 2, 3, 4, 5, 9}

But because we are allowing 6 and 9 to be reversed, the two distinct sets in the last example both represent the extended set {1, 2, 3, 4, 5, 6, 9} for the purpose of forming 2-digit numbers.

How many distinct arrangements of the two cubes allow for all of the square numbers to be displayed?


立方体数字对

在一个立方体的六个面上分别标上不同的数字(从0到9),对另一个立方体也如法炮制。将这两个立方体按不同的方向并排摆放,我们可以得到各种各样的两位数。

例如,平方数64可以通过这样摆放获得:

事实上,通过仔细地选择两个立方体上的数字,我们可以摆放出所有小于100的平方数:01、04、09、16、25、36、49、64和81。

例如,其中一种方式就是在一个立方体上标上{0, 5, 6, 7, 8, 9},在另一个立方体上标上{1, 2, 3, 4, 8, 9}。

在这个问题中,我们允许将标有6或9的面颠倒过来互相表示,只有这样,如{0, 5, 6, 7, 8, 9}和{1, 2, 3, 4, 6, 7}这样本来无法表示09的标法,才能够摆放出全部九个平方数。

在考虑什么是不同的标法时,我们关注的是立方体上有哪些数字,而不关心它们的顺序。

{1, 2, 3, 4, 5, 6}等价于{3, 6, 4, 1, 2, 5}
{1, 2, 3, 4, 5, 6}不同于{1, 2, 3, 4, 5, 9}

但因为我们允许在摆放两位数时将6和9颠倒过来互相表示,这个例子中的两个不同的集合都可以代表拓展集{1, 2, 3, 4, 5, 6, 9}。

对这两个立方体有多少中不同的标法可以摆放出所有的平方数?

package projecteuler;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;

public class Prj90 extends TestCase {

	public void testHashCode() {

		CubeDigitPairs pair = null;
		CubeDigitPairs pair2 = null;
		Set<Integer> lf = new HashSet<Integer>();
		Set<Integer> rt = new HashSet<Integer>();
		lf.addAll(Arrays.asList(0, 1, 2, 3, 4, 6));
		rt.addAll(Arrays.asList(0, 5, 6, 7, 8, 9));
		pair = new CubeDigitPairs(lf, rt);
		pair2 = new CubeDigitPairs(rt, lf);
		
		Set<CubeDigitPairs> set = new HashSet<Prj90.CubeDigitPairs>();
		set.add(pair);
		set.add(pair2);
		
		assertTrue( pair.equals(pair2));
		assertTrue( set.size() == 1);
	}

	public void testCubeDigitPairs() {

		int count = 0;
		Set<CubeDigitPairs> set = new HashSet<CubeDigitPairs>();

		for (int i1 = 0; i1 <= 9; i1++) {
			for (int i2 = i1 + 1; i2 <= 9; i2++) {

				if (i2 == i1) {
					continue;
				}

				for (int i3 = i2 + 1; i3 <= 9; i3++) {
					if (i3 == i1 || i3 == i2) {
						continue;
					}
					for (int i4 = i3 + 1; i4 <= 9; i4++) {
						if (i4 == i1 || i4 == i2 || i4 == i3) {
							continue;
						}
						for (int i5 = i4 + 1; i5 <= 9; i5++) {
							if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) {
								continue;
							}
							for (int i6 = i5 + 1; i6 <= 9; i6++) {
								if (i6 == i1 || i6 == i2 || i6 == i3
										|| i6 == i4 || i6 == i5) {
									continue;
								}
								count++;
								for (int j1 = 0; j1 <= 9; j1++) {
									for (int j2 = j1 + 1; j2 <= 9; j2++) {
										if (j2 == j1) {
											continue;
										}
										for (int j3 = j2 + 1; j3 <= 9; j3++) {
											if (j3 == j1 || j3 == j2) {
												continue;
											}
											for (int j4 = j3 + 1; j4 <= 9; j4++) {
												if (j4 == j1 || j4 == j2
														|| j4 == j3) {
													continue;
												}
												for (int j5 = j4 + 1; j5 <= 9; j5++) {
													if (j5 == j1 || j5 == j2
															|| j5 == j3
															|| j5 == j4) {
														continue;
													}
													for (int j6 = j5 + 1; j6 <= 9; j6++) {
														if (j6 == j1
																|| j6 == j2
																|| j6 == j3
																|| j6 == j4
																|| j6 == j5) {
															continue;
														}

														Set<Integer> lf = new HashSet<Integer>();
														Set<Integer> rt = new HashSet<Integer>();
														lf.addAll(Arrays
																.asList(i1, i2,
																		i3, i4,
																		i5, i6));
														rt.addAll(Arrays
																.asList(j1, j2,
																		j3, j4,
																		j5, j6));

														if (lf.size() != 6
																|| rt.size() != 6) {
															continue;
														}

														CubeDigitPairs pairs = new CubeDigitPairs(
																lf, rt);

														if (pairs
																.checkCondition()) {
															set.add(pairs);
														}

													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}

		}

		for (CubeDigitPairs pair : set) {
			System.out.println(pair.left.toString() + "|"
					+ pair.right.toString());
		}
		System.out.println("count=" + set.size() + ",count=" + count);

	}

	public static class CubeDigitPairs {
		public Set<Integer> left = new HashSet<Integer>();
		public Set<Integer> right = new HashSet<Integer>();

		public CubeDigitPairs(Set<Integer> left, Set<Integer> right) {
			super();
			this.left.clear();
			for (int val : left) {
				this.left.add(val);
			}

			this.right.clear();
			for (int val : right) {
				this.right.add(val);
			}
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((left == null) ? 0 : left.hashCode() + right.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			CubeDigitPairs other = (CubeDigitPairs) obj;

			return (left.equals(other.left) && right.equals(other.right))
					| (left.equals(other.right) && right.equals(other.left));
		}

		public boolean checkCondition() {
			// 01、04、09、16、25、36、49、64\81

			boolean ok_01 = (left.contains(0) && right.contains(1))
					|| left.contains(1) && right.contains(0);
			boolean ok_04 = (left.contains(0) && right.contains(4))
					|| left.contains(4) && right.contains(0);
			boolean ok_09 = (left.contains(0) && right.contains(9))
					|| left.contains(9) && right.contains(0);
			ok_09 |= (left.contains(0) && right.contains(6))
					|| left.contains(6) && right.contains(0);

			boolean ok_16 = (left.contains(1) && right.contains(6))
					|| left.contains(6) && right.contains(1);
			ok_16 |= (left.contains(1) && right.contains(9))
					|| left.contains(9) && right.contains(1);

			boolean ok_25 = (left.contains(2) && right.contains(5))
					|| left.contains(5) && right.contains(2);
			boolean ok_36 = (left.contains(3) && right.contains(6))
					|| left.contains(6) && right.contains(3);
			ok_36 |= (left.contains(3) && right.contains(9))
					|| left.contains(9) && right.contains(3);

			boolean ok_49 = (left.contains(4) && right.contains(9))
					|| left.contains(9) && right.contains(4);
			ok_49 |= (left.contains(4) && right.contains(6))
					|| left.contains(6) && right.contains(4);

			boolean ok_64 = (left.contains(6) && right.contains(4))
					|| left.contains(4) && right.contains(6);
			ok_64 |= (left.contains(9) && right.contains(4))
					|| left.contains(4) && right.contains(9);

			boolean ok_81 = (left.contains(8) && right.contains(1))
					|| left.contains(1) && right.contains(8);

			return ok_01 && ok_04 && ok_09 && ok_16 && ok_25 && ok_36 && ok_49
					&& ok_64 && ok_81;
		}

	}
	
	

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值