Примери з простими розрядами


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
Ви запитуєте про всі праймери під заданою n, але ви також говорите включно. Що ви маєте на увазі?
Райлі

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

Спробуйте в Інтернеті!

Фон

Для ідентифікації простих чисел ми використовуємо суперечку теореми Вілсона :

corollary of Wilson's theorem

Як це працює

Почнемо з ініціалізації 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

Математика, 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 байтах - тоді зрозумів, що вже знайшов це рішення (воно знаходиться внизу відповіді). Хіба ти не ненавидиш це, коли це станеться? : 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 байти.)
Арнольд

@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: У мене було подібне рішення, яке я також вважав, але воно також закінчилося трохи довше, ніж це.
Емінья


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

Пітона, 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..$_}

Спробуй це

Розширено:

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

}


2

CJam , 26 27 байт

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

Прямий алгоритм, буде гольф далі.

EDIT: Забули п. Включено.

Спробуйте в Інтернеті!

Для задоволення це дуже схоже, а також 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

Хакс, 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 байти.

Зробив це гольфіст із 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перевіряє, чи є число простим


Збережено 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

Пайк, 21 байт

S#j_PI\0[jb2R/_P)I\1[

Спробуйте тут!

S#j                   - for j in filter(range(1, input+1))
   _PI                -  if is_prime(j):
        [jb2R/_P)     -   function_[(a) = V
         jb2          -      base_2(j)
            R/        -     ^.count(a)
      \0         I    -   if function_[("0"):
                  \1[ -    function_[("1")



1

Python 3, 97 bytes

def f(n,k=2,m=1,p={0}):f(n-1,k+1,m*k*k,p^{m%k*k,{*map(bin(m%k%n*k)[2:].count,'01')}<p==print(k)})

This is the same algorithm as in my Python 2 answer, but the implementation is quite different. The function prints to STDOUT and terminates with an error.

Try it online!


1

JavaScript (ES6), 110 bytes

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


That primality test function is... just amazing :-) Did you create it yourself?
ETHproductions

@ETHproductions You've seen it before codegolf.stackexchange.com/a/91309/11182 modified from here. I also borrowed your 1 and 0 counting code (whooped anything I could come up with) but alas I couldn't beat your byte count.
George Reith

@ETHproductions Good catch thanks! Was an artefact of a previous version
George Reith


1

Haxe, 158 147 bytes

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

Outputs to STDOUT and terminates on a "too much recursion" error; call with e.g. f(1000);. You can use a while loop with no error for 156 bytes:

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

Using a range turned out three bytes longer:

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

Test it online!


1

Rust, 147 bytes

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

playground link

The count_ones, count_zeros, and leading_zeros methods came in handy.

Formatted version

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 bytes

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

Variation of b2gills' answer, using the & junction operator to great effect.

Try it online!

How it works

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