「素数文字」を使用せずに素数を見つける


21

受け入れることを選択した場合のタスクは、整数Nを入力として受け入れるプログラム/関数を作成することです。プログラム/関数は、最初のN個の素数のリストを出力/返す必要があります。ただし、ここで問題があります。コードでプライム文字を使用することは許可されていません。素数文字とは、Unicodeコードポイントが素数である文字です。印刷可能なASCIIの範囲では、次のとおりです。

%)+/5;=CGIOSYaegkmq

ただし、コードで非ASCII文字が使用されている場合、この規則は非ASCII文字にも適用されます。

  • 有効な入力は、整数N 0 <N <= Tあなたが選ぶことができ、Tを、それは以上10000に等しくなるように持っているTは有限である必要はありません。
  • 無効な入力(非整数、範囲外の整数)の場合は、例外をスローするか、何も出力しないかnullを返します。
  • 入力として先頭/末尾の空白を含む整数は無効と見なされます。
  • +入力として符号記号を持つ整数は無効と見なされます。
  • 入力として先行ゼロを含む整数は有効と見なされます。
  • 言語で入力として既に解析された整数を渡すことができる場合、intは既に解析されているため、上記の解析ルール(範囲1を除く)は適用されません。
  • 入力は常にbase-10です。
  • 組み込みの素数ジェネレーターおよび素数テスター(素因数分解関数を含む)の使用は許可されていません。
  • ソースの制限はUnicode文字に課されますが、スコアのバイトカウントは、必要に応じて別のエンコードにすることができます。
  • 出力には単一の末尾改行を含めることができますが、これは必須ではありません。
  • 素数リストを文字列として出力/返す場合、すべての素数は1つまたは複数の非数字文字で区切る必要があります。使用する区切り文字を選択できます。
  • これは挑戦であり、バイト単位の最短コードが勝ちます。

コードを確認するためのスタックスニペット

以下のスタックスニペットを使用して、コードにプライム文字が含まれていないことを確認できます。

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
それはそれはかなり残酷です;...禁止されることを起こる
ɐɔıʇǝɥʇuʎs

素数テスターが許可されていない場合、素因数分解関数についてはどうでしょう。
マルティセン

@Maltysen素因数分解関数から、数値が素数であるかどうかを非常にすばやく確認できるので、それは許可されないのではないかと思います。それを明確にします。
ProgramFOX

これらの無効な入力の一部を破棄することが義務付けられていますか?たとえば、言語のstring-> int関数で先行を許可+している場合、これらを手動でスローする必要があるのは残念なようです。
Runer112

11
私はこれに興奮し、解決策に着手し、閉じた括弧が禁止されていることに気付きました。さて、私は外出しています。
アレックスA.

回答:


10

CJam、19 18 30 34 33 19 17 21 20バイト

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

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

これはおそらく、私がこれまでに実装した中で最も恐ろしく非効率的なアルゴリズムの1つです。しかし、私はサイズのためにそれをしました!

私の答えは、CJamの匿名関数のように機能するコードブロックで構成されています。スタックの直前に整数を付けて実行すると、結果のリストがスタックにダンプされます。入力の上限を無限として扱うので、その上限をチェックする必要はありません。

私のアルゴリズムは、3のinputべき乗を開始することから始まりinputます。入力が有効な場合、-th素数よりも大きい数が保証されます。次に、2からこの数値から1を引いた整数のリストが生成されます。これは、必要なすべての素数を含むのに十分な大きさのスワスです。合成数を取り除くために... ため息 ...すべてのペアワイズ製品のリストを作成します。これは、4から目的に十分な大きさの、非常に大きな値までのすべての合成数を生成します。次に、この複合リストにある元のリストからすべての要素を削除し、それを最初のinput要素にトリミングし、要素を改行文字で結合するだけです。

このアルゴリズム、あらゆる入力に対して機能するはずです。ただし、時間とスペースの要件は入力に対して指数関数的であるため、インタープリター/コンピューターに十分なメモリまたは時間があるかどうかはまったく別の問題です。そのため、入力がオンラインインタープリターで約5、オフラインインタープリターで約8を超える場合、その質問に対する答えはおそらく「いいえ」です。


3
へえ、17であなたの答えに素数のバイトがあります。
コーリーオグバーン

なぜあなたは必要S*ですか?
jimmy23013

@ user23013 1未満の無効な入力はまだアルゴリズムを通過し、空のリストを生成します。しかし、それはそれらの正当な出力ではないため、リスト要素をスペースで結合して、これらの無効な入力に対して空の出力を生成します。
Runer112

1
私はこれに気づきました、S主人公ではありませんか?
ザカリー

素直なキャラクターです。私これを言うのに2年以上遅れていることを知っていますが、この答えは無効で
ザカリー

8

Java。474バイト

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}

関数の引数を介して入力を受け取り、スローされた例外を介して出力します。

インデント:

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
}

エスケープされた文字が削除されました:

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

説明:

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.

私の元の解決策はreturn声明を使用していました。StackOverflowでこの質問をした後、regettmanは素数文字を使用せずに出力/戻る方法を提供するのに十分親切でした。

いつものように、提案は大歓迎です:)


3
+1。それはあなたとrgettmanが理解するのが本当に大変でした。非常に印象的。:)
TNT

5

ルビー、74

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

説明:

*o空の出力配列を初期化します。nアイテムが見つかるまで、現在のアイテムを分割しない最小数> = 2を見つけてo、それをに追加しoます。除算をテストするには、いいですね。すべての良い演算子は許可されていませんdivmod。私はを使用することさえできません。私が見ることができたのはx.div y、xをyで割って切り捨ててから、再びyを掛けることでした。xと等しい場合、丸めは行われなかったため、yはxを除算します。1.>x.^xorの結果が0であるかどうかをチェックする等値テストです。before .すべての演算子は、.-free演算子呼び出しと括弧なしメソッド呼び出しを混在させることができないためです。

編集:これを投稿した後に範囲チェックの仕様が追加されたと思います。準拠するには79文字が必要です。

->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バイト

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

ここで試してみてください

これはすべてのルールに準拠し、負でないN(つまり、Tは無限)に対して機能するはずだと思います。しかし、それは恐ろしく非効率的ですので、大量に試さないでください。

これはブロックです-(名前のない)関数に最も近いもの-スタック上の整数を期待し、すべての素数を出力し、入力なしでスタックを残します。すべての無効な入力に対して、エラーをスローするか、何も出力しません。

ほとんどのコードは入力検証であり、その後にエラトステネスのふるいが続きます。私は3つの場所で入力制限を回避する必要がありました。

  • )CJamの増分です。一度必要になりましたが、~とにかく数字を二乗していたので、(ビット単位の補数)に置き換えることができました。
  • %モジュロです。私は37c~代わりに、最初にキャラクター%を作成し、次にevalを作成します。これにより、コードが非常に遅くなります。
  • ;スタックから要素をポップして破棄します。最後にこれを行う必要があります。代わりに、私はこれを使用'<(~してキャラクターをプッシュし、<それをデクリメントし、それを評価します

すべての入力解析規則を考えると、すでに解析された整数をそのまま取り込むことは許されていないと思いました。
Runer112

@ Runer112「整数を受け入れる関数」を書くことができます。「整数の文字列表現を受け入れる関数」ではありません。
マーティンエンダー

3

Bash + coreutils、227バイト

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

これはかなりトリッキーでした。私が遭遇したいくつかのこと:

  • ほとんどのループ(whileおよびuntil)は、doneどちらがシェルキーワードであり、変数展開の結果となることができないため、使用できません(eval使用しない限り、それも外にあります)。唯一使用可能なループであるfor/ in可能にする{/ }の代わりにdo/ donefor (( ; ; ))また、使用できません。
  • =が出ているので、変数を割り当てる別の方法が必要です。 printf -vこれに適しています。
  • p(10000)は104729であることがわかっているので、潜在的な素数の外側のループについては、単純に2から104729にループし、十分な素数ができたら中断できます。
  • jot内側のループに潜在的な要因のリストを生成します。潜在的な因子が潜在的な素数を分割する場合、それは素数ではなく、早期に発生します
  • 幸いなことbreakに、シェルビルトインであり、キーワードではないため、展開の結果として生成される可能性があります。 dc基数13の数値をバイトストリームに変換しますeakます。
  • 潜在的な因子が潜在的な素数を分割するかどうかを確認するために、通常の算術演算子/または%シェル算術演算子を使用することはできません。そのため、これはdcs ~演算子に外部委託され、商と剰余をスタックにプッシュします。
  • -lt -より小さい-は、使用可能な唯一のシェル比較演算子です。
  • echo出力には使用できません。 printf回避する限り動作します%

入力検証を正しく行うのは少し面倒です。無効な入力の場合、これは何も返しません。

出力:

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

3

Haskell、90バイト

\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]]

これは、n入力として整数を取る匿名関数です。

仕組み:[p|p<-[2..],not$or[b>p-1&&b-1<p|b<-[u*v|u<-[2..p-1],v<-[2..p-1]]]]Haskell wikiの素数1ライナーの最初の例ですが、elem関数が置き換えられています)は素数の無限リストを作成します。zipから1までの数字n(prime, seq. number)ペアのリストを作成します。シーケンスを削除します。再び。結果は、長さの素数のリストですn


1

さび、64897バイト

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

(文字の制限によりコードが欠落しています。完全なソリューションはこちら

主な制限により、次の錆機能は使用できなくなります。

  • ')'が必要なため、関数呼び出し
  • let(e)を必要とするため、通常のバインディング
  • マクロ定義、マクロルールが必要です!(a、e、m)
  • 一致ステートメント。一致(a、m)および=>(=)が必要です。
  • mutキーワード(m)で常に導入されるため、可変性。
  • return(e)、break(a、e)、continue(e)
  • その他(e)

技術的に使用できるもの:

  • もし。しかし、他の方法がなければ、それらは式のコンテキストでは役に立たないので、副作用にのみ適しています。
  • マクロ。印刷のような標準マクロ!通常は()が後に続きますが、実際には{}または[]を代わりに使用することは正当です。これがなければ、タスクは不可能です。
  • 最も狭い意味での閉鎖。それらを呼び出す(()が必要)またはバインドする(letが必要)ことはできませんが、1つの非再帰的なものを定義できます。これがなければ、タスクは明らかに不可能になります。
  • 構造体。
  • forループ。これらは実際に変数バインディングを許可し、イテレータを取ります。これは範囲構文で定義できます。イテレータは式にすることもできます。
  • +、%、/を除く組み込み演算子。短絡論理演算子は有望なようです。

これらのツールでチューリング完全なものを作ることができませんでした。ごめんなさい。残っていたのは、5個を削除した最初の10000個の素数をすべて含めることでした。少なくともあなたはそれをスライスし、可能な限り狭い意味で有効なソリューションを持つことができます。

チューリングターピットダイビング(またはRust!)の専門家に、もっと良いことをしたかどうかを教えてほしい。


1

GNU APL、75 68 67 65 59 56 55文字

⎕IOでなければなりません1

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

今月、私は余分なスペースがあることに気付いて戻ってきました!


これはAPLエンコードまたはUTF-8ですか?これをAPLエンコードに変換すると(有効な場合)、バイト単位ではるかに短くなります。
-NoOneIsHere

UTF-8。ええ、しかし、それらの低いキャラクターのポイントでは、もっと素数があるでしょう。
ザカリー

正確には、APLでバイトカウントされるようになりましたが、ソースの制限はUnicodeです。(チャレンジで非Unicodeバイトカウントが許可されることに気付きました)
ザカリー

0

Pyth -12バイト

pythの素因数分解関数を使用して、#が素数かどうかを確認します。万素!tPT問題の下の素数に対する私の答えで提案されたトリックを使用します。

<f!tPTr2^T6Q

フィルターは最初のnではなくnの下の素数に対してのみ機能するため、10,000のpi(x)の逆数を検索して104,000を得たので、10⁶の下の素数を使用して最初のnを取得します。これは実際には実行されないので、nを置き換え^T6てテストし^T3、nを1000未満に制限する必要があります。stdinからの入力とstdoutへの出力。

<          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
ルールから:「組み込みの素数ジェネレーターと素数テスターの使用は許可されていません。」
Runer112

@ Runer112ええ、しかしこれは素数テスターではなく、素因数分解であり、ルールの境界にあります。私はおそらくこれが許可されているかどうか尋ねるべきです。
マルティセン

@Maltysen 「組み込みの素数ジェネレーターおよび素数テスター(これには素因数分解関数が含まれます)の使用は許可されていません」 -私には明らかです。
デジタル外傷

4
@DigitalTraumaの説明「(これには素因数分解関数を含む)」がこの回答の投稿後に追加されました。
マーティンエンダー

MartinBüttner本当。@ProgramFOXの裁量次第だと思います。
デジタル外傷
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.