部分文字列から最小の素数を見つける


17

1946年、エルドスとコープランドは、特定の数通常の数あることを証明しまし

ユーザーは一連の数字を入力し、その文字列を10進数で含む最小の素数を見つけます。

例:

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

バイト単位の最短コードが優先されます。一部の言語(mathematica、sage、pari-gp ...)には、素数に関連する組み込み関数が付属していることを知っています。プログラムがそのような関数に依存していない場合は-50バイト。あなたの言語がすでに大きな利点を持っているなら、これをだまそうとしないでください、ボーナスを請求しないでください。

編集

以下のいくつかのコメントによると、「03」を含む最小の素数は3です。これは本当に違いがありますか?私が考えることができる唯一のことは、おそらく文字列よりも数字の方が扱いやすいということです。

「03」などの場合、優先出力は103になります。ただし、プログラムの基本的な部分とは考えていません。したがって、バイトカウントを低くする場合は、先行ゼロを無視してもかまいません。


5
これは、プロジェクトオイラータスクの良い基盤のようです
ジョンドヴォルザーク

「03」を含む最小の素数は03です。入力に先行ゼロが含まれる場合があり、出力には含まれない場合があることを明確にするルールを追加する必要があります。
レベルリバーセント14年

2
@steveverrillには、03のような番号はありません。3を意味する場合、「03」は含まれません。
ジョンドボラック14年

3
@JanDvorak 03は数値3の有効な表現です(2.9 ...無限に繰り返され、2 + 9/9に相当しますが、一部では有効な表現とみなされます)。この質問の表現。これはつまらないポイントですが、通常のルールの乱用を考えると、作成する価値があると思います。
レベルリバーセント14年

1
表現するより良い方法は、文字列に変換されたときに「03」を含む最小の数字を見つけることだと思います。
Thebluefish 14年

回答:


13

Golfscipt、 33 32バイト= -18スコア

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

説明:

  • 2{...}{)}/-で始まり2、何かが真である間、スタックのトップをインクリメントします
  • ;;x-によって収集された中間値{}{}/と入力を破棄し、テストされた最後の値をそこに入れます

  • :x,2>-として値を格納xし、からリストを生成2しますx-1

  • {x\%!},!!- x割り切れるものを保持し、次にブール値に強制する(空ではない)
  • x`3?)!- x-1見つからない場合)、インクリメント、ネゲートのテキスト形式で入力を検索します。
  • | -または

7

Haskellプログラム、97文字= 47スコア

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

Haskell関数、75文字= 25スコア

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

のタイプはpです(Integral a, Show a) => [Char] -> a。独自の整数型を指定する場合、それらの値の独自の表現で中置記号を使用して検索できます。標準Integerは、整数に予想される10進表記を使用しています。

それほど速くありません。出力の値(サイズではなく)の2次。

改変されていないバージョン:

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

例:

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文字。

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)との間にスペースを入れると、1文字節約できます{System.out.println(n)
ProgramFOX 14年

@ProgramFOXありがとう。
ワイルドカード14年

boolean p=trueようなものに置き換えることで、簡単に(約8)文字を保存できると思いますint p=1
フロリアンh 14年

すべてのintを一度に宣言すると、プログラムのサイズがさらに小さくなります。
オリビエグレゴワール14年

3

Mathematica 58

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

Macの相対タイミング(8 GBのメモリを搭載した2.6 GHz i7)。

「01」を含む最小の素数を見つけます。

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

{0.000217、101}


「012345」を含む最小の素数を見つけます。

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

{5.021915、10123457}


「0123456」を含む最小の素数を見つけます。

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

{87.056245、201234563}


StringFreeQ短くするために使用できます。
alephalpha

2

セージ、72

対話型プロンプトで実行します

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

Primes().unrank(i)与えi0番目の素数は2であることで、目の素数を。


2

R、56文字-50 = 6

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

入力を標準入力として取得します。kが素数になるまでkをインクリメントし(k mod 2からkが0であるインスタンスを合計することによりテストされ、したがって0が論理に変換されるのでFALSE)、入力として与えられた文字列を含みます(単純なgrep、ここではgreplでテストされます)論理的な結果が必要なので)。

使用法:

> 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

シェルワンライナー(coreutils):45文字

ここでは関数を定義していません... 1つの引数を取り$n、整数範囲をスキャンするワンライナー(実際にはコードを短くするためにもう少し)。55文字バージョン:

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

遅すぎることもありません。以下のためのn=0123456それを返す201234563の中で81.715s。2つの文字列プロセッサを備えた長いパイプラインの場合、これは驚くほど高速です。

2つの文字(53文字まで)と1つのパイプを削除すると、さらに高速に実行できます。

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

そして最後に、印刷をthe sedいものにしていますが、45文字に減らすための魔法があります。

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

n = 000-> 10007:10007(ユーザー0.017s)

n = 012345-> 10123457:10123457(ユーザー7.11s)

n = 0123456-> 201234563:201234563(ユーザー66.8s)


2

J-38文字-50 = -12ポイント

通常、Jでは、素数専用の非常に最適化されたビルトインを使用するので、実行が遅くなることについて謝罪するつもりはありません。

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

説明:

  • >:@]^:(...)^:_&2-2から開始して、(...)falseが返されるまで増分します。
  • (+.i.)@]-それより小さい整数ごとにカウンタのGCDを取得します。(GCD(X、0)= Xという規則を使用します。)
  • ]=*/@-これらすべての数の積を取り、カウンターとの同等性をテストします。カウンターが素数の場合、リストはすべて0のGCDを除き、すべて1でした。そうでない場合は、1より大きいGCDが少なくとも1つ存在するため、製品はカウンターより大きくなります。
  • >./@(E.":)-カウンターの文字列表現(":)に文字列(E.)が含まれているかどうかをテストします。>./は最大関数であり、それを使用しますE.、メイン文字列のサブ文字列が始まるところはどこでも1のブールベクトルを返すます。
  • *:-結果を論理NANDでまとめます。これは、両方の入力が真の場合、つまりカウンターが素数でサブストリングを含んでいた場合にのみ偽になります。

使用法:

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

後世のために、primeビルトイン(30文字長、ただしボーナスなし)を使用したバージョンは次のとおりです。

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

1 p:] GCDトリックではなく、カウンターの素数性をテストします。


2

Brachylog(v2)、Brachylogのエンコードで3バイト

ṗ≜s

オンラインでお試しください!

関数の送信。右側の引数から入力を取得し、左側の引数を変更して出力を提供します。(これは、通常のBrachylog規則の反対です。詳細については、このメタ投稿を参照してください。引数をより一般的な順序にスワップすると、3バイトかかります。)TIOリンクには、適切な呼び出し規則で関数を呼び出して出力するラッパーがあります結果。

説明

ṗ≜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}

悲しいことに、Brachylogはこの問題に非常に適切であるため、問題のルールに従って、ボーナスを獲得することさえできません(皮肉なことに、勝てないことを意味します)。

私がBrachylogが大好きな理由の1つは、プログラミングが人間とコンピューターの間のコミュニケーションであるため、「完璧な」言語では問題の仕様を英語に直接翻訳できることです。問題が述べられたアイデアとプログラムが書かれたアイデアは同じです。Brachylogは、驚くほど頻繁にこの理想を達成できます。ここでの質問は「与えられた部分文字列を含む最小の素数を見つける」ことであり、「最小、素数、部分文字列を含む」の概念を文字通り正しい順序でつなぎ、プログラムを動作させることができます。そのため、Brachylogは、問題を解決するためのアルゴリズムを明示的に指定する必要がある言語よりも、通信の性質について多くのことを述べています。他の人間と話すとき 問題を解決するための手順を説明することで問題を説明しようとしますが、それはまれです。では、なぜ私たちの言語は違うのでしょうか?


1

JavaScript 83バイト= 33スコア

ゴルフ:

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(少し):

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(Node.JS)-93バイト= 43ポイント

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

意味のある変数名を持つ抽出された形式:

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

0

Rust 0.9 136バイト= 86ポイント

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

コンパクトさにもかかわらず、非常に明確です。文字列検索に費やしたスペースが多すぎます。:(

ここでは、空白なしのバージョン(136文字)

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ポイント

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

オンラインでお試しください!

考慮して$_%%one ^$_いるのは2バイトだけ小さいなり.is-prime、ボーナスとしては価値があると思います。これは、最後のテストケースではタイムアウトします。

説明:

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

2バイト小さいですか?
ASCIIのみ

lol @「あなたの言語がすでに大きな利点を持っているなら、これをだまそうとしないでください」という質問の部分はボーナスを請求しないでください。
ASCIIのみ

@ ASCIIのみまあ、私は今でも、そう... GolfScriptで殴られています:$
ジョー・キング

0

Pythonの380の 79バイト- 50 = 30 29スコア

-1バイトの%s代わりに@ ASCII-onlyのクリエイティブな使用のおかげstr

テストケース「98765」は、テストにかかる時間のためにまだ確認されていませんが、数時間後にテストケース「98765」で確認済みですが、短絡評価を利用していくつかの素数性テストを回避する同様のアプローチで動作しますはるかに高速。また、これは可能〜2倍の速さ、我々は「2」が入力されていないことがわかっている場合は設定して、(私たちは素数のためにも、数字をチェック回避することができます)i=3最初にしてi+=2余分なバイトのコストで、ループ内で。

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

オンラインでお試しください!

while状態の説明((x in"%s"%i)*all(i%j for j in range(2,i))-1):

(x in"%s"%i)True/ 1現在のカウンターに必要な数字のシーケンスが含まれている場合。False/0それ以外。

all(i%j for j in range(2,i))True/ 12(包括的)からそれ自体(排他的)までの整数で除算したときに、現在のカウンターに常に剰余がある場合、つまり素数。False/0それ以外。

*一緒に乗算二つの条件、およびとして作用andオペレータ-生成物であるTrue/ 1あれば、両方の条件がある場合にのみTrue/1

-1作用not演算子:False/ 0- 1つの結果-1、真であると考えられるのに対して、True/ 11の結果-0偽であると考えられます。したがって、番号が目的の番号のシーケンスを含まないか、素数でない間、ループは継続します。

*with andを置き換えて、すべてを囲む括弧を追加します。ただし、-1より高速で同等のソリューション(わずかに長い)が必要です。

@ASCIIのみで指定されたPython 2 の76バイト-50 = 26スコアソリューション(``代わりにstr()

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

オンラインでお試しください!



@ ASCIIのみの私は、ほとんどのpython 3を使用するのpython 2くらいとを使用していないので、けれどもでどのような私のゴルフ、それは...短いことまで、その時間のpythonのほとんど2つの端を思わさん。
ニールA.

あなたが持っている最初のもので、タイプミスをしたreturn I
ASCIIのみの


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.