0 ile 1000 arasındaki tüm asal değerler


9

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);}

6
Sadece "Dile özgü zorluklar istemiyoruz" inişlerini ön plana çıkarmak için, bazı kodları golften almak için yardım istemek konuyla ilgili ve zorluklardan farklı bir hikaye.
Martin Ender

4
Algoritmayı mı yoksa yalnızca sonucu mı korumamız gerekiyor?
John Dvorak

Ben 0 ve 1 yazdırır, çünkü ben kesinlikle doğru olmak için 2 de başlar.
histokrat

kodun daha hızlı yürütülmesini mi yoksa kaynak kodda daha az karakter mi kullanmaya çalışıyorsunuz?
user3629249

1
Golf konusunda yardım istediğiniz için, mevcut çözümünüzün karakter sayısını yazınıza eklemek yararlı olacaktır (89 olarak yapıyorum).
Mark Reed

Yanıtlar:


7

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


2
Ciltli çek biraz daha golfed edilebilir: d=p++%999. Aksi takdirde, bu oldukça hava geçirmez golf işi görünüyor!
Runer112

10

67 bayt

C'de deneme bölümünün gerçek bir alternatifi yoktur, ancak kesinlikle biraz golf oynayabilir.

for(int p=1,d;p++<999;d&&printf("%d\n",p))for(d=p;--d>1;)d=p%d?d:1;

1 bayt tasarruf sağlayan C99 başlangıç ​​bildirimleri gerektirir.


6

(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.


1
Wilson teoremi C için yararlı değildir çünkü ints 32 bittir. Aynı şey Fermat için de geçerli.
feersum

@feersum Oh, ateş et. Bu faktöriyeller için de bir problem. Büyük int tipi var mı?
xnor

@xnor Yerleşik değil.
Martin Ender

1
biri tanımlıysa 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)
apnorton

@anorton Sanırım demek istiyorsun (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 .
HVD

4

78 77 karakter

(Sadece diğer dillerde öğrenilen bazı püf noktaları uyguladım.)

int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

C99 modunda 76 karakter

for(int i=0,p,c;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}

2

58 karakter (veya tam bir program için 61)

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++);}

1

67 64 bayt

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);}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.