Простые числа с простыми счетчиками битов


23

задача

Найдите все неотрицательные целые числа вплоть до заданного ненулевого положительного целого числа n , которые являются простыми, а количество 1'sи 0'sв их двоичном представлении (не имеющем начальных нулей) тоже простое.

Вот первые пять таких простых чисел,

17, 19, 37, 41, 79

10001, 10011, 100101, 101001, 1001111

Разъяснения и правила

  • Методы ввода / вывода по умолчанию принимаются .
  • Ответом может быть программа или функция.
  • Если таких простых чисел нет, выведите мусор или ничего.
  • Стандартные лазейки запрещены.
  • 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
Вы спрашиваете , для всех простых чисел при заданном п, но вы также сказать , включительно. Что ты имеешь в виду?
Райли

@Riley Что я имею в виду ... all the numbers from 1....n. Я не знаю, как перефразировать это простым способом.
Гурупад Мамадапур


3
@ mbomb007 Очевидно, что для любого общего порядка целочисленных последовательностей наименьшая неинтересная целочисленная последовательность сама по себе была бы интересна и, следовательно, достойна включения в OEIS. Ergo, 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

Python 2 , 106 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()

Попробуйте онлайн!

Задний план

Чтобы определить простые числа, мы используем следствие теоремы Вильсона :

следствие теоремы Вильсона

Как это работает

Мы начнем с инициализации k и m как 1 и 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

По следствию m% k будет 1, если k простое, и 0 в противном случае. Таким образом, {m%k*k,0}вернет множество {k, 0}, если k простое, а множество {0} в противном случае.

Если (и только если) k простое, поскольку p не может содержать k в этой точке, симметричная разность на месте p^={m%k*k,0}добавит k к множеству p . Кроме того, p будет содержать 0 после обновления, если и только если он не содержит 0 до этого, поэтому 0 ∊ p тогда и только тогда, когда k является четным.

В той же строке мы определяем функцию c via c=bin(k).count, которая будет подсчитывать вхождения своего аргумента в двоичном представлении k .

Вторая строка выдает фактический результат. {k,c('1'),c('0')-1}возвращает набор, состоящий из самого k , количества установленных битов в k и количества неустановленных битов в k . Так как вывод bin(k)начинается с 0b , мы должны уменьшить, c('0')чтобы учесть ведущий 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 байт

Сохранено 4 байта благодаря @Arnauld

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

Сочетание трех типичных рекурсивных функций. Предупреждает последовательность в обратном порядке и завершается с ошибкой «слишком много рекурсии».

Тестовый фрагмент

(изменено для вывода на страницу)

Основная функция может возвращать массив размером 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]

Вот тот, с которого я начал: (Сохранено 6 байтов благодаря @Arnauld)

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 байта, а затем понял, что уже нашел это решение (оно в нижней части ответа). Разве ты не ненавидишь, когда это происходит? :П

Нерекурсивная попытка главной функции (опять же, тот же счетчик байтов):

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 байта.)
Арно

@ Arnauld Ах да, спасибо! Это весело :-)
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: у меня было похожее решение, которое я рассматривал, но оно также оказалось немного длиннее, чем это.
Emigna


4

MATL , 16 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

@ Emigna Спасибо! Объяснения не очень подробны (мне трудно писать более длинные объяснения), но, кажется, этого было достаточно для вас :) (Я все еще считаю, что код немного слишком длинный, но я не понимаю, как его получить. короче, так вот оно и есть)
дада

1
Как человек, который не знает Perl, я ценю каждое объяснение, которое могу получить. Это не поможет мне создать программу на Perl, но я понимаю некоторые причины, лежащие в основе используемого метода, что всегда интересно.
Эминья

3

Python, 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')]

Попробуйте онлайн

Функция p- это функция первичной проверки, которая имеет >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..$_}

Попытайся

Expanded:

{           # 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

CJam , 26 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 Вы правы, исправлено!
Aurel Bílý

2

Утилиты Bash + 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 байта.

Сделано в гольф с секвенсом (2 байта).


2

Python, 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проверяет, является ли число простым


Сохранено 2 + 2 + 9 = 13 байт благодаря Gurupad Mamadapur.
Сохранено 5 байт благодаря mbomb007.


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
Гораздо короче -v=lambda a:p(a)and all(p(bin(a)[2:].count(x))for x in['1','0'])
Гурупад Мамадапур

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);. Вы можете использовать whileцикл без ошибок для 156 байтов:

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

Использование диапазона оказалось на три байта длиннее:

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_ones,count_zeros и leading_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! :)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.