Numeri compositi resistenti ai bitflip


26

A volte, quando si scrive un programma, è necessario utilizzare un numero primo per qualche motivo (ad esempio crittografia). Presumo che a volte sia necessario utilizzare anche un numero composto. A volte, almeno qui su PPCG, il tuo programma deve essere in grado di gestire modifiche arbitrarie. E in circostanze opportunamente inventate per fare un'interessante domanda PPCG, forse anche i numeri che stai usando devono essere resistenti alla corruzione ...

definizioni

Un numero composto è un numero intero ≥ 4 che non è un numero primo, ovvero è il prodotto di due numeri interi più piccoli maggiori di 1. Un numero composito resistente al ribaltamento è definito come segue: è un numero intero positivo composito per il quale, se lo scrivi in binario nel numero minimo possibile di bit, è possibile modificare uno o due bit dal numero e il numero è ancora composto.

Esempio

Ad esempio, considera il numero 84. In binario, questo è 1010100. Ecco tutti i numeri che differiscono di non più di 2 bit da quello:

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 prima colonna è il numero in binario; la seconda colonna è il numero in decimale. Come indica la terza colonna, tutti questi numeri sono compositi. In quanto tale, 84 è un numero composito resistente al ribaltamento dei bit.

L'obiettivo

Devi scrivere uno dei seguenti tre programmi o funzioni, a seconda di quale cosa abbia più senso per la tua lingua:

  • Un programma o una funzione che accetta un numero intero non negativo n come input e genera i primi n numeri compositi resistenti al bitflip.
  • Un programma o una funzione che accetta un numero intero non negativo n come input e genera tutti i numeri compositi resistenti al bitflip inferiori a n (o se si preferisce, minore o uguale a n , ovvero è possibile scegliere se n è incluso nell'output se bitflip -resistente).
  • Un programma o una funzione che non accetta input e genera tutti i numeri compositi resistenti al bitflip. (Questo deve usare un meccanismo di output in grado di produrre output mentre il programma è ancora in esecuzione, come la stampa su stdout, un elenco pigro o un generatore; non puoi semplicemente calcolare l'intero elenco e quindi stamparlo.)

Casi test

Ecco i primi numeri compositi resistenti ai bitflip:

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

chiarimenti

  • Sono solo i numeri che produci che devono essere resistenti alle cadute di bit. Questo non è un compito per rendere il programma che li trova resistenti alle cadute di bit; usa qualsiasi numero nel programma stesso che ti piace.
  • I numeri che emetti non devono essere resistenti a un bitflip negli "zero iniziali"; immagina che i numeri saranno memorizzati nel numero minimo possibile di bit e che solo quei bit devono essere immuni al ribaltamento. Tuttavia, i 1 bit iniziali sui numeri emessi devono essere immuni ai bitflip.
  • Utilizzare qualsiasi algoritmo che ti piace che produce il risultato giusto; qui non sei segnato sull'efficienza.
  • Se puoi provare che ci sono molti numeri compositi resistenti al bitflip, allora a) le restrizioni sul formato di output vengono aumentate e b) la codifica dura dell'elenco sarà consentita (anche se probabilmente più prolissa del semplice calcolo). Questa regola è principalmente solo per completezza; Non mi aspetto che sia rilevante.

Condizione di vittoria

Questo è , quindi come al solito, più corto è meglio. Inoltre, come al solito, la lunghezza del programma verrà misurata in byte.


"Un programma o una funzione che accetta un numero intero non negativo n come input e genera tutti i numeri compositi resistenti a bitflip inferiori a n" - posso includere nse nè resistente a bitflip? (ovvero renderlo "minore o uguale a n"?)
JungHwan Min


2
Mi piace quanto siano chiare e approfondite le tue specifiche di solito
Luis Mendo,

Con tutto quel discorso all'inizio sulla resistenza alla corruzione, ho pensato che sarebbe stata un'altra sfida quasi impossibile per l'indurimento delle radiazioni ...
ETHproductions

2
@ ais523 Sembrerebbe il programma vuoto. L'insieme di tutti i programmi vuoti.
mbomb007,

Risposte:


5

Jelly , 20 anni? 22 byte

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

Provalo online!

Produce i primi n numeri di questo tipo.

Forse il ;0può essere rimosso (senza di esso non controlliamo se il numero stesso è composito - ci sono numeri primi con tutti i compositi bit-flip?)

Si noti che è non è sufficiente per eseguire il test not(any(is prime))alla serie di numeri di bit-capovolto. Dobbiamo anche testare che 0non è nel set.

Questo perché 0non è primo e non composito (lo 1è anche, ma vedi sotto).

La necessità di verificare 0può essere vista da un contro-esempio:

  • 131136( 2 17 +2 6 ) ha il seguente set di bit-flip:

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

Tutto ciò, tranne che per il 0composito, non 0è tuttavia un numero primo.

1è anche non principale e non composito e potrebbe apparire nel set. Tuttavia, se vogliamo, possiamo lasciarlo come se fosse un composito:

  • tutti gli input inferiori o uguali a 3(se considerati affatto) contengono 0comunque un (in realtà tutti meno di 7do).

  • per raggiungere 1in un bit capovolgere il numero originale deve essere nella forma 2 k +2 0 , e se questo è maggiore di 3, cioè k> 1 , allora possiamo raggiungere 3lanciando il k -bit e impostando il 1- bit ( 2 1 +2 0 = 3 ).

  • per raggiungere 1in due lanci il numero originale deve essere nella forma 2 k e se questo è maggiore di quanto invece 3possiamo raggiungere 2in due lanci, ed 2è primo.

Allo stato attuale il codice gestisce entrambi 0e 1insieme usando l'atomo "insignificante" .

Come?

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

L'input è incluso nel tuo set di tutti i numeri che differiscono al massimo di 2 bit? In tal caso, verificherebbe comunque la composizione dell'input stesso.
JungHwan Min

No, ecco perché ;0c'è - Œċottiene tutte le coppie non ordinate con la sostituzione degli indici ( J), quindi per 84, che ha 7 bit che sono 28 (inclusi i like di [1,1] per i singoli bit-flip (dal parte "con sostituzione"), non 29 (più nessuna modifica).
Jonathan Allan,

Può essere rimosso se sappiamo che non esiste un numero primo tale che tutti i suoi cugini a punta di bit sono compositi; ma non ne sono sicuro.
Jonathan Allan,

5

Brachylog , 32 38 byte

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

Provalo online!

Questa è una funzione / predicato ↰₀che restituisce un generatore che genera tutti questi numeri. (Il collegamento TIO stampa solo il primo numero, in modo che qualcosa sia osservabile. Tuttavia, eseguirlo localmente ne ha prodotti molti altri).

Ora aggiornato per gestire correttamente i numeri che si trovano entro due bitflip di 0 o 1 (che non sono né primi né compositi).

Spiegazione

Predicato helper ↰₂ (restituisce un elenco uguale all'input, tranne forse per 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

Mi piacerebbe se ci fosse un modo più tero di fare questa ricorsione relativamente semplice, ma non sono sicuro che ci sia ancora; ci sono alcune caratteristiche dall'aspetto promettente nelle specifiche, ma sono contrassegnate come non implementate.

Programma principale ↰₀

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

Un programma completo che richiede il numero di numeri interi corrispondenti e li visualizza uno per 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 meno che il tuo browser non sia impostato per utilizzare l'ottimizzazione delle chiamate di coda, questo alla fine si interromperà a causa di un overflow di ricorsione.

Di seguito è una versione non ricorsiva (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--)}

Assunzione

Questo algoritmo si basa sul presupposto che tutti i numeri compositi resistenti al bitflip siano pari. Ciò porta a una semplificazione piuttosto importante: invece di capovolgere ogni possibile coppia di bit, capovolgiamo solo il bit # 0 e un altro (o nessun altro bit) e controlliamo che tutti i numeri risultanti siano compositi.

Tuttavia, non riesco a capire alcuna prova evidente che in realtà non esiste un numero composito bizzarro e resistente alle vibrazioni. Non succede mai per i piccoli numeri (ho controllato fino a 1.000.000), e sembra che la probabilità di trovarne uno diminuisca all'aumentare del numero di bit (ma questo è fondamentalmente solo la mia intuizione al riguardo).


3

Gelatina , 20 17 byte

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

Provalo online!

Come funziona

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
Ora mi chiedo cosa dice di me che ho capito come funziona anche senza alcuna spiegazione disponibile (leggendo il tuo codice sorgente). Ho provato questa domanda in Jelly, ma non sono andato molto lontano (cioè avevo una soluzione funzionante - è ciò che ha generato l'elenco dei casi di test - ma era chiaramente troppo prolisso). Quello che mi mancava era il trucco di produrre prima la tabella dei numeri con non più di due bit da 1 e poi XOR.

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

(La seconda riga è una funzione senza nome che restituisce un elenco di tutti i numeri compositi resistenti al bitflip che sono inferiori all'input della funzione.)

La sintassi all(u%q for q in range(2,u))valuterà Truequando uè primo o minore o uguale a 2, e altrimenti valuterà False. (È vagamente Truese uè inferiore o uguale a 2.)

In altre parole, all(u%q for q in range(2,u))è uguale a 0se e solo se uè composto.

Se l'ingresso della funzione è inferiore a 2, la funzione restituisce un elenco vuoto (come desiderato). Quindi supponiamo che l'input Nsia almeno 2, e supponiamo 1 <= n < N. Per ognuno kda 0attraverso n(incluso), il codice controllerà se nXOR'd kè composto e controlla anche se kha al massimo due 1nella sua rappresentazione binaria. Se n^kè composto o se kha più di due 1, passa al valore successivo di k. Se si arriva attraverso tutti i valori di kda 0tramite nin questo modo, allora include nnella lista.

D'altra parte, se esiste un valore di kal massimo di due 1che n^knon è composito, allora nnon è incluso nell'elenco.


2

Perl 6 , 87 85 byte

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

Restituisce tutti quei numeri che sono più piccoli o uguali al numero di input.

Come funziona

Per ogni numero n da 2 all'ingresso, procede come segue:

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

    Genera tutti i numeri interi non negativi con lunghezza bit uguale o inferiore a n .

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

    Filtra i numeri di questo elenco con meno di tre bit impostati (usando una regex).

  3. $ _ X + ^

    XOR è n con ciascuno di quei numeri, producendo tutte le "mutazioni" valide di n .

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

    N fa parte dell'elenco di output solo se nessuna delle mutazioni non è composita (verificata prendendo ciascuna mutazione x modulo una giunzione di numeri tra 2 e x -1).


2

Mathematica, 115 byte

1 4 byte salvati grazie 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&]]]&

Molto inefficiente perché genera tutti i numeri fino a 2 ^ ceil (lg (n)).

Il secondo codice utilizza U + F4A1 ( Functionfunzione)


1

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

Restituisce un elenco di numeri resistenti a errori di bit fino a input - 1. Gestisce anche le situazioni spigolose (0 e 1).

Floroid è una mia vecchia lingua, che ho usato solo un paio di volte. Non l'ho toccato per troppo tempo, quindi le dimensioni del programma.

Si traduce nel seguente codice Python, che penso possa essere ridotto con la ricorsione.

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

Ogni funzione usata qui è predefinita in Floroid. Questa pagina contiene tutte le funzioni e le loro definizioni.


Proprio come una nota: ci sono alcuni numeri (0 e 1) che non sono primi, ma nemmeno compositi. Alcune delle soluzioni hanno dovuto essere corrette a causa di ciò; Sospetto che anche questo lo farà.

@ ais523 In realtà ho letto su questo. Esiste ancora un caso di test noto per tale? Ad ogni modo, riparerò il mio, dato che è (probabilmente) incline anche a quello, grazie!
Yytsi,

@TuukaX: 131136 ha 0 come unico valore non composito che può essere raggiunto tramite due bitflip (e 0 non è primo). Grazie a Jonathan Allan per averlo trovato.

1

MATL , 30 28 27 26 byte

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

Provalo online!

Stampa in uscita tutti i numeri compositi resistenti al capovolgimento fino a (e inclusi) n. Utilizza idee di entrambe le soluzioni Jelly: considera 0 solo come problematico non-prime; e genera prima un elenco di numeri entro una distanza 2, quindi prende un xor.

Soluzione alternativa, tramite loop (30 byte):

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

Stampa in uscita tutti i numeri compositi resistenti al capovolgimento fino a (e inclusi) n.


0

CJam , 34 33 byte

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

Calcola tutti i compositi resistenti al bitflip rigorosamente inferiori a n .

Come Jonathan Allan, non sono sicuro che sia effettivamente necessario verificare la presenza di 0 bitflip. Se si scopre che nessun numero primo ha tutti i suoi bitflip, il risultato è numeri compositi, che 0+possono essere rimossi.

Provalo online!

Spiegazione

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

Grazie a Jonathan Allan per una correzione.

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

Questo richiede un numero n e genera tutti i numeri compositi resistenti al bitflip fino a n .

Come funziona

Provalo su 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 Risolto ora. Grazie ancora!
Luis Mendo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.