素数ビット数の素数


23

仕事

最大と与えられたゼロ以外の正の整数を含むすべての非負整数を探すnは、プライムされているとのカウント1's0's(何の先行ゼロを持たない)彼らのバイナリ表現ではあまりにプライムあります。

以下に、このような素数の最初の5つを示します。

17, 19, 37, 41, 79

10001, 10011, 100101, 101001, 1001111

明確化と規則

  • デフォルトのI / Oメソッドが受け入れられます。
  • 答えはプログラムまたは関数です。
  • そのような素数がない場合は、ごみを出力するか、何も出力しません。
  • 標準的な抜け穴は禁止されています。
  • 2 3 5 7は、バイナリ表現では0'sおよびの出現回数が1's素数ではないため、リストに追加しませんでした。7バイナリ表現が111であると考えてください。ここで0はゼロ回発生し、ゼロは素数ではありません。
  • 組み込みが許可されています。

  • バイト単位の最短コードが勝ちです!

テストケース

10
[]

100
[17、19、37、41、79]

150
[17、19、37、41、79、103、107、109、131、137]


1
与えられたnの下のすべての素数を求めますが、包括的とも言います。どういう意味ですか?
ライリー

@Riley私が言いたいのは… all the numbers from 1....n。私は簡単な方法でそれを言い換える方法がわかりません。
グルパッドママダプール


3
@ mbomb007明らかに、整数シーケンスのすべての順序について、最小の興味のない整数シーケンス自体が興味深いものであり、したがってOEISに含める価値があります。エルゴ、OEISには、実在または想像されるすべての整数列が含まれています:
Iwillnotexist Idonotexist

9
私は、MathematicaはOEISが列を持っているよりも多くの組み込みコマンドが含まれているかどうかを思ったんだけど...
ニール

回答:


5

ゼリー14 13バイト

RBċþd`ÆPPTfÆR

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

使い方

RBċþd`ÆPPTfÆR  Main link. Argument: n

R              Range; yield [1, ..., n].
 B             Binary; convert each integer to base 2.
    d`         Divmod self; yield [n : n, n % n], i.e., [1, 0].
  ċþ           Count table; count the occurrences of 1 and 0 in each binary
               representation, yielding a pair of lists of length n.
      ÆP       Test each count for primality.
        P      Product; multiply the corresponding Booleans.
         T     Truth; get all indices of 1, yielding the list of integers in
               [1, ..., n] that have a prime amount of 0's and 1's.
           ÆR  Prime range; yield all primes in [1, ..., n].
          f    Filter; intersect the lists.

2
そのd`​トリックは...何か他のものである
ETHproductions

10

パイソン2106の 102 100バイト

k=m=1;p={0}
exec"p^={m%k*k,0};c=bin(k).count\nif{k,c('1'),c('0')-1}<p:print k\nm*=k*k;k+=1;"*input()

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

バックグラウンド

素数を特定するために、ウィルソンの定理の帰納法を使用します。

corollary of Wilson's theorem

使い方

km1として初期化し、pをセット{0}として初期化することから始めます。m = 1 = 0!²=(k-1)!²であることに注意してください。その直後に、次のコードがn回実行されます。nは標準入力から読み取られた整数です。

p^={m%k*k,0};c=bin(k).count
if{k,c('1'),c('0')-1}<p:print k
m*=k*k;k+=1

当然、kが素数の場合、m%k1になり、それ以外の場合は0になります。したがって、kが素数であれば集合{k、0}を返し、そうでなければ集合{0}を返します。{m%k*k,0}

kが素数の場合(およびその場合のみ)、pはこの時点でkを含むことができないため、インプレース対称差分p^={m%k*k,0}はセットpにkを追加します。また、更新前にp0が含まれるのは、更新前に0が含まれていない場合のみです。したがって、kが偶数の場合にのみ0 ∊ pです。

同じ行で、を介して関数cを定義しますc=bin(k).count。これは、kのバイナリ表現で引数の出現をカウントします。

2行目は実際の出力を生成します。{k,c('1'),c('0')-1}リターンから成るセットK自体で設定ビット数K、及びで未設定のビット数K。の出力は0bbin(k)始まるため、先頭の0を説明するためにデクリメントする必要がありますc('0')

それらのすべてが素数である場合、それらはすべてpに属し、現在はk(および潜在的に0)までのすべての素数を含んでいます。場合kはメルセンヌ数である(それはビットのみを設定した場合、すなわち、)、c('0')-1もたらす0。メルセンヌ数は奇数であるため、pには0が含まれないため、条件は失敗します。

(潜在的に)kを印刷した後、mを乗算します。以降、M =(K-1)!²更新前、²!M = Kこと後。kをインクリメントした後、関係m =(k-1)!²が再び成立し、次の反復の準備ができました。


9

Mathematica、80 68 54バイト

Select[p=PrimeQ;Range@#,p@#&&And@@p/@#~DigitCount~2&]&

説明

Select[p=PrimeQ;Range@#,p@#&&And@@p/@#~DigitCount~2&]&

       p=PrimeQ                                        (* Store prime check func. in p *)
Select[                                             ]  (* Select *)
                Range@#                                (* from a list {1..n} *)
                        p@#                            (* numbers that are prime *)
                           &&                          (* And *)
                                     #~DigitCount~2    (* whose digit counts in binary *)
                             And@@p/@                  (* are prime as well *)

8

JavaScript(ES6)、123 118 115 111 104 96バイト

@Arnauldのおかげで4バイト節約

G=n=>n?G(n>>1,++a[n%2]):a.some(n=>(P=x=>n%--x?P(x):x)(n)-1)
F=n=>F(n-1,G(n,a=[0,0,n])||alert(n))

3つの典型的な再帰関数の組み合わせ。シーケンスを逆順で警告し、「再帰が多すぎる」エラーで終了します。

テストスニペット

(ページへの出力に変更)

メイン関数は、104バイトの配列を返すことができます。

G=n=>n?G(n>>1,++a[n%2]):a.some(n=>(P=x=>n%--x?P(x):x)(n)-1)
F=n=>n?F(n-1).concat(G(n,a=[0,0,n])?[]:n):[]

また、別のバイトを犠牲にして非再帰的にすることもできます。

G=n=>n?G(n>>1,++a[n%2]):a.some(n=>(P=x=>n%--x?P(x):x)(n)-1)
n=>[for(_ of Array(n))if(!G(--n,a=[0,0,n]))n]

私が始めたものは次のとおりです(@Arnauldのおかげで6バイト保存されました)

P=(n,x=n)=>n>1&--x<2||n%x&&P(n,x)
G=n=>n?G(n>>1,o+=n%2,t++):P(o)&P(t-o)
F=n=>n?F(n-1).concat(P(n)&G(n,o=t=0)?n:[]):[]

さらにゴルフを試してみて、104バイトで何とかしました。それで、その解決策を既に見つけていたことがわかりました(答えの一番下にあります)。それが起こったら嫌いではないですか?:P

メイン関数での非再帰的な試み(再び、同じバイトカウント):

n=>[for(i of Array(n))if(P(--n)&G(n,o=t=0))n]

これは、バイナリ表現に含まれる0と1の数を数える簡単なルートです。

F=n=>n?F(n-1).concat([n,(G=x=>n.toString(2).split(x).length-1)(0),G(1)].some(n=>(P=x=>n%--x?P(x):x)(n)-1)?[]:n):[]

配列内包表記でも同じこと:

n=>[for(_ of Array(n))if(![--n,(G=x=>n.toString(2).split(x).length-1)(0),G(1)].some(n=>(P=x=>n%--x?P(x):x)(n)-1))n]

これは同じことをするために少し難しいルートを取ります:

F=n=>n?F(n-1).concat([n,(G=(x,w=n)=>w&&G(x,w>>1)+(w%2==x))(0),G(1)].some(n=>(P=x=>n%--x?P(x):x)(n)-1)?[]:n):[]

そして、これはオリジナルと同じくらい短いさらに別の関連するルートを取ります:

F=n=>n?F(n-1).concat([n,o=(G=x=>x&&x%2+G(n>>++t))(n,t=0),t-o].some(n=>(P=x=>n%--x?P(x):x)(n)-1)?[]:n):[]

繰り返しますが、逆の順序でシーケンスを警告することにより、8バイトをゴルフできます。

F=n=>F(n-1,[n,o=(G=x=>x&&x%2+G(n>>++t))(n,t=0),t-o].some(n=>(P=x=>n%--x?P(x):x)(n)-1)||alert(n))

あなたは本当に再帰的に渡す必要はありませんa。の最初の呼び出しで初期化するだけGです。(これは4バイトを節約するはずです。)
アーナルド

@アーナウルドそうそう、ありがとう!これは楽しいです:
ETHproductions

1
うわー、これはたくさん落ちました。良い仕事
ジョージリース

6

ゼリー17 16 バイト

BĠL€µ;LÆPẠ
ÆRÇÐf

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

どうやって?

BĠL€µ;LÆPẠ - Link 1, hasPrimeBits: n  e.g. 7         or 13
B          - convert to binary        e.g. [1,1,1]  or [1,1,0,1]
 Ġ         - group indices            e.g. [1,2,3]  or [3,[1,2,4]]
  L€       - length of €ach           e.g. 3          or [1,3]
    µ      - monadic chain separation
     ;L    - concatenate length       e.g. [3,1]      or [1,3,2]
           -     this caters for the edge case of Mersenne primes (like 7), which have
           -     no zero bits, the length will be 1, which is not prime.
       ÆP  - isPrime?                 e.g. [1,0]      or [0,1,1]
         Ạ - All?                     e.g. 0          or 0

ÆRÇÐf - Main link: N
ÆR    - prime range (primes up to and including N)
   Ðf - filter keep those satisfying
  Ç   - last link (1) as a monad

1
ああ、ありがとうございます
ジョナサンアラン

1
アルファベットが表示されます。ẠBÇЀfĠ...
mbomb007

2
@ mbomb007ええ、LƵ;Pビットはいつも私を混乱させます。
ジョナサンアラン

6

05AB1E、14バイト

ƒNpNbSD_‚OpP&–

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

説明

ƒ               # for N in [0 ... input]
 Np             # push N is prime
   Nb           # push N converted to binary
     S          # split into individual digits
      D_        # push an inverted copy
        ‚       # pair the 2 binary lists
         O      # sum them
          p     # elementwise check for primality
           P    # product of list
            &   # and with the primality of N
             –  # if true, print N

私はまだのための使用を見つけることができない、この課題は、それのために良いと思われたが、より長いです:FNb{.¡€gpONp+3QiN}})
マジックタコ壺

@carusocomputing:私も同様のソリューションを考えましたが、これよりも少し長くなりました。
エミグナ


4

MATL16 15バイト

:"@tB!t~hshZp?@

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

:         % Input n (implicit). Push range [1 2 ... n]
"         % For each k in [1 2 ... n]
  @       %   Push k
  tB!     %   Duplicate. Binary expansion as an m×1 vector
  t~      %   Duplicate. Negate
  hs      %   Concatenate horizontally into an m×2 matrix. Sum of each column.
          %   This gives a 1×2 vector. However, for k==1 this gives the sum of
          %   the original 1×2 matrix (m==1). But fortunately it doesn't matter
          %   because 1 is not a prime anyway
  h       %   Concatenate horizontally into a 1×3 row vector
  Zp      %   Isprime function applied on each of those three numbers
  ?       %   If all gave true
    @     %     Push k
          %   End (implicit)
          % End (implicit)
          % Display (implicit)

4

Perl、101バイト

99バイトのコード+ -nlフラグ。

$r=q/^1?$|^(11+)\1+$/;for$@(2..$_){$_=sprintf"%b",$@;print$@if(1x$@)!~$r&y/01/1/dr!~$r&s/0//gr!~$r}

実行するには:

perl -lne '$r=q/^1?$|^(11+)\1+$/;for$@(2..$_){$_=sprintf"%b",$@;print$@if(1x$@)!~$r&y/01/1/dr!~$r&s/0//gr!~$r}' <<< 150

いくつかの簡単な説明
$rは、古典的な素数チェック正規表現(q/^1?$|^(11+)\1+$/)を保持しています。
2から入力までのすべての数値について
(1x$@)!~$r、数値が素数
y/01/1/dr!~$rかどうか0、バイナリ表現の数が素数かどうか、バイナリ表現の数が素数
s/0//gr!~$rかどうかを確認します1
(3つの条件が満たされている場合、print$@印刷します)。


説明してくれてありがとう。基本的に正規表現といくつかのロジックで何ができるかは非常に素晴らしいです:)
エミグナ

@Emignaありがとう!説明はあまり詳細ではありませんが(長い説明を書くのに苦労しています)、それで十分だったようです:)(まだコードが少し長すぎると思いますが、それは短いので、ここにあります)
ダダ

1
Perlを知らない人として、私が得ることができるすべての説明に感謝します。Perlプログラムを作成する助けにはなりませんが、採用されている方法の背後にある理由のいくつかは理解していますが、これは常に興味深いものです。
エミグナ

3

パイソン、129の 125 123バイト

ゼロのみが素数の場合...

p=lambda n:all(n%m for m in range(2,n))*n>1
lambda n:[i for i in range(n+1)if p(i)*all(p(bin(i)[2:].count(x))for x in'01')]

オンラインで試す

Function pは素数チェック関数です。この関数>0は最後に0でも機能するように機能し、そうでなければを返し-1ます。匿名ラムダは、必要なすべての条件をチェックするラムダです。


以下に、セット内包表記を使用した少し異なる方法を示します。結果はセットになります。(124バイト):

p=lambda n:all(n%m for m in range(2,n))*n>1
lambda n:{i*p(i)*all(p(bin(i)[2:].count(x))for x in'01')for i in range(n+1)}-{0}

3

Perl 6、65バイト

{grep {all($^a,|map {+$a.base(2).comb(~$_)},0,1).is-prime},0..$_}

それを試してみてください

拡張:

{           # bare block lambda with implicit parameter 「$_」

  grep      # find all of the values where

  {         # lambda with placeholder parameter 「$a」

    all(    # all junction ( treat multiple values as a single value )

      $^a,  # declare parameter to block

      |\    # slip the following list into the outer list

      # get the count of 0's and 1's in the binary representation
      map

      {             # bare block lambda with implicit parameter 「$_」

        +           # turn to numeric ( count the values in the list )
        $a          # the outer parameter
        .base(2)    # in base 2
        .comb(~$_)  # find the characters that are the same as
      },0,1         # 0 or 1

    # ask if $a, count of 0's, count of 1's are all prime
    ).is-prime

  },

  0 .. $_ # Range from 0 to the input inclusive

}

3

オクターブ、73バイト

@(n)(p=primes(n))(all(isprime([s=sum(dec2bin(p)'-48);fix(log2(p))+1-s])))

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

@(n)
    (p=primes(n))                           generate prime numbers
        (all(                               from them select those that
            isprime(                        are prime both
                [s=sum(dec2bin(p)'-48);     sum of 1s
                fix(log2(p))+1-s])))        and sum of 0s

2

CJam26 27バイト

ri){mp},{2b_1-,mp\0-,mp&},p

簡単なアルゴリズムは、さらにゴルフをします。

編集:忘れていたnが含まれていました。

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

おもしろいことに、これは非常によく似ており、27バイトです。

ri){_mp\2b_1-,mp\0-,mp&&},p

説明

ri                          e# Take an int as input
  ){mp},                    e# Take the range up and including to the input, 
                            e#   including only prime numbers
       {                    e# For each prime...
        2b_                 e# Convert it to binary and copy it
           1-,mp            e# Take the top binary number, remove 1's, check if the length 
                            e#   is prime
                \           e# Swap top elements
                 0-,mp      e# Do the same but remove 0's
                      &     e# And
                       },   e# Filter out primes for which the above block was false
                         p  e# Print nicely

2

ゼリー、14バイト

BċÆPðÐf
ÆRç0ç1

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

残念ながら、@ Dennisとしか結びつけることはできませんでしたが、アルゴリズムは多少異なるようですので、とにかくこれを投稿しています。

説明

ヘルパー関数(指定されたビットのオカレンスの素数を持たないリスト要素を削除します):

BċÆPðÐf
     Ðf   Filter {the first argument}, looking for truthy returns from
    ð     the preceding code, which takes two arguments:
B         Convert {the element being checked} to binary
 ċ        Count the number of occurrences of {the second argument}
  ÆP      Return true if prime, false if not prime

メインプログラム:

ÆRç0ç1
ÆR        Generate all primes from 2 to the input
  ç0      Call the subroutine to require a prime 0 count
    ç1    Call the subroutine to require a prime 1 count

2

Haxe、169 171バイト

function f(n,?p)return[for(j in(p=[for(i in 0...++n)i<2?0:i]))if(j>0){var x=j*2,y=0,z=0,k=j;while(k<n)p[k+=j]=0;while((x>>=1)>0)x&1>0?y++:z++;p[y]<1||p[z]<1?continue:j;}];

クレイジーなものはありません。本質的に、より高い非素数を消すのと同じ反復で0/1カウントの素数性を評価するエラトステネスの修正されたふるい。いくつかの空白を使用:

function f(n, ?p)
  return [ for (j in (p = [ for(i in 0...++n) i < 2 ? 0 : i ]))
    if (j > 0){
      var x = j * 2, y = 0, z = 0, k = j;
      while (k < n)
        p[k += j] = 0;
      while((x >>= 1) > 0)
        x & 1 > 0 ? y++ : z++;
      p[y] < 1 || p[z] < 1 ? continue : j;
    }
  ];

しかし今日、私continueは三項演算子を入力できることを学びました。

編集:+2 nは包括的な上限であるためです!


ねえ、n包括的です。
グルパッドママダプール

@GurupadMamadapurあなたは正しい、修正されました!
オーレルビリー

2

バッシュ + GNUユーティリティ、129の 126 123 114 111 109バイト

seq '-fp()([ `factor|wc -w` = 2 ]);g()(dc -e2o${n}n|tr -cd $1|wc -c|p);n=%.f;p<<<$n&&g 0&&g 1&&echo $n' $1|sh

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

出力が昇順である必要はないというコメントに注目してください。カウントアップする代わりにカウントダウンすることで3バイトを削り落としました。

grepをwcに置き換えて、さらに3バイトを節約しました。

変数を削除しました(さらに9バイトオフ)。

係数の使用方法を変更しました-さらに3バイト。

seq(2バイト)でゴルファーにしました。


2

パイソン、172の 170 168 159 154 133 130バイト

p=lambda n:[i for i in range(1,n)if n%i==0]==[1]
lambda n:[i for i in range(n+1)if p(i)*all(p(bin(i)[2:].count(x))for x in'10')]

使用法:匿名のラムダ関数を呼び出す
メソッドpは、数値が素数かどうかをチェックします


Gurupad Mamadapurのおかげで2 + 2 + 9 = 13バイトを節約mbomb007の
おかげで5バイトを節約


1
あなたはこれを使って、2以上を節約することができますv-def v(n):a=bin(n)[2:];return p(n)and(p(a.count('1'))and p(a.count('0')))
Gurupad Mamadapur

1
はるかに短い1 -v=lambda a:p(a)and all(p(bin(a)[2:].count(x))for x in['1','0'])
Gurupad Mamadapur

2
文字列は反復可能です。だからあなたは使うことができますfor x in'01'
mbomb007





1

JavaScript(ES6)、110バイト

B=n=>n?B(n>>1,v[n%2]++):v.every(n=>(P=i=>n%--i?P(i):1==i)(n))
F=(n,a=[])=>n?F(n-1,B(n,v=[0,0,n])?[n,...a]:a):a


その素数性テスト機能は...驚くべきことです。
ETHproductions

あなたが前にそれを見てきました@ETHproductions codegolf.stackexchange.com/a/91309/11182ここから変更。また、1と0のカウントコード(私が思いつくものなら何でも)を借りましたが、残念ながらあなたのバイトカウントに勝るものはありませんでした。
ジョージリース

@ETHproductions良いキャッチありがとう!以前のバージョンのアーティファクト
ジョージリース


1

Haxe、158 147バイト

function p(n,x=1)return n%++x<1||n<2?x==n:p(n,x);function f(n){var q=n,t=0,o=0;while(q>0){t++;o+=q%2;q>>=1;}p(n)&&p(o)&&p(t-o)?trace(n):0;f(n-1);};

STDOUTに出力し、「再帰が多すぎる」エラーで終了します。例で呼び出しますf(1000);while156バイトのエラーなしでループを使用できます。

function p(n,x=1)return n%++x<1||n<2?x==n:p(n,x);function f(n){while(n>0){var q=n,t=0,o=0;while(q>0){t++;o+=q%2;q>>=1;}p(n)&&p(o)&&p(t-o)?trace(n):0;n--;}};

範囲を使用すると、3バイト長くなりました。

function p(n,x=1)return n%++x<1||n<2?x==n:p(n,x);function f(n){for(i in 0...n+1){var q=i,t=0,o=0;while(q>0){t++;o+=q%2;q>>=1;}p(i)&&p(o)&&p(t-o)?trace(i):0;}};

オンラインでテストしてください!


1

さび、147バイト

fn f(x:u32){let p=|n|n>1&&(2..n).all(|x|n%x!=0);for n in 9..x+1{if p(n)&&p(n.count_ones())&&p(n.count_zeros()-n.leading_zeros()){print!("{} ",n)}}}

遊び場リンク

count_onescount_zerosleading_zeros方法が便利になりました。

フォーマット済みバージョン

fn f(x: u32) {
    // primality test closure using trial division
    let p = |n| n > 1 && (2..n).all(|x| n % x != 0);

    for n in 9..x + 1 {
        if p(n) && p(n.count_ones()) && p(n.count_zeros() - n.leading_zeros()) {
            print!("{} ", n)
        }
    }
}

1

Perl 6、50バイト

{grep {($_&+.base(2).comb(~0&~1)).is-prime},0..$_}

ジャンクションを使用したb2gillsの回答のバリエーション& 演算子を。

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

使い方

{                                                }  # Lambda
                                            0..$_   # Range from 0 to the lambda argument.
 grep {                                   },        # Filter values satisfying:
       ($_                      ).is-prime          #  a) The Number itself is prime.
       (   +.base(2).comb(~0   )).is-prime          #  b) The count of 0's is prime.
       (   +.base(2).comb(   ~1)).is-prime          #  c) The count of 1's is prime.
          &                 &                       # Junction magic! :)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.