Optimus以外の素数


36

チャレンジ

入力整数を指定すると、nの10進展開の1桁を変更することで生成できるn > 0素数(それ自体が素数nである場合以外n)を出力します(桁数は変更しません)。

たとえば、n = 2。小数展開で一桁を変更することにより2、我々は、三つの追加素数を思い付くことができます3, 5, 7ので、a(n) = 3

別の例として、n = 13。1桁を変更することにより、あなたは素数を得ることができます11, 17, 19, 23, 43, 53, 73, 83ので、a(13) = 8

最後の例として、n = 20。1桁を変更することにより、あなたは素数を得ることができます23, 29ので、a(20) = 2

シーケンス

始めるための最初の20の用語を以下に示します。これはOEIS A048853です。

4, 3, 3, 4, 3, 4, 3, 4, 4, 4, 7, 4, 8, 4, 4, 4, 7, 4, 7, 2

ルール

  • 入力と出力は、言語のネイティブ整数型に適合すると仮定できます。
  • 入力と出力は、任意の便利な形式で指定できます
  • 先行ゼロを無視します(たとえば、03この定式化では素数ではありません)。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 可能であれば、他の人があなたのコードを試すことができるように、オンラインテスト環境へのリンクを含めてください!
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

4
私はn、出力が最も小さいものを考えようとしています0。私はそれだと思いますn = 200。私はまた、彼らは房に来ると思う:200,202,204,206,208320,322,...,328510,...,518620,...628840,...,848、など
エンジニアトースト

「入力と出力は、あなたの言語のネイティブ整数型に適合すると仮定することができます」とは、文字列として入力を取ることを許可されていないということですか?
デッドポッサム

1
@DeadPossumいいえ、許可されています。たとえば、32ビット整数のみを使用している場合は、入力として2 ^ 100を心配する必要はありません。
AdmBorkBork

私が船外に行くかどうかを教えてください...私は今3つの異なる提出があります
パトリックロバーツ

2
@EngineerToast最初のサンプルプライム(294001)を見つけた後、私はついにそれをOEISで調べることを考えました:A192545およびA158124。また、関連する:A143641
Ørjanヨハンセン

回答:


10

05AB1E17 16 14 11バイト

ā°`<Ÿʒ.L}pO

説明:

ā             Push inclusive range from 1 to the length of the input
 °            Raise 10 to the power of each element
  `           Push each element to the stack
   <          Decrement the topmost element
    Ÿ         Inclusive range
              For 13, this creates an array like [10 11 12 13 14 .. 98 99]
     ʒ.L}     Only keep elements with a levenshtein distance to the input of
              exactly one
         p    Check each element for primality
          O   Sum

オンラインでお試しください!または100まで


1
.L?マジ?.L?!?!
エリックアウトゴルファー

@EriktheOutgolfer L
Okx

つまり、レヴェンシュタイン距離のためのビルトインがあります!
エリックアウトゴルファー

@EriktheOutgolfer¯\ _(ツ)_ /
¯– Okx

私はそれがしばらくされていることを知っていますが、あなたは<バイトを保存するために削除することができます。フィルターが100/ 1000/ 10000/ etc。を削除しなくても、とにかく素数になることはないため、出力には影響しません。
ケビンクルーイッセン

5

パイソン2146の136 127 121 118バイト

提案してくれた@ Mr.Xcoderに感謝

lambda I:sum(all(i%v for v in range(2,i))*sum(z!=x for z,x in zip(I,`i`))==1for i in range(1+10**~-len(I),10**len(I)))

説明:

入力長に等しい長さの数値を生成し、最初にスキップします(1,10,100,1000、...)

for i in range(1+10**~-len(I),10**len(I))

生成された数値が入力と1桁だけ異なることを確認します

sum(z!=x for z,x in zip(I,`i`))==1

プライムをチェック

all(i%v for v in range(2,i))

カウント

sum(...)    

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


これをラムダにしない方が短いかもしれませんしr=range、何度も使用するので...
スティーヴィーグリフィン

1
これは次のように機能します143か?私が見ているのでrange(1,10)、その除外0し、103素数である
氏Xcoder

@ Mr.Xcoderの修正
デッドポッサム

1
あなたが必要としない0r(0,10)r(10)十分です。
ミスターXcoder

1
:また、私はそのように置くことをお勧めlambda I,r=range:
氏Xcoder

4

Javascript(ES6)148バイト

入力を文字列として受け取り、数値として返します

n=>(n.replace(/./g,"$`a$' ").split` `.map(s=>s&&[..."0123456789"].map(d=>r+=+(t=s.replace(/a/,d))[0]&&t^n&&(p=v=>t>1&(--v<2||t%v&&p(v)))(t)),r=0),r)

サンプルコードスニペット:

f=
n=>(n.replace(/./g,"$`a$' ").split` `.map(s=>s&&[..."0123456789"].map(d=>r+=+(t=s.replace(/a/,d))[0]&&t^n&&(p=v=>t>1&(--v<2||t%v&&p(v)))(t)),r=0),r)

for(var k=1;k<=20;k++)
  o.innerText+=f(""+k)+" "
<pre id=o></pre>



3

Mathematica、105バイト

F=Count[Range[f=IntegerDigits;g=10^Length@f@#/10,10g],n_/;PrimeQ@n&&MatchQ[f@n-f@#,{x=0...,_,x}]&&n!=#]&;

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

Function正の整数が必要#です。入力の桁のリストを返すf関数に等しいセットIntegerDigitsRangefrom gから10g(包括的)を取ります。ここg=10^Length@f@#/10で、10は入力以下の最大の累乗であり#、次CountnようになりPrimeQ@n&&MatchQ[f@n-f@#,{x=0...,_,x}]&&n!=#ます。PrimeQ@nかどうかをチェックしn、素数MatchQ[f@n-f@#,{x=0...,_,x}]の桁のリストとの間の差かどうかをチェックnし、#フォームであり{0..., _, 0...}、かつn!=#確実n#されていますUnequal


3

JavaScript(ES6)、153 142 139バイト

n=>([...n].map((c,i,[...a])=>[...''+1e9].map((u,j)=>s+=j+i&&j!=c?p((a.splice(i,1,j),a.join``)):0),s=0,p=q=>eval('for(k=q;q%--k;);k==1')),s)

入力を文字列として受け入れます。無効な入力に対する未定義の動作。ただし、考えられるすべての文字列でエラーなしで終了するはずです。ただし、特に長い弦の場合は、必ずしも宇宙の熱死の前ではありません。

デモ

f=
n=>([...n].map((c,i,[...a])=>[...''+1e9].map((u,j)=>s+=j+i&&j!=c?p((a.splice(i,1,j),a.join``)):0),s=0,p=q=>eval('for(k=q;q%--k;);k==1')),s)
console.log([...''+1e19].map((_,i)=>f(i+1+'')).join())
i.onchange=()=>console.log(f(i.value))
<input id=i>

改善点

reduce()呼び出しをmap()呼び出しにリファクタリングし、呼び出しaのコンテキスト内ではなく、関数パラメーターで暗黙的に配列をコピーすることにより、11バイトを節約しましたsplice()

@Neilのへの変換の提案のおかげで3バイト節約さ[...Array(10)]れました[...''+1e9]

縮小されていないコード

input => (
  [...input].map(
    (char, decimal, [...charArray]) =>
      [...'' + 1e9].map(
        (unused, digit) => sum +=
          digit + decimal && digit != char ?
            prime(
              (
                charArray.splice(decimal, 1, digit)
                , charArray.join``
              )
            ) :
            0
      )
    , sum = 0
    , prime = test => eval('for(factor = test; test % --factor;); factor == 1')
  )
  , sum
)

説明

この関数は、2つのレベルmap()を使用して、この回答から借用および変更された素数性テストに合格した順列の量を合計します

(元の答え)

reduce((accumulator, currentValue, currentIndex, array) => aggregate, initialValue)

そのため、たとえば、配列の合計を計算するには、initialValueof を渡し0aggregate等しいを返しaccumulator + currentValueます。このアプローチをわずかに変更して、代わりに素数性テストに合格する順列の数を計算します。

reduce(
  (passedSoFar, currentDecimal, currentIndex, digitArray) =>
    isValidPermutation() ?
      passedSoFar + prime(getPermutation()) :
      passedSoFar
  , 0
)

それは本質的に内部reduce()であり、digitArrayそれぞれdecimalを特定のものに変更することによってのすべての順列を繰り返しますpermutatedDigit。私たちは、その後、外側を必要とするreduce()すべての可能な反復処理するpermutatedDigitの各を交換するためにどのとのdecimalちょうどです、0-9

実装の異常

[...''+1e9].map((u,j)=>...@Neil0を介して引数を反復処理するために考えられる最短の方法でした9。そうとすることが好ましいuが、uこの場合には、アレイ内の各要素のために有用ではありません。

i+j0チャレンジ仕様に従って、3進条件チェックで、先頭の桁の可能な置換ではないことを確認します。j!=cオリジナルnが素数性テストを通過する候補ではないことを保証します。

(a.splice(i,1,j),a.join``)混乱のようなものです。splice()で桁を置き換えるdecimal == ipermutatedDigit == j、しかしのでsplice()戻り除去要素(この場合には、に等しくなる[a[i]]代わり変性配列の)、我々は、修飾配列を渡すカンマ演算子を使用する必要がa素数性テストにではなく、前にjoin()それをINGの数値文字列に。

最後eval()に、より標準的なアプローチと比較して、より短いため、バイトを保存することです:

q=>eval('for(k=q;q%--k;);k==1')

q=>{for(k=q;q%--k;);return k==1}

プライムテストへの参照pは、map()呼び出しに対する未使用の引数で初期化されます。


ヒントページのほう[...''+1e9]が短いと思います。
ニール

2

Python 2、134バイト

lambda x,r=range,l=len:sum(~-f*(~-l(x)==sum(`f`[t]==x[t]for t in r(l(x))))and all(f%v for v in r(2,f))for f in r(10**~-l(x),10**l(x)))

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

よりエレガントで長いバージョン:

lambda x,r=range,l=len:l(filter(lambda f:(~-f*(~-l(x)==sum(`f`[t]==x[t]for t in r(l(x)))))*all(f%v for v in r(2,f)),r(10**~-l(x),10**l(x))))

入力は文字列として取得されます。


説明(旧バージョン)

  • lambda x,r=range,l=len:-Stringパラメーターxと2つの定数パラメーターr=rangeおよびでラムダを定義しますl=len

  • sum(1...)-長さを取得し、1バイトを節約しlen([...])ます。

  • for f in r(10**~-l(x),10**l(x))-入力と同じ大きさで絶対的にすべての数値を生成します(を期待0)。たとえば、の入力は3になり[1, 2, 3, 4, 5, 6, 7, 8, 9]ます。

  • sum(1for t in r(l(x))if`f`[t]==x[t])==~-l(x)and f>1 -現在の数値が入力から正確に1桁離れているかどうか、および1より大きいかどうかを確認します。

  • all(f%v for v in r(2,f)) -現在の数が素数かどうかを確認します。


1
あなたは変更cound sum(1for..ifBOOL)するsum(BOOLfor)いくつかのバイトを保存するために
デッドポッサムに

入力を文字列として受け取ることはできますか?見て、私はよく分からない「入力と出力は、あなたの言語のネイティブ整数型に収まるように仮定することができる」
デッドポッサム

@DeadPossumいくつかの答えはあります。なぜ許可されないのですか?
ミスターXcoder

私は今日のための投票を使い果たしたんだけど、う1はできるだけ早く:D
デッドポッサム

@DeadPossum確かに。忘れないでください (</joke>
ミスターXcoder

1

JavaScript(ES6)、137バイト

i=(a=prompt()).length;s=0;while(i--)for(j=0;j<=9;j++){(b=[...a]).splice(i,1,j);k=b=b.join('');while(b%--k);s+=i+j&&a[i]!=j&&k==1}alert(s)

Web APIメソッドとを使用して、他の回答をプログラム全体の提出に適合させます。prompt()alert()


1

Bean、126バイト

00000000: a64d a065 8050 80a0 5d20 8001 a64d a06f  ¦M e.P. ] ..¦M o
00000010: 8025 39b5 cb81 2065 27a6 4da0 6680 2581  .%9µË. e'¦M f.%.
00000020: 0035 cb81 2066 27a6 53d0 80cd a05e 8043  .5Ë. f'¦SÐ.Í ^.C
00000030: cf20 5d00 2080 82a0 65a5 3a20 66a6 4da0  Ï ]. .. e¥: f¦M 
00000040: 6780 4da0 5e80 53d0 80a0 5e20 807b 2300  g.M ^.SÐ. ^ .{#.
00000050: b5cc a05e 8f4b c120 6728 264d a06f 814e  µÌ ^.KÁ g(&M o.N
00000060: cecc a065 8b20 6681 4cd0 84a0 5d20 6581  ÎÌ e. f.LÐ. ] e.
00000070: 2066 814c a067 8025 3a26 206f b130        f.L g.%:& o±0

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

私のフルプログラムJavaScript提出の適応。

同等のJavaScript

i=a.length
s=0
while(i--){
  j=10
  while(j--){
    (b=[...a]).splice(i,1,j)
    k=b=b.join('')
    while(b%--k);
    s+=i+j&&a[i]!=j&&k==1
  }
}
s

説明

aは、入力の最初の行として文字列として暗黙的に初期化され、最後のステートメントsは暗黙的に出力されます。これには素数の順列の合計が含まれます。


1

、32バイト

Lof§&ȯ=1Σzo±≠d⁰o=Ld⁰L↑o≤Ld⁰Lmdİp

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

非ゴルフ/説明

                              İp  -- get all primes
                            md    -- and convert them to list of digits
                     ↑o≤   L      -- take as long as the lenghth of these digit lists are ≤ ..
                        Ld⁰       -- .. the number of digits of input 
 of                               -- from those primes filter:
               o=Ld⁰L             --   same number of digits as input
   §&                             --   and
        Σz                        --   the number of..
          o±≠d⁰                   --   .. digits that differ from input digits ..
     ȯ=1                          --   .. must be one
L                                 -- finally count them


1

PHP151 147 141 140 136 134 129 128バイト

@Einacioのおかげで-6バイト。@Titusのおかげで-1バイト

<?php for($i=$m=10**strlen($n=$argv[1]);$i-->$m/10;)if(levenshtein($n,$i)==$f=$t=1){while($t<$i)$f+=$i%$t++<1;$c+=$f==2;}echo$c;

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

コメント付きのフォーマット済み:

<?php
// Work through each integer with the same number of digits as the input $argv[1].
for ($i = $m = 10 ** strlen($n = $argv[1]); $i-- > $m / 10;)
    // Is it exactly one digit different from the input?
    if (levenshtein($n, $i) == $f = $t = 1) {
        // Count its factors.
        while ($t < $i) $f += $i % $t++ < 1;
        // If there are exactly 2 factors then it's a prime, so increment the counter.
        $c += $f == 2;
    }
// Print the final count.
echo $c;

できるだけ短くするために、次のことを行いました。

  • 結合された割り当て$f = $t = 1
  • ++別の式の一部として増分をスヌークします$f += $i % $t++ == 0(増分はモジュラス演算のに実行されるため、結果に影響しません)。
  • if条件付きインクリメントのステートメントを使用するのではなく、整数としてキャストしたときにブール値trueが1になるという事実を利用するの$c += $f == 2;ではなく、を使用していif ($f == 2) $c++;ます。

1
$ cを定義する必要はありません。最初の場合は0としてカウントされます+ =
Einacio

@Einacioゴルフのルールは?未定義の変数警告通知を与えるため、それは許可されていますか?
WebSmithery

@EinacioどうやらSTDERRへの出力は無視できるようですので、提案をありがとう。
–WebSmithery

1
+1を使用する場合levenshtein。良いアイデア!$i%$t++<1はより短い$i%$t++==0
タイタス


0

PHP、100 + 1バイト

for(;~($a=$argn)[$i];$i++)for($d=-!!$i;$d++<9;$c+=$k==1)for($a[$i]=$d,$k=$a;--$k&&$a%$k;);echo$c-$i;

でパイプとして実行する-nR、オンラインで試してください

壊す

for(;~($n=$argn)[$i];$i++)  # loop through argument digits, restore $n in every iteration
    for($d=-!!$i;               # loop $d from 0 (1 for first digit)
        $d++<9;                 # ... to 9
        $c+=$k==1                   # 3. if divisor is 1, increment counter
    )
        for($n[$i]=$d,              # 1. replace digit
            $k=$n;--$k&&$n%$k;      # 2. find largest divisor of $n smaller than $n
        );
echo$c-$i;                  # print counter - length

0

Java 8、201 194バイト

n->{String s=n+"";int r=0,i=0,j,k,t,u,l=s.length();for(;i<l;i++)for(j=0;++j<10;r+=n==u|t<2?0:1)for(u=t=new Integer(s.substring(0,i)+j+(i<l?s.substring(i+1):"")),k=2;k<t;t=t%k++<1?0:t);return r;}

説明:

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

n->{                        // Method with integer as parameter and return-type
  String s=n+"";            //  String representation of the input-int
  int r=0,                  //  Result-integer
      i=0,j,k,              //  Index-integers
      t,u,                  //  Temp integers
      l=s.length();         //  Length of the String
  for(;i<l;i++)             //  Loop (1) from 0 to `l` (exclusive)
    for(j=0;++j<10;         //   Inner loop (2) from 1 to 10 (exclusive)
        r+=                 //     And after every iteration, raise the result by:
           n==u             //      If the current number equals the input
           |t<2?            //      or it is not a prime:
            0               //       Add nothing to the result-counter
           :                //      Else:
            1)              //       Raise the result-counter by one
      for(                  //    Inner loop (3)
          u=t=              //     First set both `u` and `t` to:
              new Integer(  //      Convert the following String to an integer: 
               s.substring(0,i)
                            //       Get the substring from 0 to `i` (exclusive)
               +j           //       + `j`
               +(i<l?       //       + If `i` is smaller than the String-length:
                  s.substring(i+1)
                            //          The substring from 0 to `i` (inclusive)
                 :          //         Else:
                  "")),     //          Nothing
          k=2;              //     And start `k` at 2
              k<t;          //     Continue looping as long as `k` is smaller than `t`
        t=t%k++<1?          //     If `t` is divisible by `k`:
           0                //      Change `t` to 0
          :                 //     Else:
           t                //      Leave `t` as is
      );                    //    End of inner loop (3)
                            //    (`t` remained the same after loop 3? -> It's a prime)
                            //   End of inner loop (2) (implicit / single-line body)
                            //  And of loop (1) (implicit / single-line body)
  return r;                 //  Return the result-counter
}                           // End of method

new Integer(s.substring(0,i)+j+(i<l?s.substring(i+1):"") これらの整数になります:

の場合0-91, 2, 3, 4, 5, 6, 7, 8, 9
の場合1010, 20, 30, 40, 50, 60, 70, 80, 90, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
の場合1111, 21, 31, 41, 51, 61, 71, 81, 91, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19


0

JavaScript(ES7)、118バイト

入力を文字列として受け取ります。

n=>[...2**29+'4'].map(d=>n.replace(/./g,c=>s+=d+i>0&(P=k=>N%--k?P(k):N-n&&k==1)(N=p+d+n.slice(++i),p+=c),i=p=0),s=0)|s

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

コメント済み

n =>                        // n = input number (as a string)
  [...2**29 + '4']          // generate "5368709124" (all decimal digits)
  .map(d =>                 // for each digit d in the above string:
    n.replace(/./g, c =>    //   for each digit c in n:
      s +=                  //     increment s if the following code yields 1:
        d + i > 0 & (       //       if this is not the first digit of n or d is not "0":
          P = k =>          //         P = recursive function taking k and using N:
            N % --k ?       //           decrement k; if k is not a divisor of N:
              P(k)          //             do recursive calls until it is
            :               //           else:
              N - n &&      //             return true if N is not equal to n
              k == 1        //             and k is equal to 1 (i.e. N is prime)
          )(                //         initial call to P ...
            N =             //           ... with N defined as:
              p +           //             the current prefix p
              d +           //             followed by d
              n.slice(++i), //             followed by the trailing digits
                            //             (and increment the pointer i)
            p += c          //           append c to p
          ),                //         end of initial call
          i = p = 0         //         start with i = p = 0
    ),                      //   end of replace()
    s = 0                   //   start with s = 0
  ) | s                     // end of map(); return s

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