Bir alt dizeden en küçük prime'ı bulun


17

1946 Erdös ve Copeland kanıtladı belirli sayıda a, normal sayıda , eşit olarak dağıtıldığı, ondalık genişleme basamak yani.

Kullanıcılar bir basamak dizisi girecek ve bu dizeyi içeren en küçük üssü taban 10'da bulacaksınız.

Misal:

input   -> output
"10"    -> 101
"03"    -> 103
"222"   -> 2221
"98765" -> 987659

Bayt cinsinden en kısa kod kazanır. Bazı dillerin (mathematica, adaçayı, pari-gp ...) primerlerle ilgili yerleşik işlevlerle geldiğini biliyorum. Programınız bu tür işlevlere bağlı değilse -50 bayt . Bunu aldatmaya çalışmayın lütfen, eğer diliniz zaten büyük bir avantaja sahipse bonusu talep etmeyin.

Düzenle

Aşağıdaki birkaç yoruma göre, "03" içeren en küçük asal 3'tür. Bu gerçekten bir fark yaratır mı? Aklıma gelen tek şey belki sayıların dizelerden daha kolay işlenebilmesidir.

"03" gibi durumlarda, tercih edilen çıktı 103 olacaktır. Ancak, bunu programınızın temel parçası olarak görmüyorum, bu nedenle size daha düşük bir bayt sayımı verirse, önde gelen sıfırları yok sayabilirsiniz.


5
Bu bir Proje Euler görevi için güzel bir temel gibi görünüyor
John Dvorak

"03" içeren en küçük asal 03'tür. Belki girdinin baştaki sıfırlar içerebileceğini belirten bir kural eklemelisiniz, ancak çıktı olmayabilir.
Level River St

2
@steveverrill 03 diye bir sayı yoktur. 3'ü kastediyorsanız, "03" içermez.
John Dvorak

3
@ JanDvorak 03 3 rakamının geçerli bir temsilidir. bu sorunun temsili. Bu bilgelikli bir nokta, ama kuralların olağan kötüye kullanımı göz önüne alındığında, bence bir şey yapmaya değer.
Level River St

1
Ben ifade etmek için daha iyi bir yol, bir dizeye dönüştürüldüğünde, "03" içerecek en küçük sayıyı bulmak olacağını düşünüyorum.
Thebluefish

Yanıtlar:


13

Golfscipt, 33 32 bayt = -18 puan

2{:x,2>{x\%!},!!x`3$?)!|}{)}/;;x

Açıklama:

  • 2{...}{)}/- bir 2şey doğru olsa da, yığının üst kısmını artır
  • ;;x- tarafından toplanan ara değerleri {}{}/ve girişi atın , ardından test edilen son değeri buraya koyun

  • :x,2>- değeri olarak depolayın x, ardından ile arasında bir liste oluşturun 2.x-1

  • {x\%!},!!- xbölünebilir olanları tut , sonra boole'ye zorla (boş değil)
  • x`3?)!- girdiyi metin formunda x( -1bulunmazsa), artışı, olumsuzlamayı arayın .
  • | - veya

7

Haskell programı, 97 karakter = 47 puan

main=getLine>>= \i->print$head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

Haskell işlevi, 75 karakter = 25 puan

p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

tipi pDİR (Integral a, Show a) => [Char] -> a. Kendi integral türünüzü sağlıyorsanız, bu değerleri temsil ettiğiniz şekilde infix'e göre arama yapabilirsiniz. Standart Integer, tamsayılar için beklenen ondalık gösterimi kullanır.

Çok hızlı değil. Çıktının değerinde (boyut değil) ikinci dereceden.

ungolfed sürümü:

import Data.List
leastPrime infix = head $ filter prime' [2..]
  where prime' x  = all (\n-> x`mod`n /= 0) [2..x-1]
                 && i `isInfixOf` show x
main = print . leastPrime =<< getLine

misal:

Prelude> let p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]
Prelude> p "0"
101
Prelude> p "00"
1009
Prelude> p "000" -- long pause
10007

3

Java - 175 karakter.

class s{public static void main(String[]a){int i,n=2,p;for(;;){p=1;for(i=3;i<n;i++)if(n%i==0)p=0;if((n==2||p>0)&&(""+n).indexOf(a[0])>=0) {System.out.println(n);break;}n++;}}}

indexOf(a[0])>=0)Ve arasındaki boşluğu bırakarak 1 karakter kaydedebilirsiniz {System.out.println(n).
ProgramFOX

@ProgramFOX Teşekkürler.
joker

Ben senin boolean p=truegibi bir şey ile değiştirerek (yaklaşık 8) karakterleri kolayca kaydedebilirsiniz düşünüyorum int p=1.
florian h

tüm yazılarınızı aynı anda bildirmeniz program boyutunuzu daha da küçültecaktır.
Olivier Grégoire

3

Mathematica 58

(n=1;While[StringCases[ToString[p=Prime@n],#]=={},n++];p)&

Mac bilgisayarımdaki Göreli Zamanlamalar (8 GB belleğe sahip 2.6 GHz i7).

"01" içeren en küçük prime'ı bulun.

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["01"]]

{0.000217, 101}


"012345" içeren en küçük prime'ı bulun.

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["012345"]]

{5.021915, 10123457}


"0123456" içeren en küçük üssü bulun.

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["0123456"]]

{87.056245, 201234563}


Kısaltmak için kullanabilirsiniz StringFreeQ.
alephalpha

2

Adaçayı , 72

Etkileşimli bilgi isteminde çalışır

a=raw_input()
i=0
p=2
while a not in str(p):i+=1;p=Primes().unrank(i)
p

Primes().unrank(i)i0'ın asal sayısını verir, 0'ın asal sayısı 2'dir.


2

R, 56 karakter -50 = 6

k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k

Girişi stdin olarak alın. K bir asal olana kadar k artışları (k mod 2 ila k'nin sıfır olduğu durumların toplanmasıyla test edilir, bu nedenle 0 mantıklı hale geldiğinden FALSE FALSE olur) ve girdi olarak verilen dizeyi içerir (basit bir grep ile test edilir, burada grepl çünkü sonuç olarak bir mantık istiyoruz).

Kullanımı:

> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "03"
2: 
Read 1 item
[1] 103
> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "003"
2: 
Read 1 item
[1] 2003

2

kabuk oneliner (coreutils): 45chars

Burada bir fonksiyon tanımlamamak ... sadece bir argümanı alan $nve tamsayı aralığını tarayan (aslında kodu kısaltmak için biraz daha fazla) bir oneliner . 55 karakterlik versiyon:

seq 5e9|grep $n|factor|awk '{if(NF==2)print $2}'|head -n1

Çok yavaş bile değil. İçin n=0123456döndürür 201234563içinde 81.715s. İki telli işlemcili uzun bir boru hattı için bu oldukça hızlı.

İki karakteri (53'e kadar) ve bir karakteri kaldırarak, daha da hızlı çalışmasını sağlayabiliriz:

seq 5e9|grep $n|factor|awk '{if(NF==2){print $2;exit}}'

Ve son olarak, çıktı çirkin olmasına rağmen , bazı karakterleri 45 karakteresed düşürmek için :

seq 5e9|grep $n|factor|sed -n '/: \w*$/{p;q}'

n = 000 -> 10007: 10007 (kullanıcı 0.017s)

n = 012345 -> 10123457: 10123457 (kullanıcı 7.11s)

n = 0123456 -> 201234563: 201234563 (kullanıcı 66.8s)


2

J - 38 karakter -50 = -12 puan

Normalde J'de, asallara adanmış çok optimize edilmiş yerleşikleri kullanacaksınız, bu yüzden yürütmedeki herhangi bir yavaşlık için özür dilemeyeceğim.

>:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2

Açıklaması:

  • >:@]^:(...)^:_&2- 2 ile başlayan, (...)false döndürene kadar artırın.
  • (+.i.)@]- Sayacın GCD'sini, ondan daha küçük her tamsayı ile alın. (GCD (X, 0) = X sözleşmesini kullanıyoruz.)
  • ]=*/@- Tüm bu sayıların çarpımını alın ve sayaç ile eşitliği test edin. Sayaç asalsa, liste 0'lı GCD hariç 1'di; aksi takdirde 1'den büyük en az bir GCD olacaktır, bu nedenle ürün sayaçtan daha büyük olacaktır.
  • >./@(E.":)- counter ( ":) öğesinin dize gösteriminin E.herhangi bir noktada dize ( ) içerip içermediğini test edin . >./max işlevidir ve bunu kullanırız çünkü E.alt dizenin ana dizede başladığı yerde 1 olan bir boole vektörü döndürür.
  • *:- Sonuçları mantıklı NAND birlikte. Bu sadece her iki giriş de doğruysa yanlış olacaktır, yani sayaç her ikisi de asal ve alt dizeyi içeriyorsa.

Kullanımı:

   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '03'
103
   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '713'
2713

Posterity için, burada prime builtin kullanan sürüm (30 karakter uzunluğunda, ancak bonus yok):

>:@]^:(>./@(E.":)*:1 p:])^:_&2

1 p:] sayacı GCD hilesi yerine önceliklilik için test eder.


2

Brachylog (v2), Brachylog'un kodlamasında 3 bayt

ṗ≜s

Çevrimiçi deneyin!

Fonksiyon sunumu, sağ taraftaki argümandan girdi alma, sol taraftaki argümanı değiştirerek çıktı verme. (Bu, normal Brachylog kuralının tersidir; daha fazla tartışma için bu meta gönderiye bakın . Bağımsız değişkenleri daha normal sıraya dönüştürmek üç bayta mal olur.) TIO bağlantısı, işlevi uygun çağrı kuralına ve baskılara çağıran bir sargıya sahiptir. sonuç.

açıklama

ṗ≜s
 ≜   Find the integer closest to zero
ṗ      which is prime {implicit: and output it via the left argument}
  s    and which is a substring of the {right argument}

Ne yazık ki, Brachylog bu problem için o kadar uygundur ki problemdeki kurallara göre, bonusa gitmeye bile çalışamam (ki ironik bir şekilde kazanamayacağı anlamına gelir).

Brachylog'u bu kadar çok sevmemin nedenlerinden biri, programlamanın insan ve bilgisayar arasındaki bir iletişim olması ve bu nedenle "mükemmel" bir dilin, sorun tanımını doğrudan İngilizceye çevirmenize izin vermesidir; sorunun belirtildiği ve programın yazıldığı fikirler aynı olurdu. Brachylog bu ideale şaşırtıcı bir şekilde sık sık vurabilir; burada soru "verilen bir alt dize içeren en küçük asal bulmak" ve "küçük, asal, alt dize içeren alt kavramları" kavramlarını doğru sırada sıralayabilir ve bir çalışma programı olabilir. Bu nedenle, Brachylog, iletişimin doğası hakkında, sorunu çözmek için açıkça bir algoritma belirtmeniz gereken bir dilden çok daha fazlasını söylüyor; bazen diğer insanlarla konuşurken, bir sorunu çözmek için atacağınız adımları açıklayarak açıklamaya çalışırız, ancak bu nadirdir. Öyleyse neden dillerimiz farklı olsun ki?


1

JavaScript 83 bayt = 33 puan

golfed:

for(s=prompt(n=x=0);!n;x++)for(n=(''+x).match(s)?2:0;n&&n<x;n=x%n?n+1:0);alert(x-1)

Ungolfed (biraz):

s=prompt() // get the input
n = 0
for(x=0;!n;x++) // stop when n is non-zero
    if ((''+x).match(s)) { // if x matches the pattern, check if x is prime
        for(n=2;n&&n<x;)
            n = (x%n == 0) ? 0 : n+1; // if x%n is zero, x is not prime so set n=0
        // if n is non-zero here, x is prime and matches the pattern
    }
alert(x-1)

0

Javascript (Düğüm.JS) - 93 bayt = 43 puan

l:for(i=x=process.argv[2];j=i;i++){while(--j>2)if(!(i%j*(""+i).match(x)))continue l
throw i}

Mantıklı değişken isimleri ile çıkarılan formda:

outerLoop:for (currentTry=inputNumber=process.argv[2]; primeIterator=currentTry; currentTry++ ) {
    while (--primeIterator > 2) 
        if(!(currentTry % primeIterator * (""+currentTry).match(inputNumber)))
            continue outerLoop;
    throw i
}

0

Pas 0.9 136 bayt = 86 puan

fn main(){
   let mut n:u32=2;
   while n.to_str().find_str(std::os::args()[1])==None ||
         range(2,n).find(|&x|n%x==0)!=None {
      n=n+1;
   }
   print!("{}",n);
}

Kompakt olmasına rağmen çok açık. Dize bulmaya çok fazla yer harcanmış. :(

Burada boşluk olmayan sürüm (136 karakter)

fn main(){let mut n:u32=2;while n.to_str().find_str(std::os::args()[1])==None||range(2,n).find(|&x|n%x==0)!=None{n=n+1;}print!("{}",n);}



0

Perl 6 , 36-50 = -14 puan

{$^a;first {/$a/&&$_%%one ^$_},2..*}

Çevrimiçi deneyin!

Düşünüldüğünde $_%%one ^$_sadece 2 byte olduğu küçük daha büyük.is-prime , ben ikramiye için en değerinde onu düşünüyorum. Bu son test durumu için zaman aşımına uğradı.

Açıklama:

{                                  }  # Anonymous code block
 $^a;                                 # Assign input to $a
     first                    ,2..*   # Find the first number
           {                 }        # Which
            /$a/                        # Contains the input
                &&                      # And
                  $_%%one ^$_           # Is prime

2 bayt daha küçük?
Sadece ASCII

lol @ "Dile zaten büyük bir avantajı varsa, bu konuda hile yapmaya çalışmayın lütfen bonus diyor iddia" bölümünde.
Sadece ASCII

@ Sadece ASCII sadece GolfScript tarafından dövülüyorum, bu yüzden ...:$
Jo King

0

Python 3 , 80 79 bayt - 50 = 30 29 puan

@ ASCII'nin yalnızca %syerine yaratıcı kullanımı sayesinde -1 baytstr

Test durumu "98765" henüz test edilmesinin ne kadar sürdüğü nedeniyle henüz doğrulanmadı Birkaç saat sonra test durumu "98765" için onaylandı, ancak bazı öncelik testlerinden kaçınmak için kısa devre değerlendirmesini kullanan benzer bir yaklaşımla çalışıyor Çok daha hızlı. Alternatif olarak, "2" nin bir girdi olmadığını bilersek ~ 2 kat daha hızlı olabilir ( i=3başlangıçta ve i+=2döngüde ekstra bir bayt maliyeti olmadan ayarlayarak bir giriş olmadığını (ilkeliğin çift sayısını kontrol etmekten kaçınabiliriz) .

def f(x):
 i=2
 while(x in"%s"%i)*all(i%j for j in range(2,i))-1:i+=1
 return i

Çevrimiçi deneyin!

Durumun açıklaması while((x in"%s"%i)*all(i%j for j in range(2,i))-1 ):

(x in"%s"%i): True/ 1geçerli sayaç içinde istenen sayı dizisini içeriyorsa; False/0 yoksa.

all(i%j for j in range(2,i)): True/ 1geçerli sayacın 2 (dahil) ile kendi (hariç) arasında herhangi bir tamsayıya bölünmesiyle her zaman bir kalıntısı varsa, yani asal; False/0 yoksa.

*Çarpar birlikte iki koşulları ve bir şekilde hareket eden andoperatör - ürün True/ 1ve her iki durum da, yalnızca eğer True/1 .

-1Bir olarak hareket notoperatör: False/ 0- 1 sonuçlar -1, doğru olarak kabul edilir, oysa True/ 11 sonuçları -0 yanlış olarak kabul edilir. Böylece, sayı ya istenen sayı dizisini içermiyor ya da asal değilken döngü devam eder.

Değiştir *ile andve her şey parantez içine ekleyin ama-1 çok daha hızlı, eşdeğer çözeltisi (yani biraz daha uzun olan).

Bir 76 bayt - 50 = 26 puan çözeltisi Python 2 (@ ASCII sadece verilen kullanmaktadır ``yerine str(),

def f(x):
 i=2
 while(x in`i`)*all(i%j for j in range(2,i))-1:i+=1
 return i

Çevrimiçi deneyin!



@ ASCII sadece ben, çoğunlukla piton 3 kullanmak piton 2 kadar ve kullanmadıysanız böylece gerçi ne golf o ... kısa olmak kadar o zaman piton çoğu 2 uçlarını görünüyor en.
Neil A.

Bir yazım hatası yaptın, ilkindereturn I
ASCII sadece


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.