public class CoprimeNeighbors {
long gcd( long a, long b) {
return a == 0 ? b : gcd( b % a, a) ;
}
final long BIL = 1000 * 1000 * 1000 ;
boolean isPrime( int a) {
for ( int i = 2 ; i * i <= a; ++ i)
if ( a % i == 0 )
return false ;
return true ;
}
// find first 'cnt' primes
int [ ] findPrimes( int cnt) {
int [ ] primes = new int [ cnt] ;
int next = 2 ;
for ( int i = 0 ; i < cnt; ++ i) {
while ( ! isPrime( next) )
++ next;
primes[ i] = next++;
}
return primes;
}
// return product of 'k' random primes
long randomNumber( int [ ] primes, boolean [ ] forbidden, int k) {
int n = primes.length ;
boolean [ ] taken = new boolean [ n] ;
long x = 1 ;
for ( int repeat = 0 ; repeat < k; ++ repeat) {
int i;
do {
i = rand.nextInt ( n) ;
} while ( taken[ i] || forbidden[ i] ) ;
taken[ i] = true ;
long product = x * primes[ i] ;
if ( product / primes[ i] != x || product > BIL * BIL) {
return randomNumber( primes, forbidden, k) ; // 1e18 exceeded, try again
}
x *= primes[ i] ;
}
return x;
}
public long [ ] findAny( int len) {
final int x = 32 , y = 11 ;
long [ ] t = new long [ len] ;
int [ ] primes = findPrimes( x) ;
for ( int i = 0 ; i < len; ++ i) {
boolean [ ] forbidden = new boolean [ x] ;
if ( i != 0 )
for ( int j = 0 ; j < x; ++ j)
if ( t[ i- 1 ] % primes[ j] == 0 )
forbidden[ j] = true ;
while ( true ) {
t[ i] = randomNumber( primes, forbidden, y) ;
boolean ok = true ;
for ( int j = 0 ; j < i - 1 ; ++ j)
if ( gcd( t[ j] , t[ i] ) == 1 )
ok = false ;
if ( ok) break ;
}
}
return t;
}
}
cHVibGljIGNsYXNzIENvcHJpbWVOZWlnaGJvcnMgewoJbG9uZyBnY2QobG9uZyBhLCBsb25nIGIpIHsKCQlyZXR1cm4gYSA9PSAwID8gYiA6IGdjZChiICUgYSwgYSk7Cgl9CglmaW5hbCBsb25nIEJJTCA9IDEwMDAgKiAxMDAwICogMTAwMDsKCWJvb2xlYW4gaXNQcmltZShpbnQgYSkgewoJCWZvcihpbnQgaSA9IDI7IGkgKiBpIDw9IGE7ICsraSkKCQkJaWYoYSAlIGkgPT0gMCkKCQkJCXJldHVybiBmYWxzZTsKCQlyZXR1cm4gdHJ1ZTsKCX0KCS8vIGZpbmQgZmlyc3QgJ2NudCcgcHJpbWVzCglpbnRbXSBmaW5kUHJpbWVzKGludCBjbnQpIHsKCQlpbnRbXSBwcmltZXMgPSBuZXcgaW50W2NudF07CgkJaW50IG5leHQgPSAyOwoJCWZvcihpbnQgaSA9IDA7IGkgPCBjbnQ7ICsraSkgewoJCQl3aGlsZSghaXNQcmltZShuZXh0KSkKCQkJCSsrbmV4dDsKCQkJcHJpbWVzW2ldID0gbmV4dCsrOwoJCX0KCQlyZXR1cm4gcHJpbWVzOwoJfQoJLy8gcmV0dXJuIHByb2R1Y3Qgb2YgJ2snIHJhbmRvbSBwcmltZXMKCXN0YXRpYyBSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKCWxvbmcgcmFuZG9tTnVtYmVyKGludFtdIHByaW1lcywgYm9vbGVhbltdIGZvcmJpZGRlbiwgaW50IGspIHsKCQlpbnQgbiA9IHByaW1lcy5sZW5ndGg7CgkJYm9vbGVhbltdIHRha2VuID0gbmV3IGJvb2xlYW5bbl07CgkJbG9uZyB4ID0gMTsKCQlmb3IoaW50IHJlcGVhdCA9IDA7IHJlcGVhdCA8IGs7ICsrcmVwZWF0KSB7CgkJCWludCBpOwoJCQlkbyB7CgkJCQlpID0gcmFuZC5uZXh0SW50KG4pOwoJCQl9IHdoaWxlKHRha2VuW2ldIHx8IGZvcmJpZGRlbltpXSk7CgkJCXRha2VuW2ldID0gdHJ1ZTsKCQkJbG9uZyBwcm9kdWN0ID0geCAqIHByaW1lc1tpXTsKCQkJaWYocHJvZHVjdCAvIHByaW1lc1tpXSAhPSB4IHx8IHByb2R1Y3QgPiBCSUwgKiBCSUwpIHsKCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiZXhjZWVkIik7CgkJCQlyZXR1cm4gcmFuZG9tTnVtYmVyKHByaW1lcywgZm9yYmlkZGVuLCBrKTsgLy8gMWUxOCBleGNlZWRlZCwgdHJ5IGFnYWluCgkJCX0KCQkJeCAqPSBwcmltZXNbaV07CgkJfQoJCXJldHVybiB4OwoJfQoJcHVibGljIGxvbmdbXSBmaW5kQW55KGludCBsZW4pIHsKCQlmaW5hbCBpbnQgeCA9IDMyLCB5ID0gMTE7CgkJbG9uZ1tdIHQgPSBuZXcgbG9uZ1tsZW5dOwoJCWludFtdIHByaW1lcyA9IGZpbmRQcmltZXMoeCk7CgkJU3lzdGVtLm91dC5wcmludGxuKEFycmF5cy50b1N0cmluZyhwcmltZXMpKTsKCQlmb3IoaW50IGkgPSAwOyBpIDwgbGVuOyArK2kpIHsKCQkJYm9vbGVhbltdIGZvcmJpZGRlbiA9IG5ldyBib29sZWFuW3hdOwoJCQlpZihpICE9IDApCgkJCQlmb3IoaW50IGogPSAwOyBqIDwgeDsgKytqKQoJCQkJCWlmKHRbaS0xXSAlIHByaW1lc1tqXSA9PSAwKQoJCQkJCQlmb3JiaWRkZW5bal0gPSB0cnVlOwoJCQl3aGlsZSh0cnVlKSB7CgkJCQl0W2ldID0gcmFuZG9tTnVtYmVyKHByaW1lcywgZm9yYmlkZGVuLCB5KTsKCQkJCWJvb2xlYW4gb2sgPSB0cnVlOwoJCQkJZm9yKGludCBqID0gMDsgaiA8IGkgLSAxOyArK2opCgkJCQkJaWYoZ2NkKHRbal0sIHRbaV0pID09IDEpCgkJCQkJCW9rID0gZmFsc2U7CgkJCQlpZihvaykgYnJlYWs7CgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oImdjZCIpOwoJCQl9CgkJfQoJCXJldHVybiB0OwoJfQp9Cg==