Композитні числа, стійкі до бітфліпу


26

Іноді під час написання програми вам потрібно використовувати просте число з тих чи інших причин (наприклад, криптовалюта). Я припускаю, що іноді потрібно використовувати і складене число. Іноді, принаймні тут, на PPCG, ваша програма повинна мати можливість боротися з довільними змінами. І за обставин, зручних для створення цікавого питання про PPCG, можливо, навіть ті цифри, які ви використовуєте, повинні бути стійкими до корупції ...

Визначення

Складене число є цілим числом ≥ 4 , що не є простим, тобто цей твір двох менших чисел більше 1. А bitflip резистентних складене число визначається наступним чином : це складене натуральне число , для якого, якщо ви пишете у двійковій формі з мінімально можливою кількістю бітів ви можете змінити будь-який один або два біти з числа, і число все ще є складовим.

Приклад

Наприклад, розглянемо число 84. У двійковому - це 1010100. Ось усі числа, які відрізняються не більше ніж на 2 біти від цього:

0000100 4 2 × 2
0010000 16 4 × 4
0010100 20 4 × 5
0010101 21 3 × 7
0010110 22 2 × 11
0011100 28 4 × 7
0110100 52 4 × 13
1000000 64 8 × 8
1000100 68 4 × 17
1000101 69 3 × 23
1000110 70 7 × 10
1001100 76 4 × 19
1010000 80 8 × 10
1010001 81 9 × 9
1010010 82 2 × 41
1010100 84 7 × 12
1010101 85 5 × 17
1010110 86 2 × 43
1010111 87 3 × 29
1011000 88 8 × 11
1011100 92 4 × 23
1011101 93 3 × 31
1011110 94 2 × 47
1100100 100 10 × 10
1110000 112 8 × 14
1110100 116 4 × 29
1110101 117 9 × 13
1110110 118 2 × 59
1111100 124 4 × 31

Перший стовпець - це число у двійковій формі; другий стовпець - це число у десятковій частині. Як вказує третій стовпець, усі ці числа є складовими. Таким чином, 84 - це композитне число, стійке до бітліпу.

Завдання

Ви повинні написати одну з наступних трьох програм або функцій, що б не мало сенсу для вашої мови:

  • Програма або функція, яка приймає як вхідне невід'ємне ціле число n , і виводить перші n композитних чисел, стійких до бітфліпу.
  • Програма або функція, яка приймає як вхідне невід'ємне ціле число n і видає всі складені числа, стійкі до бітфліпу, менші ніж n (або, якщо вам зручніше, менше або дорівнює n , тобто ви можете вибрати, чи буде включено n у вихід, якщо bitflip -резистентний).
  • Програма або функція, яка не вводить даних, і виводить всі складені числа, стійкі до бітфліпу. (Для цього потрібно використовувати механізм виводу, здатний виробляти вихід, поки програма ще працює, наприклад, друк у stdout, лінивий список чи генератор; ви не можете просто обчислити весь список, а потім надрукувати його.)

Тестові справи

Ось перші декілька композитних номерів, стійких до бітфліпу:

84, 184, 246, 252, 324, 342, 424, 468, 588, 636, 664, 670, 712, 730, 934, 958

Роз'яснення

  • Лише ті цифри, які ви створюєте, повинні бути стійкими до бітфліпів. Це не завдання зробити програму, яка вважає їх стійкими до бітфліпів; використовувати будь-які цифри в самій програмі, які вам подобаються.
  • Виведені цифри не повинні бути стійкими до бітфліпта у "провідних нулях"; уявіть, що цифри будуть збережені в мінімально можливій кількості бітів, і лише ті біти повинні бути захищені від гортання. Однак початкові 1 біт на число, яке ви виводите, повинні бути захищені від бітфліпів.
  • Використовуйте будь-який вподобаний вам алгоритм, який дає правильний результат; тут вас не відзначають ефективність.
  • Якщо ви можете довести, що існує безліч стійких до бітфліп складених номерів, то а) обмеження на вихідний формат зняті, і б) жорстке кодування списку буде дозволено (хоча, ймовірно, більш багатослівне, ніж просто його обчислення). Це правило здебільшого справедливе для повноти; Я не очікую, що це буде актуальним.

Стан перемоги

Це , так як зазвичай, коротше - краще. Також, як завжди, довжина програми буде вимірюватися в байтах.


"Програма або функція, яка приймає як вхідне негативне ціле число n і видає всі складені числа, стійкі до бітфліпу, менше n" - чи можу я включити, nякщо nстійкий до бітліпса? (тобто зробити його "меншим або рівним n"?)
JungHwan Min


2
Мені подобається, наскільки чіткими і ретельними є ваші характеристики
Луїс Мендо,

Зважаючи на те, що на початку говорили про стійкість до корупції, я подумав, що це буде ще одним майже неможливим випромінюванням проти радіації ...
ETHproductions

2
@ ais523 Це виглядатиме як порожня програма. Набір усіх порожніх програм.
mbomb007

Відповіді:


5

Желе , 20? 22 байти

BµJŒċ;0Ṭ^µḄµÆPoỊṀ¬
⁴Ç#

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

Виходить перше n таких чисел.

Можливо, балончик ;0може бути вилучений (без нього ми не перевіряємо, чи є саме число складеним - чи є праймес із усіма складеними бітами фліп?)

Зверніть увагу , що НЕ досить , щоб провести тест not(any(is prime))на безліч бітових-перевернуті числа. Ми також повинні перевірити, що 0немає в наборі.

Це тому 0, що не є простим і не складеним ( 1теж є, але дивіться нижче).

Необхідність перевірки на наявність 0може бути зрозуміла зустрічним прикладом:

  • 131136( 2 17 +2 6 ) має такий набір бітів:

[0, 64, 65, 66, 68, 72, 80, 96, 192, 320, 576, 1088, 2112, 4160, 8256, 16448, 32832, 65600, 131072, 131073, 131074, 131076, 131080, 131088, 131104, 131136, 131137, 131138, 131139, 131140, 131141, 131142, 131144, 131145, 131146, 131148, 131152, 131153, 131154, 131156, 131160, 131168, 131169, 131170, 131172, 131176, 131184, 131200, 131264, 131265, 131266, 131268, 131272, 131280, 131296, 131328, 131392, 131393, 131394, 131396, 131400, 131408, 131424, 131520, 131584, 131648, 131649, 131650, 131652, 131656, 131664, 131680, 131776, 131904, 132096, 132160, 132161, 132162, 132164, 132168, 132176, 132192, 132288, 132416, 132672, 133120, 133184, 133185, 133186, 133188, 133192, 133200, 133216, 133312, 133440, 133696, 134208, 135168, 135232, 135233, 135234, 135236, 135240, 135248, 135264, 135360, 135488, 135744, 136256, 137280, 139264, 139328, 139329, 139330, 139332, 139336, 139344, 139360, 139456, 139584, 139840, 140352, 141376, 143424, 147456, 147520, 147521, 147522, 147524, 147528, 147536, 147552, 147648, 147776, 148032, 148544, 149568, 151616, 155712, 163840, 163904, 163905, 163906, 163908, 163912, 163920, 163936, 164032, 164160, 164416, 164928, 165952, 168000, 172096, 180288, 196608, 196672, 196673, 196674, 196676, 196680, 196688, 196704, 196800, 196928, 197184, 197696, 198720, 200768, 204864, 213056, 229440]

Все це, крім 0композитних, ще 0не є простим.

1також є непростим і нескладеним і може з'являтися в наборі. Однак ми можемо, якщо хочемо, залишити це так, як ніби це складене:

  • всі вхідні дані менші або рівні 3(якщо вони взагалі розглядаються) містять у 0будь-якому випадку (насправді все менше, ніж 7робити).

  • щоб досягти 1одним бітним перевертанням, вихідне число повинно мати вигляд 2 k +2 0 , і якщо це більше 3, тобто k> 1 , ми можемо досягти 3, відкинувши k- біт і встановивши 1- біт ( 2 1 +2 0 = 3 ).

  • щоб досягти 1у двох бітних обертах, початкове число повинно мати форму 2 k, і якщо це більше, ніж 3ми можемо досягти 2на два обертання, і 2є простим.

Оскільки це коштує код обробка як 0і 1разом з використанням «нікчемний» атома .

Як?

⁴Ç# - Main link: n
⁴   - 16
  # - count up from 16 finding the first n matches of
 Ç  -     last link (1) as a monad

BµJŒċ;0Ṭ^µḄµÆPoỊṀ¬ - Link 1, test a number: i
B                  - convert to a binary list
 µ                 - start a new monadic chain
  J                - range(length): [1,2,...,nBits]
   Œċ              - pairs with replacement: [[1,1],[1,2],...,[1,nBits],[2,2],[2,3],...,[2,nBits],...,[nBits-1,nBits]]
     ;0            - concatenate a zero
       Ṭ           - untruth (makes lists with ones at those indexes - the [1,1], [2,2], etc make the one-flips, the zero makes the no-flip, the rest make the two-flips)
        ^          - exclusive or with the binary list version of i (flip the bits)
         µ         - start a new monadic chain
          Ḅ        - un-binary (get the integer values of each of the flipped versions)
           µ       - start a new monadic chain
            ÆP     - is prime? (make a list of 1s for primes and 0 for non-primes)
               Ị   - is insignificant (abs(v)<=1)
              o    - logical or (now we have true for any primes, 0 or 1 - hence non-composites)
                Ṁ  - maximum (1 if any non-composite was found)
                 ¬ - not (1 if all were composite)

Чи входить у ваш набір усі числа, які відрізняються щонайбільше на 2 біти? Якщо так, то в будь-якому випадку він перевірив би складність самого входу.
JungHwan Мін

Ні, саме тому ;0є - Œċотримує всі не упорядковані пари із заміною індексів ( J), так що для 84, що має 7 біт, це 28 (включаючи лайки [1,1] для одиночних бітів) "із замінною" частиною), а не 29 (плюс без змін).
Джонатан Аллан

Його можна зняти, якщо ми знаємо, що не існує прем'єра такого, що всі його кусані двоюрідні брати є складовими; але я не впевнений у цьому.
Джонатан Аллан

5

Брахілог , 32 38 байт

2<≜.¬(ḃ↰₂↰₂~ḃ≜{ṗ|ℕ<2}∧)
k~k|tgT∧?k↰:Tc

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

Це функція / предикат, ↰₀який повертає генератор, який генерує всі такі числа. (Посилання TIO друкує лише перший номер, щоб щось було помітно. Хоча запуск його локально дав багато інших.)

Тепер оновлено для обробки чисел, які знаходяться в межах двох біт-фліпків 0 або 1 (які не є простими і не складеними) правильно.

Пояснення

Довідковий предикат ↰₂ (повертає список, рівний вхідному, за винятком, можливо, одного елемента)

k~k|tgT∧?k↰:Tc
   |            Either:
 ~k               the output is produced by appending an arbitrary element
k                 to the input minus its last element
                Or:
        ?k        take the input minus its last element,
          ↰       call this predicate recursively on that,
      T    :Tc    then append
     g            the singleton list consisting of
    t             the last element of the input

Мені б подобалося, якби існував коротший спосіб зробити цю відносно просту рекурсію, але я не впевнений, що ще є; У специфікації є деякі перспективні особливості, але вони позначені як нереалізовані.

Основна програма ↰₀

2<≜.¬(ḃ↰₂↰₂~ḃ≜{ṗ|ℕ<2}∧)
2<≜                      For each integer greater than 2
   .                     generate it if
    ¬(                )  it does not have the following property:
      ḃ                  converting it to binary,
       ↰₂↰₂              running the helper predicate twice,
           ~ḃ            and converting back to decimal
             ≜           does not allow us to find a specific value
              {     }    that is:
               ṗ           prime;
                |        or:
                 ℕ<2       nonnegative and less than 2
                     ∧   (disable an unwanted implicit constraint)

4

JavaScript (ES6), 96 байт

Повна програма, яка підказує кількість відповідних цілих чисел та відображає їх по одному, використовуючи alert().

for(i=prompt(n=2);i;n+=2)(g=b=>b>n?alert(n,i--):(C=(n,x=n)=>n%--x?C(n,x):x>1)(n^b|1)&&g(b*2))(1)

Якщо ваш браузер не налаштований на використання оптимізації викликів Tail, це врешті-решт порушиться через переповнення рекурсії.

Нижче представлена ​​нерекурсивна версія (102 байти).

for(i=prompt(n=2);i;n+=2){for(c=b=1;b<n;b*=2,c&=C)for(C=k=2,x=n^b|1;k<x;k++)C|=!(x%k);c&&alert(n,i--)}

Припущення

Цей алгоритм спирається на припущення, що всі складові числа, стійкі до бітфліпу, парні. Це призводить до досить важливого спрощення: замість перегортання кожної можливої ​​пари бітів, ми лише гортаємо біт № 0 та ще один (або взагалі ніякий інший біт) і перевіряємо, чи всі отримані числа складаються.

Однак я не можу з’ясувати жодного очевидного доказу того, що непарне композитне число, стійке до бітліпсу, насправді не існує. Що стосується невеликих чисел (ніколи я не перевірив до 1 000 000), це здається, що ймовірність знайти його зменшується, оскільки кількість бітів збільшується (але це в основному лише моя інтуїція щодо цього).


3

Желе , 20 17 байт

BJŒċṬUḄ^;⁸ÆḍṂỊµÐḟ

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

Як це працює

BJŒċṬUḄ^;⁸ÆḍṂỊµÐḟ  Main link. Argument: n

              µ    Combine all links to the left into a chain.
               Ðḟ  Filter-false; keep only integers k from [1, ..., n] for which
                   the chain returns 0.
B                    Convert k to binary.
 J                   Get the indices of all digits.
  Œċ                 Take all combination of two indices, with replacement.
    Ṭ                Untruth; map each index pair [i, j] to the Boolean array of
                     length j that has 1's at (and only at) indices i and j.
     U               Upend; reverse each Boolean array.
      Ḅ              Unbinary; convert each array from base 2 to integer.
       ^             XOR the resulting numbers with k.
        ;⁸           Append k to the resulting list.
          Æḍ         Count the number of proper divisors of each result.
            Ṃ        Take the minimum.
             Ị       Insignificant; test if the minimum is 0 or 1.

1
Тепер мені цікаво, що це говорить про мене, що я зрозумів, як це працює, навіть не маючи пояснень (читаючи ваш вихідний код). Я вирішив це питання в Jelly, але не зайшов дуже далеко (тобто у мене було робоче рішення - саме це створило список тестових випадків - але це було явно занадто багатослівним). Чого мені не вистачало, це трюк: спершу скласти таблицю чисел - не-більше-двох-1-біт, а потім - XORing.

3

Python 2, 113 байт

r=range
lambda N:[n for n in r(1,N)if 1-any((bin(k).count('1')<3)*all((n^k)%q for q in r(2,n^k))for k in r(n+1))]

(Другий рядок - це неназвана функція, яка повертає список усіх складених номерів, стійких до бітфліпу, менших за вхід до функції.)

Синтаксис all(u%q for q in range(2,u))буде оцінювати, Trueколи він uє простим або меншим або рівним 2, і в іншому випадку оцінить до False. (Це вакуумно, Trueякщо uменше або дорівнює 2.)

Іншими словами, all(u%q for q in range(2,u))дорівнює, 0якщо і тільки якщоu є складовою.

Якщо вхід функції менше, ніж 2функція повертає порожній список (за бажанням). Тож припустимо, що вхід Nє принаймні 2, і припустимо 1 <= n < N. Для кожного kз 0наскрізних n(включно) код перевірятиме, чи nXOR'd kскладений, а також перевіряє, чи kмає 1у своєму бінарному поданні не більше двох . Якщо n^kскладений або kмає більше двох 1s, то він переходить до наступного значення k. Якщо він проникає через усі значення kз 0допомогою nцього шляху, то він включаєn до списку.

З іншого боку, якщо є значення kпринаймні двох 1таких, що n^kне є композитними, вони nне включаються до списку.


2

Perl 6 , 87 85 байт

{grep {!grep {$_%all 2..^$_},($_ X+^grep {.base(2)~~m:g/1/ <3},^(2+<.log(2)))},2..$_}

Повертає всі такі числа, менші або рівні вхідному номеру.

Як це працює

Для кожного числа n від 2 до входу воно робить наступне:

  1. ^ (2 + <.log (2))

    Створює всі невід’ємні цілі числа, які мають однакову або коротку бітну довжину, ніж n .

  2. grep {.base (2) ~~ m: g / 1 / <3},

    Номери фільтрів із цього списку, у яких встановлено менше трьох біт (використовуючи регулярний вираз).

  3. $ _ X + ^

    XOR ' n з кожним із цих чисел, даючи всі дійсні "мутації" з n .

  4. ! grep {$ _% всі 2 .. ^ $ _}

    Лише n може бути частиною списку вихідних даних, якщо жодна з мутацій не є композитною (перевіряється шляхом взяття кожної мутації x модуля на всезв'язок чисел між 2 і x -1).


2

Математика, 115 байт

1 4 байт збережено завдяки @MartinEnder

Cases[4~Range~#,x_/;And@@CompositeQ[Fold[#+##&]/@Select[{0,1}~Tuples~BitLength@x,Tr@Abs[#-x~IntegerDigits~2]<3&]]]&

(* or *)

(s=Select)[4~Range~#,xAnd@@CompositeQ[Fold[#+##&]/@s[{0,1}~Tuples~BitLength@x,Tr@Abs[#-x~IntegerDigits~2]<3&]]]&

Дуже неефективно, оскільки генерує всі числа до 2 ^ ceil (lg (n)).

Другий код використовує U + F4A1 ( Functionфункція)


1

Флороїд , 95 109 байт

Bj:[n KnIw(j)Fp(Cao(hm("".y(k)))Mhm("".y(k))>1KkIcd("10"*Z(hi(n)),Z(hi(n)))FT(a!=b Ka,bIq(hi(n),"".y(k)))<3)]

Повертає список номерів, стійких до бітліпу, до input - 1. Також обробляє різкі ситуації (0 і 1).

Флороїд - моя стара мова, якою я користувався лише пару разів. Довго не торкався його, отже, і розмір програми.

Перекладається на наступний код Python, який, на мою думку, може бути зменшений з рекурсією.

lambda j:[n for n in  range(j) if  all( not  functions.isPrime( functions.fromBinStr("".join(k))) and  functions.fromBinStr("".join(k))>1for k in  functions.combinations_with_replacement("10"*len( functions.pureBin(n)),len( functions.pureBin(n))) if sum (a!=b for a,b in  zip( functions.pureBin(n),"".join(k)))<3)]

Кожна функція, що використовується тут, заздалегідь визначена у Floroid. Ця сторінка містить усі функції та їх визначення.


Як зауваження: є деякі числа (0 і 1), які не є простими, але і не складені. Деякі рішення повинні були бути виправлені через це; Я підозрюю, що це теж буде.

@ ais523 Я насправді читав про це. Чи є ще відомий тестовий випадок для такого? У будь-якому разі я виправлю своє, оскільки це (мабуть) теж схильне до цього, дякую!
Yytsi

@TuukaX: 131136 має 0 як єдине некомпозитне значення, до якого можна дістатися за допомогою двох бітфліптів (а 0 не є простим). Дякуємо Джонатану Аллану за те, що його знайшли.

1

MATL , 30 28 27 26 байт

:GBnW:qtB!s3<)!Z~tZpw~+a~f

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

Виводить усі композитні номери, стійкі до бітфліпу, до (включаючи) n. Використовує ідеї з обох рішень Jelly - розглядає лише 0 як проблематичне, що не є простим; і генерує список номерів на відстані 2 спочатку, потім приймає xor.

Альтернативне рішення за допомогою циклу (30 байт):

:"@BnW:qt@Z~B!s3<)Zp1M~ha~?@D]

Виводить усі композитні номери, стійкі до бітфліпу, до (включаючи) n.


0

CJam , 34 33 байт

ri{_2b,,2\f#_m*::|0+f^:mp:+!},2>p

Обчислює всі стійкі до бітфліпу композити строго менше n .

Як і Джонатан Аллан, я не впевнений, чи дійсно потрібно перевірити наявність 0 бітфліпів. Якщо виявиться, що жодне просте число не має всіх своїх бітфліпів, то це призводить до складених чисел0+ можна буде видалити.

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

Пояснення

ri                                 Take an integer from input (n)
  {                                Filter out all numbers in the range 0...n-1 for which
                                    the following block is false
   _                                 Duplicate the number
    2b,                              Convert to binary, get the length
       ,                             Range from 0 to length-1
        2\f#                         Map each number in that range as a power of 2
                                      results in all powers of 2 less than or equal to n
            _m*                      Cartesian product with itself
               ::|                   Reduce each Cartesian pair with btiwse OR
                                      results in all numbers that have 1-2 1 bits in binary
                  0+                 Add 0 to that list
                    f^               Bitwise XOR the number we're checking with each of these
                                      This computes all the bitflips
                      :mp            Map each result to 0 if it's prime, 1 if it's composite
                         :+!         Take the sum of the list, check if it's 0
                                      If it is, then none of the results were prime
                            },     (end of filter block)
                              2>   Discard the first 2 numbers, since 0 and 1 always pass
                                p  Print the list nicely

0

MATL , 29 байт

Дякую Джонатану Аллану за виправлення.

q:Q"@BtnFTZ^=~!s3<fqt2>)Zp~?@

Це займає число n і видає всі складені числа, стійкі до бітфліпу, до n .

Як це працює

Спробуйте в MATL Online!

q:Q       % Input n implicitly. Push range [2 3 ... n]
"         % For each k in [2 3 ... n]
  @       %   Push k
  B       %   Convert to binary. Gives a row vector of zeros and ones, say v
  tn      %   Duplicate. Number of elements, say m
  FT      %   Push [0 1]
  Z^      %   Cartesian power of [0 1] raised to m. This gives a matrix,
          %   where each row is a binary number of length m
  =~      %   Compare with v, with broadcast
  !s      %   Sum of each row. Gives a row vector. This is the number of
          %   bit flips
  3<      %   True for numbers that are less than 3 bit flips away from k
  fq      %   Find their indices and subtract 1 to convert to decimal form.
          %   This gives a vector of numbers that are less than 3 bit flips
          %   away from k
  t2>)    %   Remove 0 or 1
  Zp~     %   Test each entry for non-primeness
?         % If all entries are true
  @       %   Push k
          % End (implicit)
          % Display stack (implicit)

@JonathanAllan Вирішено зараз. Знову дякую!
Луїс Мендо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.