Asal sayıları “asal karakter” kullanmadan bulma


21

Göreviniz kabul etmeyi seçerseniz, N tamsayısını girdi olarak kabul eden bir program / işlev yazmaktır . Program / fonksiyon ilk N asal sayının listesini çıkarmalı / vermelidir . Ancak buradaki açıklama: kodunuzda asal karakterleri kullanmanıza izin verilmiyor . Asal karakter, Unicode kod noktası asal bir sayı olan bir karakterdir. Yazdırılabilir ASCII aralığında bunlar:

%)+/5;=CGIOSYaegkmq

Ancak kural, kodunuz bunları kullanıyorsa ASCII olmayan karakterler için de geçerlidir.

  • Geçerli bir giriş, N değeri olan 0 <N <= T , T'yi seçebileceğiniz , ancak 10000'den büyük veya ona eşit olması gereken bir tamsayıdır . T sonlu olmak zorunda değildir.
  • Geçersiz girişler için (tamsayı olmayanlar, tamsayılar dışında), bir istisna atayın veya hiçbir şey döndürmeyin / hiçbir şey döndürmeyin.
  • Giriş olarak öncü / izleyen boşluk olan bir tam sayı geçersiz sayılır.
  • +Giriş olarak as işareti karakterli bir tam sayı geçersiz sayılır.
  • Giriş olarak başında sıfır olan bir tam sayı geçerli olarak kabul edilir.
  • Diliniz zaten ayrıştırılmış bir tamsayıyı giriş olarak geçirmenize izin veriyorsa, yukarıdaki ayrıştırma kuralları (aralık dışında) int kullanılmadığı için geçerli değildir.
  • Giriş her zaman taban-10'dur.
  • Yerleşik asal jeneratörlerin ve asallık test cihazlarının (asal çarpanlara ayırma fonksiyonlarını içerir) kullanımına izin verilmez.
  • Kaynak kısıtlaması Unicode karakterlere uygulanır, ancak puan için bayt sayımı, isterseniz başka bir kodlamada olabilir.
  • Çıktı, tek bir izleyen yeni satır içerebilir, ancak bu gerekli değildir.
  • Asal sayı listesini bir dizge olarak çıkarıp verirseniz, her asal sayının bir veya daha fazla basamaksız karakter (ler) ile sınırlandırılması gerekir. Kullanacağınız sınırlayıcıyı seçebilirsiniz.
  • Bu bir mücadelesidir, bayttaki en kısa kod kazanır.

Kodunuzu doğrulamak için Yığın Parçacığını

Kodunuzun asıl karakterler içermediğini doğrulamak için aşağıdaki Yığın Parçacığını kullanabilirsiniz:

var primes=[],max=10000;for(var i=2;i<=max;i++){primes.push(i);}for(var N=2;N<Math.sqrt(max);N++){if(primes.indexOf(N)===-1){continue;}primes=primes.filter(function (x){return x===N||x%N!==0;});}function setText(elem,text){var z=('innerText' in elem)? 'innerText' : 'textContent';elem[z]=text;}function verify(inputCode,resultSpan){var invalidChars=[];var success=true;for(var i=0;i<inputCode.length;i++){var cc = inputCode.charCodeAt(i);if (cc>max){setText(resultSpan,"Uh oh! The char code was bigger than the max. prime number calculated by the snippet.");success = false;break;}if (primes.indexOf(cc)!==-1){invalidChars.push(inputCode[i]);}}if (invalidChars.length===0&&success){setText(resultSpan, "Valid code!");}else if(success) {  var uniqueInvalidChars = invalidChars.filter(function (x, i, self){return self.indexOf(x)===i;});setText(resultSpan, "Invalid code! Invalid chars: " + uniqueInvalidChars.join(""));    }}document.getElementById("verifyBtn").onclick=function(e){e=e||window.event;e.preventDefault();var code=document.getElementById("codeTxt").value;verify(code,document.getElementById("result"));};
Enter your code snippet here:<br /><textarea id="codeTxt" rows="5" cols="70"></textarea><br /><button id="verifyBtn">Verify</button><br /><span id="result"></span>


10
O bu oldukça zalim ;... yasaklanmasını olur
ɐɔıʇǝɥʇuʎs

Asallık test cihazlarına izin verilmiyorsa, asal çarpanlara ayırma işlevi ne olur.
Maltysen

@Maltysen Asal çarpanlara ayırma işlevlerinden, bir sayının asal olup olmadığını çok hızlı bir şekilde görebilirsiniz, korkarım ki izin verilmez. Bunu açıklığa kavuşturacağım.
ProgramFOX

Bu geçersiz girdilerin bir kısmını atmak zorunda mıyız? Örneğin, eğer dilimizin string>> int işlevi bir öncülüğe izin veriyorsa +, bunları manuel olarak atmak için hayal kırıklığı yaratıyor gibi görünmektedir.
Runer112

11
Bu konuda çok heyecanlandım ve bir çözüm bulmaya başladım, daha sonra kapalı parenlerin yasaklandığını fark ettim. Ben dışarıdayım.
Alex A.

Yanıtlar:


10

CJam, 19 18 30 34 33 19 17 21 20 bayt

Çevrimiçi deneyin.

{_3\#,2>__ff*:~-<N*}

Bu muhtemelen şimdiye kadar uyguladığım en korkunç verimsiz algoritmalardan biri. Ama boyut için yaptım!

Cevabım CJam'da isimsiz bir fonksiyon gibi davranan bir kod bloğundan ibaret. Yığın üzerinde hemen önceki bir tamsayı ile çalıştırın ve ortaya çıkan liste yığına dökülür. Girişteki üst sınırı sonsuz olarak kabul ediyorum, bu yüzden o sınırı kontrol etmek zorunda kalmıyorum.

Algoritmam , giriş geçerliyse, en inputyüksek değerden daha büyük bir sayı vermesi garanti edilen 3. güce yükselterek başlar input. Daha sonra bu sayıdan 2'ye kadar olan tamsayıların bir listesi oluşturulur, bu bizim istediğiniz tüm asal sayıları içerecek kadar büyük bir alandır. Kompozit sayılardan kurtulmak için ... ... ... her bir çift üründen oluşan bir liste oluştururuz; bu, 4 ila bazı aptalca büyük değerlere sahip tüm kompozit sayıları, amaçlarımız için yeterince büyük olan bir sayı oluşturur. Öyleyse, bu listedeki her öğeyi orijinal listeden çıkarmak, ilk inputöğelere ayırmak ve öğeleri yeni satır karakteriyle birleştirmek meselesi .

Algoritma gereken herhangi bir giriş için çalışıyorum. Bununla birlikte, tercüman / bilgisayarın yeterli hafızası veya zamanı olup olmadığı diğer bir sorudur, çünkü zaman ve alan gereksinimleri girdiyle ilgili olarak üsteldir. Yani giriş çevrimiçi tercüman için yaklaşık 5'ten, çevrimdışı olan için yaklaşık 8'den büyükse, o zaman bu sorunun cevabı muhtemelen hayır olacaktır.


3
heh, 17 yaşındayken cevabında en fazla sayıda bayt var.
Corey Ogburn,

Neden ihtiyacım var S*?
jimmy23013

@ user23013 Algoritmadan içeri giren 1'den küçük geçersiz girişler, yalnızca boş bir liste oluşturur. Ancak bu onlar için yasal bir çıktı değil, bu nedenle bu geçersiz girdiler için boş bir çıktı üretmek üzere liste öğelerine boşluk içeren birleştirme yapıyorum.
Runer112

1
Bunu farkettim, Sana karakter değil mi?
Zacharı

Bu ana karakter. Bunu söylerken 2 yıldan fazla geciktiğimi biliyorum , ancak bu cevap geçersiz
Zacharý

8

Java. 474 bayt

i\u006dport j\u0061v\u0061.util.*\u003bvoid b(int b\u0029{Lon\u0067 c\u003d2L,d,f[]\u003d{}\u003bfor(f\u003dArr\u0061ys.copy\u004ff(f,b\u0029,Arr\u0061ys.fill(f,0L\u0029\u003bb-->0\u003b\u0029for(d\u003d0L\u003bf[b]<1\u003bf[b]\u003dd<1?c:f[b],d\u003d0L,c\u002b\u002b\u0029for(lon\u0067 h:f\u0029d\u003dh>0&&c\u002fh*h\u003d\u003dc?1:d\u003bj\u0061v\u0061x.x\u006dl.bind.JAXB.un\u006d\u0061rsh\u0061l(""\u002bArr\u0061ys.\u0061sList(f\u0029,Lon\u0067.cl\u0061ss\u0029\u003b}

Fonksiyon argümanı ile girdi alır, atılan istisna ile çıktı verir.

Girintili'ye:

i\u006dport j\u0061v\u0061.util.*\u003b
void b(int b\u0029{
    Lon\u0067 c\u003d2L,d,f[]\u003d{}\u003b
    for(f\u003dArr\u0061ys.copy\u004ff(f,b\u0029,Arr\u0061ys.fill(f,0L\u0029\u003bb-->0\u003b\u0029
        for(d\u003d0L\u003bf[b]<1\u003bf[b]\u003dd<1?c:f[b],d\u003d0L,c\u002b\u002b\u0029
            for(lon\u0067 h:f\u0029
                d\u003dh>0&&c\u002fh*h\u003d\u003dc?1:d\u003b
    j\u0061v\u0061x.x\u006dl.bind.JAXB.un\u006d\u0061rsh\u0061l(""\u002bArr\u0061ys.\u0061sList(f\u0029,Lon\u0067.cl\u0061ss\u0029\u003b
}

Kaçan karakterler kaldırıldı:

import java.util.*;
void b(int b){
    Long c=2L,d,f[]={};
    for(f=Arrays.copyOf(f,b),Arrays.fill(f,0L);b-->0;)
        for(d=0L;f[b]<1;f[b]=d<1?c:0,d=0L,c++)
            for(long h:f)
                d=h>0&&c/h*h==c?1:d;
    javax.xml.bind.JAXB.unmarshal(""+Arrays.asList(f),Long.class);
}

Açıklama:

Long c,d,f[]={};                                                //Initialize variables.

for(f=java.util.Arrays.copyOf(f,b),Arrays.fill(f,0L);b-->0;)
    f=java.util.Arrays.copyOf(f,b),Arrays.fill(f,0L)            //Initialize f to an array of 0's.
                                                     b-->0      //Iterate over the first b primes.

for(d=0L;f[b]<1;f[b]=d<1?c:0,d=0L,c++)
    d=0L                        d=0L                            //Initialize d to 0.
         f[b]<1                      c++                        //Increment c while the b'th prime is 0.
                f[b]=d<1?c:0                                    //If d = 0, the b'th prime = c, else continue.

for(long h:f)                                                   //Iterate over all found primes.

d=h>0&&c/h*h==c?1:d;
  h>0                                                           //Ignore non-found primes.
       c/h*h==c                                                 //Equivalent to c%h==0
               ?1:d                                             //If h is prime and c is divisible by h, d = 1. Otherwise d stays unchanged.

javax.xml.bind.JAXB.unmarshal(""+Arrays.asList(f),Long.class)   //Print solution to stderr
javax.xml.bind.JAXB.unmarshal(                   ,Long.class)   //Prints what's contained to stderr.
                                 Arrays.asList(f)               //Convert f to list.
                              ""+                               //Convert to string.

Orijinal çözümüm bir returnifade kullandı . StackOverflow'ta bu soruyu sorduktan sonra , regettman asıl harfleri kullanmadan çıktı / geri dönüş yolu sağlayacak kadar nazikti.

Her zamanki gibi önerilerinizi bekliyoruz :)


3
+1. Bunu anlamak için sizin ve rgettman'ın gerçekten zor olması gerekiyordu. Çok etkileyici. :)
TNT

5

Ruby, 74

->n,*o{o<<[2..n*n][0].find{|x|!o.find{|y|1.>x.^y.*x.div y}}until o[n-1]
o}

Açıklama:

*oboş bir çıktı dizisi başlatır. nMaddeleri olana kadar , şu anda içinde hiçbir öğeyi bölmeyen en küçük sayı olan> = 2 odeğerini bulduk , sonra ekleyin o. Bölünmeyi denemek için, yikes. Bütün iyi operatörlere izin verilmedi ve ben bile kullanamıyorum divmod. Görebildiğim en iyi şey kullanmaktı x.div y, ki x bölü y'ye yuvarlar ve aşağı yuvarlar sonra tekrar y ile çarpın. Eğer x'e eşitse, yuvarlama olmazdı, bu yüzden y x'e bölünür. 1.>x.^Xor sonucunun 0 olup olmadığını kontrol eden bir eşitlik testidir.. karıştırıp olamaz çünkü her operatörüdür önce .-ücretsiz operatör aramaları ve parantez içermeyen yöntem çağrıları.

Düzenleme: Ben bunu yayınladıktan sonra aralık kontrol özellikleri eklendi, sanırım. Uyum sağlamak için 79 karakter gerekir:

->n,*o{o<<[*2..-~n*n].find{|x|!o.find{|y|1.>x.^y.*x.div y}}until o[n-1]||n<1
o}

4

CJam, 38 37 30 bayt

{_~2#,2>\{(\{1$37c~},\p}*'<(~}

Burada dene

Bu olmayan herhangi negatif için tüm kuralları ve eserleri uymak gerektiğini düşünüyorum N (yani T sonsuzdur) . Gerçi çok verimsiz, bu yüzden büyük sayılar için denemeyin.

Bu bir bloktur - (isimsiz) bir fonksiyona en yakın şey - yığında bir tamsayı bekler, tüm asal sayıları yazdırır ve yığını girişi olmadan bırakır. Tüm geçersiz girişler için hata verir veya hiçbir şey yazdırmaz.

Kodun çoğu giriş doğrulama, ardından Eratosthenes elek. Yalnızca giriş kısıtlamasıyla ilgili 3 yerde çalışmam gerekiyordu:

  • )CJam’daki artış. Buna bir kez ihtiyacım vardı, ancak bunun yerine ~(bitsel tamamlayıcı) kullanabilirsiniz, çünkü sayıları yine de kareler.
  • %modulo. Bunun 37c~yerine kullanıyorum , ilk önce karakteri yaratan, %sonra değerlendiren ise bu. Bu, kodu çok daha yavaş yapar.
  • ;bir öğeyi yığından çıkarır ve atar. Sonunda bunu yapmam gerekiyor. Bunun yerine ben '<(~karakteri iten kullanıyorum <, onu azaltır ve eval's.

Girdi ayrıştırma kurallarına bakıldığında, zaten ayrıştırılmış bir tamsayı alma yetkisine sahip olmadığımızı düşündüm.
Runer112

@ Runer112 "bir tamsayı kabul eden bir fonksiyon" yazmamıza izin veriyor. "Bir tamsayı dizesini temsil eden bir işlev" değil.
Martin Ender

3

Bash + coreutils, 227 bayt

printf -vb br`dc<<<Di14B8209P`
printf -vc -- $[$1-0]
[ "${1#$c}" -o $c -lt 1 ]||{
for i in {2..104729}
{
for f in `jot $[i-1] $[i-1] 1`
{
[ 0 -lt `dc<<<"$i $f~p"` ]||$b
}
[ $f -lt 2 ]&&printf $i\ &&: $[c--]
[ $c -lt 1 ]&&$b
}
}

Bu oldukça zordu. Karşılaştığım bazı şeyler:

  • Döngülerin çoğu ( whileve until) kullanılamaz, çünkü bunlara en doneçok bir kabuk anahtar sözcüğüdür ve değişken bir genişlemenin sonucu olamaz ( evalkullanılmadığı sürece , ancak bu da bitmez). Yalnızca kullanılabilir döngüdür for/ insağlayan {/ }yerine do/ ' done. for (( ; ; ))ayrıca kullanılamaz.
  • = çıktı, bu yüzden değişken atamak için başka bir yola ihtiyacımız var. printf -vbunun için iyidir.
  • P (10000) 'ün 104729 olduğunu biliyoruz, bu nedenle potansiyel primerlerin dış halkası için 2'den 104729'a kadar döngü yapabilir ve yeterli prime sahip olduktan sonra kırılabiliriz
  • jotİç döngüdeki potansiyel faktörlerin listesini oluşturur. Potansiyel bir faktör potansiyel bir üssü bölerse, o zaman asal değildir ve erken ayrılırız
  • Neyse ki breakbir anahtar kelime değil bir kabuk yerleşiktir, bu nedenle bir genişlemenin sonucu olarak oluşturulabilir. dcbir baz 13 sayısını bytestream'e dönüştürür eak.
  • Potansiyel bir faktörün potansiyel bir üssü ayırıp ayırmadığını kontrol etmek için, normal /veya %kabuk aritmetik operatörlerini kullanamayız . Buna dış kaynaklı Böylece dcs ~yığınına bölüm ve kalan iter operatör.
  • -lt - daha az - tek kullanılabilir kabuk karşılaştırma operatörüdür.
  • echoçıktı için kullanılamaz. printfkaçındığımız sürece çalışır%

Giriş doğrulamasını doğru yapmak biraz acı verici. Bu geçersiz giriş durumunda hiçbir şey döndürmez.

Çıktı:

$ ./primenoprime.sh 10
2 3 5 7 11 13 17 19 23 29 $ 

3

Haskell, 90 bayt

\n->[fst c|c<-zip[p|p<-[2..],not$or[b>p-1&&b-1<p|b<-[u*v|u<-[2..p-1],v<-[2..p-1]]]][1..n]]

Bu bir tamsayı alır anonim bir işlevdir n giriş olarak .

Nasıl çalışır: [p|p<-[2..],not$or[b>p-1&&b-1<p|b<-[u*v|u<-[2..p-1],v<-[2..p-1]]]](ilk Haskell wiki'de bir numaralı asıl örnek, ancak elemişlevi değiştirilmiş olan ilk örnek ) sonsuz bir asal liste oluşturur. zipdan sayılarla bu 1kadar nbir listesini yapmak için (prime, seq. number)çiftler. Sıra çıkarın. tekrar, numara. Sonuç, uzunluk astarlarının listesidir n.


1

Rust, 64897 bayt

|n|println!{"{:?}",&[2,3,6-1,7,11,13,17,19,23,29,31,37,41,43,47,60-7,0x3b,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,0x97,0x9d,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,0xfb,0x101 ...}

(karakter sınırı nedeniyle kod yazıldı, burada tam çözüm )

Asal kısıtlama nedeniyle aşağıdaki pas özellikleri kullanılamıyor:

  • işlev çağrıları, ')' istedikleri gibi
  • Düzenli ciltleme, izin vermelerini gerektirdiğinden
  • Makro tanımları, makro kuralları gerektirir! (A, e, m)
  • maç ifadeleri, eşleşmeyi gerektirir (a, m) ve => (=)
  • değişkenlik, çünkü her zaman mut anahtar sözcüğü (m) ile birlikte verilir.
  • dönüş (e), ara (a, e), devam et (e)
  • başka (e)

Teknik olarak ne kullanabilirsiniz:

  • Eğer. Fakat başkaları olmadan, ifade bağlamında işe yaramazlar, bu yüzden sadece yan etkiler için iyidir.
  • makrolar. Baskı gibi standart makrolar! genellikle () tarafından izlenir, ancak bunun yerine {} veya [] kullanmak yasaldır. Bu olmadan, görev imkansız olurdu.
  • en dar anlamda kapanır. Onları arayamaz (zorunlu ()) ya da onları bağlayamazsınız (izin vermeniz gerekir), ancak özyinelemeli olmayan bir tane tanımlayabilirsiniz. Bu olmadan, görev açıkça imkansız hale gelirdi.
  • yapılar.
  • döngüler için. Bunlar ümit vericidir, çünkü aslında değişken bağlanmaya izin verirler ve yine de sözdizimi aralığıyla tanımlanabilen bir yineleyici kullanırlar. Yineleyici bir ifade bile olabilir.
  • Yerleşik operatörler, +,% ve / dışında. Kısa devre mantıksal operatörleri umut verici görünüyor.

Bu aletlerle Turing-complete hiçbir şey yapamadım. Üzgünüm. Geride kalan tek şey, 5'lerden arındırılmış ilk 10000 astarın tamamını içermekti. En azından mümkün olan en dar anlamda dilimleyebilir ve geçerli bir çözüme sahip olabilirsiniz.

Turing tarpit diving (veya Rust!) Uzmanlarının bana daha iyi bir şey yapıp yapamayacağımı söylemesini çok istiyorum!


1

GNU APL, 75 68 67 65 59 56 55 karakter

⎕IOolmalı 1.

∇z←p n
z←2,j←3
j←j--2
→2×⍳∨⌿1>z|j
z←z,j
→2×⍳n>⍴z
z←n↑z∇

Bu aylar sonra tekrar geldim ki fazladan bir yerim olduğunu fark ettim!


Bu APL kodunda mı yoksa UTF-8'de mi? APL kodlamasına dönüştürürseniz (ve geçerlidir) bayt cinsinden çok daha kısa olur.
NoOneIsHere

UTF-8. Evet, ama o düşük karakterli noktalarda, daha fazla asal olacak.
Zacharý

Kesin olarak, şu anda APL'de sayılan bayt, ancak kaynak üzerindeki kısıtlaması Unicode'dur. (Unicode olmayan bayt sayımına izin verilen zorlukların farkına vardım)
Zacharý

0

Pyth - 12 bayt

#'Nin asal olup olmadığını görmek için pyth'in asal çarpanlaştırma işlevini kullanır. Kullanımları !tPTmilyon soruna altında asal için cevabım bana önerilen hile.

<f!tPTr2^T6Q

Filtre sadece n'nin altındaki primerler için işe yaradığından ve ilk n'nin kullanılmadığından, pi (x) in tersini 10.000'e baktım ve 104.000'i aldım, bu yüzden 10⁶ altındaki primerleri kullanıp ilk n'i kullandım. Bu aslında çalışmaz, bu nedenle n'yi 1000 ile altı ^T6ile değiştirip ^T3kısıtlayarak test etmelisiniz . Stdin ve output'tan stdout'a giriş yapın.

<          Q     Slice first n
f     r2^T6      filter on range 2->10⁶
 !               Logical not (gives true if tail is empty)
  t              Tail (all but first, so gives empty if prime fact is len 1)
   PT            Prime factorization of filter var (len 1 if num is prime)

5
Kurallardan: "Yerleşik ana jeneratörlerin ve ilkellik test cihazlarının kullanımına izin verilmemektedir."
Runer112

@ Runer112 Evet ama bu bir asalet test cihazı değil, asal çarpanlara ayırma, kuralların sınırında. Muhtemelen buna izin verilip verilmediğini sormalıyım.
Maltysen

@Maltysen " Yerleşik primer jeneratörlerin ve ilkellik test cihazlarının (bu, prime faktörizasyon fonksiyonlarını içerir) kullanımına izin verilmez" - bana oldukça açık görünüyor.
Dijital Travma

4
@ DigitalTrauma, bu cevabın gönderilmesinden sonra "(asal çarpanlara ayırma işlevlerini içerir)" açıklamasını ekledi.
Martin Ender

MartinBüttner Doğru. Sanırım @ ProgramFOX'un takdirine bağlı.
Dijital Travma
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.