为什么不结合 sum 和 product? (下面等效的java代码)
斯卡拉:
val r = scala.util.Random
// 10 digits produce to few collisions to control by hand:
// def arr = Vector (r.nextInt (10), r.nextInt (10), r.nextInt (10))
def arr = Vector (r.nextInt (3), r.nextInt (3), r.nextInt (3))
// first idea: a*b*c + a+b+c, but 3,0,0 and 2,1,0 produce
// product 0 and sum 3
// def checksum (v: Vector[Int]) : Int = v.product + v.sum
// so we just add 1 to every digit
def checksum (v: Vector[Int]) : Int = (v(0)+1)*(v(1)+1)*(v(2)+1) + v(0)+v(1)+v(2)
def cmp (a:Vector[Int], b:Vector[Int]) : Boolean = { checksum(a) == checksum(b)}
(1 to 30).foreach (i => {val a=arr; val b=arr; val m = cmp (a, b); println (s"match: $a $b $m") })
测试数据:
match: Vector(0, 1, 2) Vector(0, 1, 0) false
match: Vector(1, 1, 0) Vector(2, 1, 1) false
match: Vector(2, 1, 0) Vector(2, 0, 2) false
match: Vector(0, 0, 2) Vector(0, 1, 1) false
match: Vector(2, 1, 1) Vector(2, 1, 1) true
match: Vector(0, 1, 1) Vector(1, 0, 2) false
match: Vector(2, 0, 2) Vector(2, 0, 0) false
match: Vector(0, 2, 2) Vector(2, 1, 0) false
match: Vector(2, 2, 2) Vector(0, 1, 2) false
match: Vector(2, 2, 0) Vector(1, 1, 0) false
match: Vector(0, 2, 2) Vector(0, 0, 2) false
match: Vector(0, 2, 1) Vector(2, 1, 1) false
match: Vector(0, 2, 1) Vector(1, 0, 0) false
match: Vector(2, 2, 2) Vector(2, 1, 1) false
match: Vector(0, 1, 1) Vector(1, 0, 2) false
match: Vector(1, 0, 0) Vector(1, 0, 2) false
match: Vector(2, 1, 1) Vector(0, 1, 2) false
match: Vector(2, 0, 0) Vector(2, 1, 0) false
match: Vector(1, 2, 1) Vector(2, 1, 2) false
match: Vector(2, 2, 1) Vector(2, 1, 2) true
match: Vector(0, 0, 0) Vector(0, 2, 2) false
match: Vector(2, 0, 1) Vector(0, 1, 1) false
match: Vector(2, 0, 1) Vector(1, 2, 1) false
match: Vector(0, 1, 1) Vector(1, 1, 0) true
match: Vector(0, 2, 0) Vector(1, 0, 0) false
match: Vector(1, 2, 1) Vector(0, 1, 0) false
match: Vector(2, 0, 2) Vector(0, 1, 0) false
match: Vector(0, 1, 0) Vector(1, 2, 2) false
match: Vector(1, 1, 0) Vector(0, 0, 0) false
match: Vector(0, 1, 1) Vector(0, 2, 1) false
仍然需要逐个控制,我将编写一个检查函数,在比较之前对向量进行排序。我想,虽然代码是 scala,但很容易理解并转化为 java 等价物?
def cmp2 (a:Vector[Int], b:Vector[Int]) : Boolean = { a.sorted == b.sorted}
(1 to 3000).foreach (i => {val a=arr; val b=arr; if (cmp (a, b) != cmp2 (a, b)) println (s"match: $a $b ${cmp(a,b)} ${cmp2(a,b)}") })
// silence
当然,你也可以做数学证明:
(a+1)*(b+1)*(c+1)+a+b+c ?= (d+a+1)*(e+b+1)*(c+1)+(d+a)+b+c | d!=0
// or
(a+1)*(b+1)*(c+1)+a+b+c ?= (d+a+1)*(e+b+1)*(c+1)+(d+a)+b+c | d!=0, e!=0
像往常一样,留给读者作为练习:)
Java:
Random r = new java.util.Random();
int [] arr (int max) {
int[] v = new int[3];
v[0] = r.nextInt (max);
v[1] = r.nextInt (max);
v[2] = r.nextInt (max);
return v;
}
int checksum (int[] v) { return (v[0] +1) * (v[1] +1) * (v[2] +1) + v[0] + v[1] + v[2]; }
boolean cmp (int[] a, int[] b) { return checksum(a) == checksum(b); }
for (int i = 0; i < 30; ++i) {
int [] a = arr (3);
int [] b = arr (3);
boolean m = cmp (a, b);
System.out.printf ("match: %6s %6s %b\n", Arrays.toString (a), Arrays.toString (b), m);
}