Nomor komposit tahan-bitflip


26

Kadang-kadang, ketika menulis sebuah program, Anda perlu menggunakan bilangan prima karena alasan tertentu (misalnya kriptografi). Saya berasumsi bahwa kadang-kadang, Anda perlu menggunakan nomor komposit juga. Terkadang, setidaknya di sini di PPCG, program Anda harus dapat menangani perubahan yang sewenang-wenang. Dan dalam keadaan yang dibuat dengan mudah untuk membuat pertanyaan PPCG yang menarik, mungkin bahkan angka yang Anda gunakan harus tahan terhadap korupsi ...

Definisi

Bilangan komposit adalah bilangan bulat ≥ 4 yang bukan bilangan prima, yaitu bilangan bulat yang lebih besar dari 1. Bilangan komposit tahan bitflip didefinisikan sebagai berikut: bilangan bulat positif komposit, yang jika Anda menulisnya dalam biner dalam jumlah bit minimum yang mungkin, Anda dapat mengubah satu atau dua bit dari angka tersebut, dan jumlahnya masih berupa gabungan.

Contoh

Sebagai contoh, perhatikan angka 84. Dalam biner, itu 1010100. Berikut adalah semua angka yang berbeda tidak lebih dari 2 bit dari itu:

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

Kolom pertama adalah angka dalam biner; kolom kedua adalah angka dalam desimal. Seperti yang ditunjukkan kolom ketiga, semua angka ini adalah gabungan. Dengan demikian, 84 adalah nomor komposit tahan-bitflip.

Tugas

Anda harus menulis salah satu dari tiga program atau fungsi berikut, yang mana yang paling masuk akal untuk bahasa Anda:

  • Suatu program atau fungsi yang mengambil bilangan bulat n negatif sebagai input, dan mengeluarkan bilangan komposit n bitflip-tahan pertama.
  • Sebuah program atau fungsi yang mengambil bilangan bulat positif n sebagai input, dan output semua nomor komposit bitflip tahan kurang dari n (atau jika Anda suka, kurang dari atau sama dengan n , yaitu Anda dapat memilih apakah n termasuk dalam output jika bitflip -tahan).
  • Program atau fungsi yang tidak mengambil input, dan mengeluarkan semua nomor komposit yang tahan-bitflip. (Ini harus menggunakan mekanisme output yang mampu menghasilkan output saat program masih berjalan, seperti mencetak ke stdout, daftar malas, atau generator; Anda tidak bisa hanya menghitung seluruh daftar dan kemudian mencetaknya.)

Uji kasus

Berikut adalah beberapa angka komposit tahan-bitflip pertama:

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

Klarifikasi

  • Hanya angka yang Anda hasilkan yang harus tahan terhadap bitflips. Ini bukan tugas membuat program yang tahan terhadap bitflips; gunakan angka apa pun dalam program itu sendiri yang Anda sukai.
  • Angka yang Anda hasilkan tidak harus tahan terhadap bitflip di "nol terkemuka"; bayangkan bahwa jumlahnya akan disimpan dalam jumlah bit minimum yang mungkin, dan hanya bit-bit itu yang harus kebal terhadap flipping. Namun, 1 bit awal pada angka yang Anda hasilkan harus kebal terhadap bitflips.
  • Gunakan algoritma apa pun yang Anda suka yang menghasilkan hasil yang tepat; Anda tidak ditandai dengan efisiensi di sini.
  • Jika Anda dapat membuktikan bahwa ada banyak angka komposit tahan-bitflip, maka a) pembatasan format output dicabut, dan b) pengodean daftar akan diizinkan (walaupun mungkin lebih bertele-tele daripada hanya menghitungnya). Aturan ini sebagian besar hanya untuk kelengkapan; Saya tidak berharap itu relevan.

Kondisi kemenangan

Ini , jadi seperti biasa, lebih pendek lebih baik. Juga seperti biasa, panjang program akan diukur dalam byte.


"Suatu program atau fungsi yang mengambil bilangan bulat nonnegatif sebagai input, dan mengeluarkan semua angka komposit yang tahan bitflip kurang dari n" - dapatkah saya memasukkan njika ntahan bitflip? (yaitu membuatnya "kurang dari atau sama dengan n"?)
JungHwan Min


2
Saya suka betapa jelas dan menyeluruhnya spesifikasi Anda
Luis Mendo

Dengan semua pembicaraan di awal tentang tahan terhadap korupsi, saya pikir ini akan menjadi tantangan pengerasan radiasi yang hampir mustahil ...
ETHproduksi

2
@ ais523 Ini akan terlihat seperti program kosong. Himpunan semua program kosong.
mbomb007

Jawaban:


5

Jelly , 20? 22 byte

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

Cobalah online!

Menghasilkan angka pertama n tersebut .

Mungkin ;0dapat dihapus (tanpanya kita tidak memeriksa apakah nomor itu sendiri komposit - apakah ada bilangan prima dengan semua bit-flips komposit?)

Perhatikan bahwa tidak cukup untuk melakukan tes not(any(is prime))ke set angka bit-membalik. Kita juga harus menguji yang 0tidak di set.

Ini karena 0tidak prima dan bukan komposit ( 1juga, tapi lihat di bawah).

Kebutuhan untuk memeriksa 0dapat dilihat oleh contoh tandingan:

  • 131136( 2 17 +2 6 ) memiliki set bit-flip berikut:

[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]

Semuanya, kecuali 0komposit, namun 0tidak prima.

1juga non-prime dan non-komposit dan bisa muncul di set. Namun kita dapat, jika kita mau, membiarkan ini seolah-olah itu adalah gabungan:

  • semua input kurang dari atau sama dengan 3(jika dianggap sama sekali) mengandung 0pula (sebenarnya semua kurang dari yang 7dilakukan).

  • untuk mencapai 1dalam satu bit flip nomor aslinya harus dalam bentuk 2 k +2 0 , dan jika ini lebih besar dari 3, yaitu k> 1 , maka kita dapat mencapai 3dengan membalik k- bit dan mengatur 1- bit ( 2 1 +2 0 = 3 ).

  • untuk mencapai 1dalam dua bit membalik angka asli harus dalam bentuk 2 k dan jika ini lebih besar dari yang 3bisa kita raih 2dalam dua flip, dan 2merupakan bilangan prima.

Seperti berdiri kode menangani keduanya 0dan 1bersama - sama menggunakan "tidak signifikan" atom ,.

Bagaimana?

⁴Ç# - 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)

Apakah input termasuk dalam set Anda dari semua angka yang paling banyak berbeda 2 bit? Jika demikian, itu akan memeriksa kekompakan input itu sendiri.
JungHwan Min

Tidak, itu sebabnya ;0ada - Œċdapatkan semua pasangan unordered dengan penggantian indeks ( J), jadi untuk 84, yang memiliki 7 bit itu 28 (termasuk suka [1,1] untuk bit-flips tunggal (dari bagian "dengan penggantian"), bukan 29 (ditambah tanpa perubahan)
Jonathan Allan

Itu bisa dihilangkan jika kita tahu bahwa tidak ada bilangan prima yang ada sehingga semua sepupu yang dibalik itu komposit; tapi saya tidak yakin dengan fakta itu.
Jonathan Allan

5

Brachylog , 32 38 byte

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

Cobalah online!

Ini adalah fungsi / predikat ↰₀yang mengembalikan generator yang menghasilkan semua angka tersebut. (TIO link hanya mencetak angka pertama, sehingga sesuatu dapat diamati. Menjalankannya secara lokal telah menghasilkan lebih banyak.)

Sekarang diperbarui untuk menangani angka yang berada dalam dua bit dari 0 atau 1 (yang tidak prima atau komposit) dengan benar.

Penjelasan

Predikat helper ↰₂ (mengembalikan daftar yang sama dengan input, kecuali mungkin satu elemen)

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

Saya akan senang jika ada cara terser untuk melakukan rekursi yang relatif sederhana ini, tapi saya belum yakin; ada beberapa fitur yang tampak menjanjikan dalam spesifikasi, tetapi ditandai sebagai tidak diterapkan.

Program utama ↰₀

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 byte

Program lengkap yang meminta jumlah bilangan bulat yang cocok dan menampilkannya satu per satu, menggunakan 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)

Kecuali jika browser Anda diatur untuk menggunakan Tail Call Optimization, ini pada akhirnya akan rusak karena limpahan rekursi.

Di bawah ini adalah versi non-rekursif (102 byte).

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

Anggapan

Algoritma ini bergantung pada asumsi bahwa semua angka komposit yang tahan bitflip adalah genap. Ini mengarah ke penyederhanaan yang agak penting: alih-alih membalik setiap pasangan bit yang mungkin, kami hanya membalik bit # 0 dan yang lainnya (atau tidak ada bit sama sekali) dan memeriksa bahwa semua angka yang dihasilkan adalah komposit.

Namun, saya tidak dapat menemukan bukti yang jelas bahwa nomor komposit tahan bitflip aneh tidak benar-benar ada. Kebetulan tidak pernah terjadi untuk jumlah kecil (saya memeriksa hingga 1.000.000), dan sepertinya probabilitas menemukan satu menurun karena jumlah bit meningkat (tetapi ini pada dasarnya hanya intuisi saya tentang hal itu).


3

Jelly , 20 17 byte

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

Cobalah online!

Bagaimana itu bekerja

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
Sekarang saya bertanya-tanya apa yang dikatakan tentang saya bahwa saya menemukan cara kerjanya bahkan tanpa penjelasan yang tersedia (dengan membaca kode sumber Anda). Saya mencoba pertanyaan ini di Jelly, tetapi tidak terlalu jauh (yaitu saya punya solusi yang berfungsi - itu yang membuat daftar kasus uji - tapi jelas terlalu bertele-tele). Apa yang saya lewatkan adalah trik menghasilkan tabel angka-dengan-tidak-lebih-dari-dua-1-bit pertama, dan kemudian XORing itu.

3

Python 2, 113 byte

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

(Baris kedua adalah fungsi tanpa nama yang mengembalikan daftar semua angka komposit tahan-bitflip yang kurang dari input ke fungsi.)

Sintaks all(u%q for q in range(2,u))akan mengevaluasi Truekapan pun uprima atau kurang dari atau sama dengan 2, dan sebaliknya akan dievaluasi False. (Kosong Truejika ukurang dari atau sama dengan 2.)

Dengan kata lain, all(u%q for q in range(2,u))sama dengan 0if dan only if uis composite.

Jika input fungsi kurang dari 2, maka fungsi mengembalikan daftar kosong (seperti yang diinginkan). Jadi asumsikan input Npaling tidak 2, dan anggaplah 1 <= n < N. Untuk masing-masing kdari 0hingga n(termasuk), kode akan memeriksa apakah nXOR dengan kkomposit, dan juga memeriksa apakah kmemiliki paling tidak dua 1dalam representasi binernya. Jika n^kkomposit, atau jika kmemiliki lebih dari dua 1, maka itu bergerak ke nilai berikutnya k. Jika melewati semua nilai kdari 0melalui ncara ini, maka itu termasuk ndalam daftar.

Di sisi lain, jika ada nilai kdengan paling banyak dua 1sehingga n^ktidak komposit, maka ntidak termasuk dalam daftar.


2

Perl 6 , 87 85 byte

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

Mengembalikan semua angka yang lebih kecil atau sama dengan angka input.

Bagaimana itu bekerja

Untuk setiap angka n dari 2 hingga input, ia melakukan yang berikut:

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

    Menghasilkan semua bilangan bulat non-negatif yang memiliki panjang bit yang sama atau lebih pendek dari n .

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

    Memfilter angka dari daftar ini yang memiliki kurang dari tiga bit yang ditetapkan (menggunakan regex).

  3. $ _ X + ^

    XOR n dengan masing-masing angka itu, menghasilkan semua "mutasi" yang valid dari n .

  4. ! grep {$ _% semua 2 .. ^ $ _}

    Hanya membiarkan n menjadi bagian dari daftar output jika tidak ada mutasi yang non-komposit (diperiksa dengan mengambil masing-masing mutasi x modulo semua-Persilangan angka antara 2 dan x -1).


2

Mathematica, 115 byte

1 4 byte disimpan berkat @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&]]]&

Sangat tidak efisien karena menghasilkan semua angka hingga 2 ^ ceil (lg (n)).

Kode kedua menggunakan U + F4A1 ( Functionfungsi)


1

Floroid , 95 109 byte

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

Mengembalikan daftar nomor yang tahan bitflip hingga input - 1. Menangani situasi tegang (0 dan 1) juga.

Floroid adalah bahasa lama saya, yang hanya saya gunakan beberapa kali. Belum menyentuhnya untuk waktu yang lama, maka ukuran program.

Diterjemahkan ke kode Python berikut, yang saya pikir dapat dikurangi dengan rekursi.

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

Setiap fungsi yang digunakan di sini sudah ditentukan sebelumnya dalam Floroid. Halaman ini berisi semua fungsi dan definisinya.


Sama seperti catatan: ada beberapa angka (0 dan 1) yang tidak prima, tetapi juga tidak komposit. Beberapa solusi harus diperbaiki karena itu; Saya menduga ini juga akan.

@ ais523 Saya benar-benar membaca tentang itu. Apakah ada test case yang dikenal untuk itu? Ngomong-ngomong, saya akan perbaiki milik saya, karena itu (mungkin) rawan juga, terima kasih!
Yytsi

@ TuukaX: 131136 memiliki 0 sebagai satu-satunya nilai non-komposit yang dapat dicapai melalui dua bitflips (dan 0 bukan prima). Terima kasih kepada Jonathan Allan untuk menemukannya.

1

MATL , 30 28 27 26 byte

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

Cobalah online!

Menghasilkan semua angka komposit tahan-bitflip hingga (dan termasuk) n. Menggunakan gagasan dari kedua solusi Jelly - hanya menganggap 0 sebagai masalah non-prima; dan menghasilkan daftar angka dalam jarak 2 terlebih dahulu, kemudian mengambil xor.

Solusi alternatif, dengan mengulang (30 byte):

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

Menghasilkan semua angka komposit tahan-bitflip hingga (dan termasuk) n.


0

CJam , 34 33 byte

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

Hitung semua komposit yang tahan bitflip secara ketat kurang dari n .

Seperti Jonathan Allan, saya tidak yakin apakah itu benar-benar perlu untuk memeriksa 0 bitflips. Jika ternyata tidak ada bilangan prima yang memiliki semua bitflipsnya menghasilkan bilangan komposit, maka 0+dapat dihilangkan.

Cobalah online!

Penjelasan

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 byte

Terima kasih kepada Jonathan Allan untuk koreksi.

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

Ini membutuhkan angka n dan menghasilkan semua angka komposit tahan-bitflip hingga n .

Bagaimana itu bekerja

Cobalah di 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 Dipecahkan sekarang. Terima kasih lagi!
Luis Mendo
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.