Il più piccolo moltiplicatore che rivela un fattore di semiprime


16

Dato un semiprime N , trova il numero intero positivo più piccolo m tale che la rappresentazione binaria di uno dei due fattori di N possa essere trovata nella rappresentazione binaria di N * m .

Esempio

Consideriamo il semiprime N = 9799 .

Proviamo diversi valori di m , iniziando da 1:

 m |  N * m |   N * m in binary
---+--------+------------------
 1 |   9799 |    10011001000111
 2 |  19598 |   100110010001110
 3 |  29397 |   111001011010101
 4 |  39196 |  1001100100011100
 5 |  48995 |  1011111101100011
 6 |  58794 |  1110010110101010
 7 |  68593 | 10000101111110001
 8 |  78392 | 10011001000111000
 9 |  88191 | 10101100001111111
10 |  97990 | 10111111011000110
11 | 107789 | 11010010100001101

Ci fermiamo qui perché la rappresentazione binaria dell'ultimo prodotto contiene 101001quale è la rappresentazione binaria di 41 , uno dei due fattori di 9799 (l'altro è 239 ).

esempio

Quindi la risposta sarebbe 11 .

Regole e note

  • Cercare valori pari di m non ha senso. Sono stati mostrati nell'esempio sopra per completezza.
  • Il tuo programma deve supportare qualsiasi N per cui N * m rientri nelle capacità di calcolo della tua lingua.
  • Hai il permesso di fattorizzare N anticipo piuttosto che cercare ogni possibile sottostringa della rappresentazione binaria di N * m per vedere se si scopre di essere un fattore di N .
  • Come dimostrato da MitchellSpector , m esiste sempre.
  • Questo è code-golf, quindi vince la risposta più breve in byte. Sono vietate le scappatoie standard.

Casi test

La prima colonna è l'input. La seconda colonna è l'output previsto.

         N |    m |         N * m |                              N * m in binary | Factor
-----------+------+---------------+----------------------------------------------+-------
         9 |    3 |            27 |                                      [11]011 |      3
        15 |    1 |            15 |                                       [11]11 |      3
        49 |    5 |           245 |                                   [111]10101 |      7
        91 |    1 |            91 |                                    10[1101]1 |     13
       961 |   17 |         16337 |                             [11111]111010001 |     31
      1829 |    5 |          9145 |                             1000[111011]1001 |     59
      9799 |   11 |        107789 |                          1[101001]0100001101 |     41
     19951 |   41 |        817991 |                       1[1000111]101101000111 |     71
    120797 |   27 |       3261519 |                     11000[1110001]0001001111 |    113
   1720861 |  121 |     208224181 |               11000110100[100111111101]10101 |   2557
 444309323 |  743 |  330121826989 |    100110011011100110010[1101010010101011]01 |  54443
 840000701 | 4515 | 3792603165015 | 11011100110000[1000110000111011]000101010111 |  35899
1468255967 |   55 |   80754078185 |      1001011001101010100010[1110001111]01001 |    911

Sento un algoritmo simile a quelli che abbiamo usato per la sfida della sequenza del Blackjack ...
ETHproductions

@ETHproductions Hmm, davvero? Onestamente dovrebbero essere completamente indipendenti.
Arnauld,

Bene, sono principalmente simili in quanto è necessario controllare ogni sottostringa contigua per una proprietà specifica. A parte questo, sono davvero indipendenti.
ETHproductions

"e probabilmente incoraggiato" - Mi dispiace. Non ci interessa la velocità del nostro codice.
John Dvorak,

@JanDvorak Abbastanza giusto. Rimosso.
Arnauld,

Risposte:


6

Pyth, 13 byte

ff}.BY.B*TQPQ

Dimostrazione

Spiegazione:

ff}.BY.B*TQPQ
f                Find the first integer >= to 1 where the following is true
 f         PQ    Filter the prime factors of the input
        *TQ      Multiply the input by the outer integer
      .B         Convert to a binary string
   .BY           Convert the prime factor to a binary string
  }              Check whether the factor string is in the multiple string.

6

05AB1E , 18 16 15 byte

-2 byte grazie a Riley!

-1 byte grazie a Emigna!

[N¹*b¹Ñ¦¨båOiNq

Spiegazione:

[                   # Infinite loop start
 N                  # Push the amount of times we have iterated
  ¹*               # Multiplied by input
    b              # Convert to binary
     ¹Ñ¦¨b         # Calculate the proper divisors of the input in binary excluding one
          åO       # Check if a substring of N * m in binary is in the divisors
            iNq    # If so, print how many times we have iterated and terminate the program

Provalo online!


¹Ñ¦¨båOdovrebbe funzionare invece di controllare ogni sottostringa.
Riley,

@Riley grazie per averlo individuato!
Okx,

2
È possibile salvare un altro byte sostituendo ¼e ¾con N.
Emigna,

@Emigna Non sapevo di quel trucco, grazie!
Okx,

4

JavaScript (ES6), 96 95 80 byte

n=>F=m=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:F(-~m)

Una funzione che restituisce una funzione ricorsiva che utilizza una funzione ricorsiva che utilizza una funzione ricorsiva. Sto davvero iniziando a chiedermi se il .toString(2)percorso sarebbe più breve ...

Assegnare ad un esempio variabili f=n=>...e chiamata con un paio di parentesi, f(9)(). Se ciò non è consentito (il meta post è a + 6 / -2), puoi utilizzare questa versione da 83 byte con invocazione standard:

f=(n,m)=>(k=p=>p&&(q=1,g=x=>1<x&&x<n&n%x<1|g(x>>1,q*=2))(p)|k(p-q))(n*m)?m:f(n,-~m)

Entrambe le versioni funzionano per tutti tranne gli ultimi tre casi di test. Puoi provare anche questi casi di test cambiando x>>1in (x-x%2)/2.


Non sono sicuro che ci sia davvero un consenso al riguardo (siamo al + 6 / -2 al momento della pubblicazione), ma per quanto mi riguarda, il primo formato di input va bene.
Arnauld,

3

Utilità Bash + Unix, 85 84 byte

for((;;m++)){ dc -e2o$[$1*m]n|egrep -q $(dc "-e2o`factor $1`nBEPn")&&break;}
echo $m

Provalo online!


Sottolineerò anche che m esiste sempre per qualsiasi semiprime n. Ecco perché:

Scrivi n = pq, dove p e q sono primi e p <= q.

Sia b il numero di cifre nella rappresentazione binaria di n-1. Quindi, per qualsiasi k compreso tra 0 e n-1 compreso, p * (2 ^ b) + k in binario consiste nella rappresentazione binaria di p seguita da b bit aggiuntivi che rappresentano k.

Quindi i numeri p * (2 ^ b) + k per 0 <= k <= n-1, quando scritti in binario, iniziano tutti con la rappresentazione binaria di p. Ma questi sono n numeri consecutivi, quindi uno di essi deve essere un multiplo di n.

Ne segue che abbiamo un mn multiplo di n la cui rappresentazione binaria inizia con la rappresentazione binaria di p.

Sulla base di questo, si può trovare un limite superiore per m di 2 sqrt (n). (Probabilmente si può ottenere un limite superiore molto più stretto di così.)


2

Haskell, 161 byte

import Data.List
(!)=mod
a#b|a!b==0=b|0<1=a#(b+1)
g 0=[]
g n=g(n`div`2)++show(n!2)
(a%b)c|g b`isInfixOf`g(a*c)=c|0<1=a%b$c+1
f n=min(n%(n#2)$1)$n%(n`div`(n#2))$1

Controllo diretto. Prima fattore, quindi cerca linearmente a partire da 1 e prendi il minimo del valore per entrambi i fattori.

Richiede alcuni secondi per l'ultimo testcase ( 1468255967), ghciriporta (15.34 secs, 18,610,214,160 bytes)sul mio laptop.


2

Mathematica, 83 byte

1//.x_/;FreeQ[Fold[#+##&]/@Subsequences@IntegerDigits[x#,2],d_/;1<d<#&&d∣#]:>x+1&

2

Brachylog (2), 14 byte

ḋḃᵐD∧?:.×ḃs∈D∧

Provalo online!

C'è più di un modo per scrivere questo in 14 byte in Brachylog, quindi sono andato per il più efficiente. Come è comune per l'invio di Brachylog, si tratta di un'invio di funzioni; il suo input è il semiprime, il suo output è il moltiplicatore.

Spiegazione

ḋḃᵐD∧?:.×ḃs∈D∧
ḋ               Prime decomposition (finds the two prime factors)
 ḃᵐ             Convert each factor to binary
   D            Name this value as D
    ∧?          Restart with the user input
      :.×       The output is something that can be multiplied by it
         ḃ      to produce a number which, when expressed in binary
          s     has a substring
           ∈D   that is an element of D
             ∧  (suppress an implicit constraint that D is the output; it isn't)

L'ordine di valutazione di Prolog e Brachylog è impostato dal primo vincolo che non può essere immediatamente dedotto dall'input. In questo programma, questo è un vincolo al risultato di una moltiplicazione, quindi l'interprete mirerà a mantenere gli operandi della moltiplicazione il più vicino possibile a 0. Conosciamo uno degli operandi e l'altro è l'output, quindi troviamo l'output più piccolo possibile, che è esattamente quello che vogliamo.


1

PowerShell , 136 byte

param($n)$a=2..($n-1)|?{!($n%$_)}|%{[convert]::ToString($_,2)};for(){$b=[convert]::toString(++$m*$n,2);if($a|?{$b-like"*$_*"}){$m;exit}}

Provalo online!

Molto lungo a causa del funzionamento della conversione in binario in PowerShell. : - /

Riceve l'input $n, una legatura 2a $n-1ed estrae i fattori !($n%$_). Invia quelli in un ciclo |%{...}e convertciascuno di essi su una 2stringa binaria (base ). Memorizza le stringhe binarie in $a.

Quindi entriamo in un for(){...}ciclo infinito . Ogni iterazione, incrementiamo ++$m, moltipliciamo quella per $ne convertquella in una stringa binaria, memorizzata in $b. Quindi, ifquella stringa è regex -likequalsiasi stringa in $a, abbiamo output $me exit.


0

Perl 6 , 66 byte

->\n{first {(n*$_).base(2)~~/@(grep(n%%*,2..^n)».base(2))/},^∞}

Regex-based.

Super slow, perché bruta di nuovo i fattori di n in ogni posizione di regex match di ogni numero che viene provato.

Calcolare i fattori una sola volta, migliora le prestazioni ma lo rende 72 byte:

->\n{my @f=grep(n%%*,2..^n)».base(2);first {(n*$_).base(2)~~/@f/},^∞}
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.