Bu C kodunu küçültmek mümkün mü? 0 ile 1000 arasındaki tüm astarları yazdırır.
C, 89 karakter
int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}
Bu C kodunu küçültmek mümkün mü? 0 ile 1000 arasındaki tüm astarları yazdırır.
C, 89 karakter
int i,p,c;for(i=2;i<1e3;i++){c=0;for(p=2;p<i;p++)if(i%p==0)c++;if(c==0)printf("%u\n",i);}
Yanıtlar:
59 57 bayt
@Feersum çözümüne dayanmaktadır, ancak öncelik kontrolü daha fazla golf edilebilir
for(int p=1,d;d=p++%999;d||printf("%d\n",p))for(;p%d--;);
Runer112 adlı kullanıcının yorumlarına göre düzenlendi
d=p++%999. Aksi takdirde, bu oldukça hava geçirmez golf işi görünüyor!
(Bunu, C'deki tamsayıların boyut sınırlamalarını fark etmediğini yazdım, bu yüzden kodu kısaltmak için muhtemelen kullanışlı değil.)
İlk olarak, algoritma hakkında bir kelime. Kodunuzu golf oynamadan önce, sonucu elde etmek için en iyi genel stratejiyi düşünmelisiniz.
Deneme bölümü yaparak asallık kontrol ediyoruz - Her potansiyel böleni test parasında i. İki döngü gerektirdiğinden, bu karakterlerde maliyetlidir. Yani, bir döngü olmadan ilkeliğin test edilmesi karakterleri kurtarır.
Genellikle daha kısa bir yaklaşım Wilson Teoremini kullanmaktır : sayı nsadece ve sadece
fact(n-1)%n == n-1
factfaktöriyel fonksiyon nerede . Eğer mümkün olan tüm test aşamasında olduğu ngelen 1etmek 1000, bu çalışan ürünün izleyerek faktöryel uygulama önlemek kolaydır Pve bunu güncellenmesi P*=nher döngü sonra. Bir milyona kadar prim basmak için bu stratejinin bir Python uygulaması .
Alternatif olarak, programınızın sadece 1000'e kadar olması gerektiği başka bir strateji daha açar: Fermat öncelik testi . Bazıları için aher asal ntatmin olur
pow(a,n-1)%n == 1
Ne yazık ki, bazı kompozitler nbu testi bazıları için de geçmektedir a. Bunlara Fermat psödoprimleri denir . Ancak, a=2ve bugüne kadar a=3birlikte başarısız olmayın n=1105, bu yüzden 1000'e kadar primleri kontrol etme amacınız için yeterlidirler. (1000 yerine 100 olsaydı, sadece kullanabilirsiniz a=2.) Yani, (kodsuz kod)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
Bu ayrıca primer 2 ve 3'ü tanıyamaz, bu nedenle bunların özel kasalı olması gerekir.
Bu yaklaşımlar daha mı kısa? Bilmiyorum çünkü C'de kod yazmıyorum. Ama, karakterleri eklemeye başlamak için bir kod parçasına yerleşmeden önce denemeniz gereken fikirler.
ints 32 bittir. Aynı şey Fermat için de geçerli.
fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }, sonuç oldukça büyük değerleri için 32 bitlik bir tamsayı taşmaz n. ( mmodül)
(n*fact(n-1,m)) % m. Hangi sorunu vurgular: factçünkü mdış döngü her yineleme için farklı olacaktır , çünkü uygulama özyinelemesini önleyemezsiniz .
Benzer bir soruya verdiğim cevabın yeniden kullanılması .
EDIT : bağımsız kod parçası, aramak için bir işlev yok.
for(int m,n=2;n<999;m>1?m=n%m--?m:n++:printf("%d\n",m=n));
Komple program:
n=2;main(m){n<999&&main(m<2?printf("%d\n",n),n:n%m?m-1:n++);}
Simyacı'nın çözümünden ilham alan:
int i=1,p;for(;i++<1e3;p-i||printf("%d\n",i)){p=1;while(i%++p);}