Números compuestos resistentes a Bitflip

26

A veces, al escribir un programa, debe usar un número primo por alguna razón u otra (por ejemplo, criptografía). Supongo que a veces, también necesitas usar un número compuesto. A veces, al menos aquí en PPCG, su programa tiene que poder manejar cambios arbitrarios. Y en circunstancias convenientemente diseñadas para hacer una pregunta interesante de PPCG, tal vez incluso los números que está usando tienen que ser resistentes a la corrupción ...

Definiciones

Un número compuesto es un número entero ≥ 4 que no es primo, es decir, es el producto de dos números enteros más pequeños mayores que 1. Un número compuesto resistente al bitflip se define de la siguiente manera: es un número entero compuesto positivo para el cual, si lo escribe en binario en el mínimo número posible de bits, puede cambiar uno o dos bits del número, y el número sigue siendo compuesto.

Ejemplo

Por ejemplo, considere el número 84. En binario, eso es 1010100. Aquí están todos los números que difieren en no más de 2 bits de eso:

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

La primera columna es el número en binario; La segunda columna es el número en decimal. Como indica la tercera columna, todos estos números son compuestos. Como tal, 84 es un número compuesto resistente a bitflip.

La tarea

Debe escribir uno de los siguientes tres programas o funciones, el que tenga más sentido para su idioma:

  • Un programa o función que toma un número entero no negativo n como entrada y emite los primeros n números compuestos resistentes a los cambios de bits.
  • Un programa o función que toma un número entero no negativo n como entrada, y genera todos los números compuestos resistentes a bitflip menores que n (o si lo prefiere, menor o igual que n , es decir, puede elegir si n está incluido en la salida si bitflip -resistente).
  • Un programa o función que no recibe entrada y genera todos los números compuestos resistentes a los cambios de bit (Esto debe usar un mecanismo de salida capaz de producir resultados mientras el programa aún se está ejecutando, como imprimir en stdout, una lista diferida o un generador; no puede calcular la lista completa y luego imprimirla).

Casos de prueba

Aquí están los primeros números compuestos resistentes a bitflip:

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

Aclaraciones

  • Son solo los números que produce los que tienen que ser resistentes a los bitflips. Esta no es una tarea para hacer que el programa los encuentre resistentes a los bitflips; use cualquier número en el programa que le guste.
  • Los números que genera no tienen que ser resistentes a un bitflip en los "ceros iniciales"; imagine que los números se almacenarán en el mínimo número posible de bits, y solo esos bits tienen que ser inmunes al volteo. Sin embargo, los 1 bits iniciales en los números que genera tienen que ser inmunes a los cambios de bits.
  • Use cualquier algoritmo que le guste que produzca el resultado correcto; No estás siendo marcado en eficiencia aquí.
  • Si puede probar que hay muchos números compuestos resistentes a los bitflip, entonces a) se levantan las restricciones en el formato de salida, yb) se permitirá codificar la lista (aunque probablemente sea más detallado que solo calcularlo). Esta regla es principalmente para completar; No espero que sea relevante.

Condición de victoria

Este es el , así que, como siempre, más corto es mejor También, como de costumbre, la longitud del programa se medirá en bytes.

boboquack
fuente
"Un programa o función que toma un número entero no negativo n como entrada y emite todos los números compuestos resistentes a los cambios de bits menores que n". ¿Puedo incluir nsi nes resistente a los cambios de bits? (es decir, ¿hacerlo "menor o igual que n"?)
JungHwan Min
Continuemos esta discusión en el chat .
Jonathan Allan
2
Me gusta lo claras y minuciosas que suelen ser tus especificaciones
Luis Mendo
Con todo lo que se decía al principio sobre ser resistente a la corrupción, pensé que este sería otro desafío casi imposible para endurecer la radiación ...
ETHproductions
2
@ ais523 Se vería como el programa vacío. El conjunto de todos los programas vacíos.
mbomb007

Respuestas:

5

Jalea , 20? 22 bytes

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

Pruébalo en línea!

Produce los primeros n de tales números.

Tal vez ;0se pueda eliminar (sin él no verificamos si el número en sí es compuesto, ¿hay algún primo con todos los cambios de bits compuestos?)

Tenga en cuenta que es no suficiente para realizar la prueba not(any(is prime))al conjunto de números de bit-volteado. También debemos probar que 0no está en el conjunto.

Esto se debe a 0que no es primo ni compuesto ( 1también lo es, pero vea a continuación).

La necesidad de verificar 0puede verse en un contraejemplo:

  • 131136( 2 17 +2 6 ) tiene el siguiente conjunto de cambios de bits:

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

Todos los cuales, excepto los 0compuestos, no 0son primos.

1también es no primo y no compuesto y podría aparecer en el conjunto. Sin embargo, si queremos, podemos dejar esto como si fuera un compuesto:

  • todas las entradas menores o iguales que 3(si se considera en absoluto) contienen un de 0todos modos (de hecho, todas menos que 7hacer).

  • para alcanzar 1en un bit, el número original debe tener la forma 2 k +2 0 , y si es mayor que 3, es decir, k> 1 , entonces podemos alcanzar 3cambiando el k- bit y estableciendo el 1- bit ( 2 1 +2 0 = 3 ).

  • para alcanzar los 1saltos de dos bits, el número original debe ser de la forma 2 k y, si es mayor de 3lo que podemos alcanzar, puede alcanzar 2dos saltos y 2es primo.

Tal y como está el código está manejando tanto 0y 1junto con el átomo de "insignificante", .

¿Cómo?

⁴Ç# - 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)
Jonathan Allan
fuente
¿La entrada está incluida en su conjunto de todos los números que difieren en un máximo de 2 bits? De ser así, comprobaría la composición de la entrada de todos modos.
JungHwan Min
No, es por eso que ;0está ahí: Œċobtiene todos los pares desordenados con el reemplazo de los índices ( J), por lo que para 84, que tiene 7 bits, es 28 (incluidos los gustos de [1,1] para los cambios de bits individuales (del parte "con reemplazo"), no 29 (más ningún cambio)
Jonathan Allan
Se puede eliminar si sabemos que no existe un primo, de modo que todos sus primos de bits son compuestos; pero no estoy seguro de ese hecho.
Jonathan Allan
5

Brachylog , 32 38 bytes

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

Pruébalo en línea!

Esta es una función / predicado ↰₀que devuelve un generador que genera todos esos números. (El enlace TIO solo imprime el primer número, para que algo sea observable. Sin embargo, ejecutarlo localmente ha producido muchos más).

Ahora actualizado para manejar números que están dentro de dos bits de bits de 0 o 1 (que no son primos ni compuestos) correctamente.

Explicación

Predicador auxiliar ↰₂ (devuelve una lista que es igual a la entrada, excepto tal vez un elemento)

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

Me encantaría si hubiera una manera más tersa de hacer esta recursión relativamente simple, pero no estoy seguro de que la haya todavía; Hay algunas características prometedoras en la especificación, pero están marcadas como no implementadas.

Programa principal ↰₀

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)

fuente
4

JavaScript (ES6), 96 bytes

Un programa completo que solicita la cantidad de enteros coincidentes y los muestra uno por uno, usando 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)

A menos que su navegador esté configurado para usar Tail Call Optimization, esto eventualmente se interrumpirá debido a un desbordamiento de recursividad.

A continuación se muestra una versión no recursiva (102 bytes).

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

Suposición

Este algoritmo se basa en la suposición de que todos los números compuestos resistentes a bitflip son pares. Esto lleva a una simplificación bastante importante: en lugar de voltear cada par de bits posible, solo volteamos el bit # 0 y otro (o ningún otro bit) y verificamos que todos los números resultantes sean compuestos.

Sin embargo, no puedo encontrar ninguna prueba obvia de que en realidad no exista un número compuesto resistente a los bitflip. Resulta que nunca es el caso para números pequeños (verifiqué hasta 1,000,000), y parece que la probabilidad de encontrar uno está disminuyendo a medida que aumenta el número de bits (pero esto es básicamente mi intuición al respecto).

Arnauld
fuente
3

Jalea , 20 17 bytes

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

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
1
Ahora me pregunto qué dice de mí que descubrí cómo funciona esto incluso sin una explicación disponible (a través de la lectura de su código fuente). Tuve una oportunidad con esta pregunta en Jelly, pero no llegué muy lejos (es decir, tenía una solución que funcionaba, es lo que generó la lista de casos de prueba, pero claramente era demasiado detallada). Lo que me faltaba era el truco de producir primero la tabla de números con no más de dos bits 1 y luego hacer un XOR.
3

Python 2, 113 bytes

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

(La segunda línea es una función sin nombre que devuelve una lista de todos los números compuestos resistentes a los bitflip que son menores que la entrada a la función).

La sintaxis all(u%q for q in range(2,u))evaluará a Truesiempre uque sea primo o menor o igual que 2, y de lo contrario evaluará a False. (Es por aspiración Truesi ues menor o igual que 2).

En otras palabras, all(u%q for q in range(2,u))es igual a 0si y solo si ues compuesto.

Si la entrada de la función es menor que 2, entonces la función devuelve una lista vacía (como se desee). Entonces suponga que la entrada Nes al menos 2, y suponga 1 <= n < N. Para cada uno kde a 0través n(incluido), el código verificará si nXOR'd con kes compuesto, y también verifica si ktiene como máximo dos 1en su representación binaria. Si n^kes compuesto, o si ktiene más de dos 1, entonces pasa al siguiente valor de k. Si se hace a través de todos los valores de ka 0través de nesta forma, entonces se incluye nen la lista.

Por otro lado, si hay un valor de kcomo máximo dos 1que n^kno es compuesto, entonces nno está incluido en la lista.

Mathmandan
fuente
2

Perl 6 , 87 85 bytes

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

Devuelve todos esos números que son más pequeños o iguales al número de entrada.

Cómo funciona

Para cada número n del 2 a la entrada, hace lo siguiente:

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

    Genera todos los enteros no negativos que tienen la misma longitud de bit o menor que n .

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

    Filtra los números de esta lista que tienen menos de tres bits establecidos (usando una expresión regular).

  3. $ _ X + ^

    XOR's n con cada uno de esos números, produciendo todas las "mutaciones" válidas de n .

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

    Solo permitamos que n forme parte de la lista de salida si ninguna de las mutaciones no es compuesta (se verifica tomando cada mutación x módulo una unión total de números entre 2 y x -1).

smls
fuente
2

Mathematica, 115 bytes

1 4 byte guardado gracias a @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&]]]&

Muy ineficiente porque genera todos los números hasta 2 ^ ceil (lg (n)).

El segundo código usa U + F4A1 ( Functionfunción)

JungHwan Min
fuente
1

Floroid , 95 109 bytes

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

Devuelve una lista de números resistentes a bitflip hasta input - 1. Maneja las situaciones nerviosas (0 y 1) también.

Floroid es un idioma antiguo que he usado solo un par de veces. No lo he tocado durante mucho tiempo, de ahí el tamaño del programa.

Se traduce al siguiente código de Python, que creo que podría reducirse con recursividad.

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

Cada función utilizada aquí está predefinida en Floroid. Esta página contiene todas las funciones y sus definiciones.

Yytsi
fuente
Solo como una nota: hay algunos números (0 y 1) que no son primos, pero tampoco son compuestos. Algunas de las soluciones han tenido que corregirse debido a eso; Sospecho que este también lo hará.
@ ais523 En realidad leí sobre eso. ¿Hay algún caso de prueba conocido para tal? De todos modos, arreglaré el mío, ya que es (probablemente) propenso a eso también, gracias
Yytsi
@TuukaX: 131136 tiene 0 como el único valor no compuesto que se puede alcanzar a través de dos bitflips (y 0 no es primo). Gracias a JonathanAllan por encontrarlo.
1

MATL , 30 28 27 26 bytes

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

Pruébalo en línea!

Emite todos los números compuestos resistentes a los cambios de bits hasta (e incluidos) n. Utiliza ideas de ambas soluciones Jelly: solo considera 0 como un problema no primo problemático; y genera una lista de números dentro de una distancia 2 primero, luego toma un xor.

Solución alternativa, por bucle (30 bytes):

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

Emite todos los números compuestos resistentes a los cambios de bits hasta (e incluidos) n.

B. Mehta
fuente
0

CJam , 34 33 bytes

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

Calcula todos los compuestos resistentes a los bitflip estrictamente menores que n .

Al igual que Jonathan Allan, no estoy seguro de si es realmente necesario verificar 0 bitflips. Si resulta que ningún número primo tiene todos sus resultados de bitflips en números compuestos, 0+se puede eliminar.

Pruébalo en línea!

Explicación

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
Gato de negocios
fuente
0

MATL , 29 bytes

Gracias a Jonathan Allan por una corrección.

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

Esto toma un número n y genera todos los números compuestos resistentes a los cambios de bits hasta n .

Cómo funciona

¡Pruébalo en 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)
Luis Mendo
fuente
@JonathanAllan Resuelto ahora. ¡Gracias de nuevo!
Luis Mendo