Java 7+, TIO'da n = 50 inç ~ 30 saniye
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Random;
class Main{
public static void main(String[] a){
int n=50;
Random randomGenerator = new Random();
int i = n+1;
int squaredN = n*n;
int[]randomIntegers = new int[i];
randomIntegers[n] = squaredN;
while(true){
for(i=n; i-->1; ){
randomIntegers[i] = randomGenerator.nextInt(squaredN);
}
Set<Integer> result = new HashSet<>();
Arrays.sort(randomIntegers);
for(i=n; i-->0; ){
result.add(randomIntegers[i+1] - randomIntegers[i]);
}
if(!result.contains(0) && result.size()==n){
System.out.println(result);
return;
}
}
}
}
Şimdilik bu zorluğun kod-golf versiyonu için cevabımın yorumlanmamış versiyonu, sadece küçük bir değişiklikle: aralıktaki bir tamsayı java.util.Random#nextInt(limit)yerine kullanılır , çünkü yaklaşık iki kat daha hızlıdır .(int)(Math.random()*limit)[0, n)
Çevrimiçi deneyin.
Açıklama:
Kullanılan yaklaşım:
Kod iki bölüme ayrılmıştır:
nToplamı rastgele tamsayıların bir listesini oluşturun n squared.
- Daha sonra tüm değerlerin benzersiz olup olmadığını ve hiçbirinin sıfır olup olmadığını kontrol eder ve her ikisi de falsey ise, bir sonuç elde edene kadar durulayın ve tekrarlayın.
Adım 1 aşağıdaki alt adımlarla yapılır:
1) n-1Aralıkta rastgele tamsayıların bir miktarını oluşturun [0, n squared). Ve eklemek 0ve n squaredbu listeye. Bu O(n+1)performansta yapılır .
2) Daha sonra diziyi yerleşik ile sıralar java.util.Arrays.sort(int[]), Bu, O(n*log(n))dokümanlarda belirtildiği gibi performansta yapılır :
Belirtilen ints dizisini artan sayısal sıraya göre sıralar. Sıralama algoritması, Jon L. Bentley ve M. Douglas McIlroy'un "Bir Sıralama Fonksiyonu Mühendislik", Software-Practice and Experience, Vol. 23 (11) S. 1249-1265 (Kasım 1993). Bu algoritma, diğer hızlı sıralamaların ikinci dereceden performansa düşmesine neden olan birçok veri kümesinde n * log (n) performansı sunar.
3) Her çift arasındaki farkı hesaplayın. Bu sonuçta ortaya çıkan farklar listesi, ntoplanan tam sayıları içerecektir n squared. Bu O(n)performansta yapılır .
İşte bir örnek:
// n = 4, nSquared = 16
// n-1 amount of random integers in the range [0, nSquared):
[11, 2, 5]
// Add 0 and nSquared to it, and sort:
[0, 2, 5, 11, 16]
// Calculate differences:
[2, 3, 6, 5]
// The sum of these differences will always be equal to nSquared
sum([2, 3, 6, 5]) = 16
Bu nedenle yukarıdaki bu üç adım, adım 2'den ve her şeyin etrafındaki döngüden farklı olarak performans için oldukça iyidir, bu temel bir kaba kuvvettir. 2. Adım şu alt adımlara ayrılmıştır:
1) Farklar listesi zaten a java.util.Set. Bu Setin boyutunun eşit olup olmadığını kontrol edecektir n. Öyleyse, ürettiğimiz tüm rastgele değerlerin benzersiz olduğu anlamına gelir.
2) Ve aynı zamanda hiçbir içerdiğini kontrol edecektir 0meydan aralığında rastgele değerler sorar beri Set içinde [1, X]nerede Xolduğu n squaredeksi toplamı [1, ..., n-1]da belirttiği gibi, @Skidsdev aşağıda açıklamada.
Yukarıdaki iki seçenekten herhangi biri (tüm değerler benzersiz değilse veya bir sıfır mevcutsa), yeni bir dizi oluşturur ve 1. adıma sıfırlayarak tekrar ayarlayın. Bu, bir sonuç elde edene kadar devam eder. Bu nedenle, zaman biraz değişebilir. TIO için 3 saniyede bir kez n=50, ama aynı zamanda 55 saniyede bittiğini gördüm n=50.
Tekdüzelik kanıtlamak:
Bunun tamamen dürüst olduğunu nasıl kanıtlayacağımdan tam olarak emin değilim. java.util.Random#nextIntDocs tarif edildiği gibi, kesin üniforma:
intBu rasgele sayı üretecinin dizisinden eşit olarak dağıtılmış bir sonraki yalancı rayı döndürür . Genel sözleşmesi, nextIntbir intdeğerin sahte olarak üretilip iade edilmesidir. 2 32 olası intdeğerin tümü (yaklaşık) eşit olasılıkla üretilir.
Bu (sıralı) rastgele değerler arasındaki farklar elbette tekdüze değildir, ancak bir bütün olarak kümeler tekdüzedir. Yine, bunu matematiksel olarak nasıl kanıtlayacağımdan emin değilim, ancak burada,10,000n=10 çoğu kümenin benzersiz olduğu bir Sayaçlı bir Haritaya oluşturulan kümeleri (for ) koyacak bir komut dosyası ; bazıları iki kez tekrarlanır; ve tekrarlanan maksimum oluşum genellikle aralıktadır [4,8].
Kurulum Talimatları:
Java, Java kodunun nasıl oluşturulacağı ve çalıştırılacağı konusunda bol miktarda bilgiye sahip oldukça iyi bilinen bir dildir, bu kadar kısa tutacağım.
Kodumda kullanılan tüm araçlar Java 7'de mevcuttur (belki de zaten Java 5 veya 6'da, ancak her ihtimale karşı 7'yi kullanalım). Java 7 zaten arşivlenmiş eminim, bu yüzden kodumu çalıştırmak için Java 8 indirmenizi öneririm.
Gelişmelerle ilgili düşünceler:
Sıfır kontrolü için bir iyileştirme bulmak ve tüm değerlerin benzersiz olup olmadığını kontrol etmek istiyorum. 0Diziye eklediğimiz rastgele değerin zaten içinde olmadığından emin olarak daha önce kontrol edebilirdim , ancak birkaç şey anlamına gelir: dizi ArrayListyerleşik yöntemi kullanabilmemiz için bir olmalıdır .contains; henüz listede bulunmayan rastgele bir değer bulana kadar while döngüsü eklenmelidir. Sıfır için kontrol artık .contains(0)Sette yapıldığı için (sadece bir kez kontrol edilir), performansın .containsen az nkez kontrol edilecek olan Listedeki döngüyü eklemeye kıyasla, bu noktada kontrol etmesi daha olasıdır. , ama büyük olasılıkla daha fazla.
Benzersizlik kontrolüne gelince, sadece programın 1. adımından sonra toplanan nrastgele tamsayılarımız var n squared, bu yüzden ancak o zaman hepsinin benzersiz olup olmadığını kontrol edebiliriz. Dizi yerine sıralanabilir bir Liste tutmak ve aradaki farkları kontrol etmek mümkün olabilir, ancak ciddiye sadece onları koyarak Setve bu Setin boyutu bir nkez olup olmadığını kontrol daha performans artıracaktır şüpheliyim .