Fattorizzazione parziale di un numero intero positivo


23

Una raccolta di numeri interi positivi d_1 d_2 ... d_kè una fattorizzazione di un numero intero positivo nse

d_1 * d_2 * ... * d_k = n

Ogni numero intero positivo ha una fattorizzazione primaria unica , ma in generale ha anche fattori in cui alcuni termini sono composti. Per esempio

12 = 6 * 2 = 4 * 3 = 3 * 2 * 2

Scrivi un programma, una funzione, un verbo o simile che accetta come input un singolo intero positivo e restituisce o stampa un elenco completo delle sue distinte fattorizzazioni. Le fattorizzazioni possono essere prodotte in qualsiasi ordine e i loro termini possono essere in qualsiasi ordine, ma non due dovrebbero essere permutazioni l'una dell'altra. Le fattorizzazioni potrebbero non includere 1due eccezioni: per input nsi può dare la fattorizzazione n*1invece di n; e per input 1puoi dare la fattorizzazione 1invece dell'elenco vuoto.

Si può presumere che l'ingresso sarà compreso nell'intervallo di un numero intero a 32 bit con segno. Se l'output è una stringa, dovrebbe esserci una chiara distinzione tra la delimitazione dei numeri all'interno di una fattorizzazione e la delimitazione delle fattorizzazioni, ma non è necessario (ad esempio) che i fattori siano uniti a un *.

Il tuo codice dovrebbe essere in grado di gestire qualsiasi input valido entro 10 minuti su una macchina desktop ragionevole.

Esempi

1                  [[]]
                or [[1]]
                or [[1 1]]

7                  [[7]]
                or [[7 1]]
                or [[1 7]]

12                 [[12] [6 2] [4 3] [2 3 2]]
                or variants

16                 [[2 2 2 2] [2 2 4] [2 8] [4 4] [16]]
                or variants

901800900          a list of 198091 factorisations

1338557220         a list of 246218 factorisations

Puoi pubblicare l'elenco delle fattorizzazioni 901800900e 1338557220da qualche parte dove possiamo verificarle? Il mio codice mi dà 2048 e 1024 fattorizzazioni per quei numeri, rispettivamente, e non sono sicuro del perché.
Sherlock9,

@ Sherlock9, lo farò quando torno a casa. Quello che posso fare con un generatore online è darti un output valido per 5336100 .
Peter Taylor,

3
Questo mi ricorda una sfida di ProjectEuler (sfortunatamente non ricordo quale). Ma lì dovevi contare il numero di fattorizzazioni invece di elencarle.
Flawr,

OEIS correlati: A001055
Sherlock9,

Risposte:


12

Haskell, 56 byte

_!1=[[]]
i!n=[j:f|j<-[i..n],mod n j<1,f<-j!div n j]
(2!)

(2!)(1338557220::Int)stampa in cinque minuti sul mio laptop, quando compilato ghc -O3.

Haskell, 62 byte, ma molto più veloce

i!n|i*i>n=[[n]]|0<1=[i:f|mod n i<1,f<-i!div n i]++(i+1)!n
(2!)

(2!)(1338557220::Int)stampa in un quarto di secondo sul mio laptop, quando compilato ghc -O3.


Come posso provarlo? ghcmi dà Parse error: naked expression at top levele mi ghciparse error on input `='
Peter Taylor,

@PeterTaylor Sostituisci la funzione (2!)con il programma main = print ((2!) (1338557220::Int)), compila con ghc -O3 factor.hsed esegui con ./factor.
Anders Kaseorg,

7

Pyth, 29 byte

Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2

M                                def g(G, H):
                   @H2             square root of H
                  S                1-indexed range up to floor
                 >    tG           all but first G − 1 elements
            f                      filter for elements T such that:
              %HT                    H mod T
             !                       is false (0)
   m                               map for elements d:
       gd/Hd                         g(d, H/d)
    +Ld                              prepend d to each element
  a                     ]]H        append [[H]]
 s                                 concatenate
                           g2Q   print g(2, input)

Provalo online

Funziona in venti secondi per 1338557220il mio laptop.


@PeterTaylor Il solito modo: pyth factor.pyth(o pyth -c 'Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2'), fornendo 16su stdin. Assicurati di utilizzare una versione corrente di Pyth; implicito è Qstato aggiunto a marzo. Tuttavia, non riesco a immaginare come potresti ottenere una divisione per zero.
Anders Kaseorg,

Arrrrgh. Stavo usando al "posto di ', e bash stava espandendo il !%qualcos'altro.
Peter Taylor,

6

Python , 252 313 312 311 145 141 137 135 103 84 83 byte

Questo è in gran parte basato sulla risposta Pyth di Anders Kaseorg . Eventuali suggerimenti sul golf sono i benvenuti. Provalo online!

Modifica: 19 byte giocati a golf grazie a Dennis. Risolto un errore di battitura nel codice e aggiunto un collegamento TIO.

g=lambda n,m=2:[[n]]+[j+[d]for d in range(m,int(n**.5)+1)if n%d<1for j in g(n/d,d)]

Ungolfed:

def g(n, m=2):
    a = [[n]]
    s = int(n**.5) + 1
    for d in range(m, s):
        if n%d == 0:
            for j in g(n/d, d):
                a.append([d]+j)
    return a

1
**.5si sbarazza dell'importazione.
Dennis,

4

JavaScript (ES6), 83 byte

f=(n,a=[],m=2,i=m)=>{for(;i*i<=n;i++)n%i<1&&f(n/i,[...a,i],i);console.log(...a,n)}

Ho preso in prestito solo il trucco della radice quadrata di @ AndersKaseorg perché alla fine mi ha salvato byte nel complesso. Stampa 1per un input di 1, altrimenti non stampa 1s.


1

Ruby 1.9+, 87 89 87 byte

Questa risposta si basa sulla risposta Pyth di Anders Kaseorg . Questo codice funziona solo per le versioni successive a Ruby 1.9, poiché i stabby lambdas ->sono stati introdotti solo nella versione 1.9. Tutti i suggerimenti per il golf sono i benvenuti.

g=->n,m=2{(m..Math.sqrt(n)).select{|i|n%i<1}.flat_map{|d|g[n/d,d].map{|j|[d]+j}}+[[n]]}

Ungolfed:

def g(n, m=2)
  a = [[n]]
  s = (m..Math.sqrt(n))
  t = s.select{|i|n%i<1}
  t.each do |d|
    g[n/d,d].each do |j|
      a.push([d]+j)
    end
  end
  return a
end

Ciò richiede una versione particolare di Ruby? Con 1.8.7 ricevo una lamentela riguardo a g[n/d,d]:wrong number of arguments (0 for 1)
Peter Taylor,

Apparentemente i lambda di stabby ->sono stati introdotti in Ruby 1.9. Modificherò la risposta per mostrare il numero di versione richiesto.
Sherlock9,

Ok grazie. Sono ancora curioso di sapere g[n/d,d]. g(n/d,d)è più compatibile con le versioni precedenti.
Peter Taylor,

1
Ah, f[n]è necessario chiamare stabby lambdas e Ruby lambdas in generale. f(n)e le f nchiamate richiedono defe end. Maggiori informazioni qui e qui
Sherlock9,

1

J, 52 byte

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:

Non efficiente come potrebbe essere poiché alcune fattorizzazioni possono essere ripetute e deve essere eseguito un passaggio finale dopo aver ordinato ciascuna fattorizzazione e poi de-duplicato.

Provalo online! (Ma cerca di mantenere piccoli i valori di input).

Sul mio desktop, i tempi sono

   f =: [:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:
   timex 'r =: f 1338557220'
3.14172
   # r
246218
   timex 'r =: f 901800900'
16.3849
   # r
198091

Spiegazione

Questo metodo si basa sulla generazione di tutte le partizioni impostate per i fattori primi dell'intero di input n . Le prestazioni sono migliori quando n è privo di quadrati, altrimenti verranno create fattorizzazioni duplicate.

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:  Input: integer n
                                                  }:  Curtail, forms an empty array
                       q:                             Prime factorization
                     #@                               Length, C = count prime factors
                         _&(                     )    Repeat that many times on x = []
                                 (            )"1       For each row
                                            ~.            Unique
                                         #\@              Enumerate starting at 1
                                       0,                 Prepend 0
                                  ,~"{~                   Append each of those to a
                                                          copy of the row
                               <@                         Box it
                            ;&]                         Set x as the raze of those boxes
                                                      These are now the restricted growth
                                                      strings of order C
    q:                                                Prime factorization
            (    )"$~                                 For each RGS
               /.                                       Partition it
             */                                         Get the product of each block
        /:~@                                            Sort it
      <@                                                Box it
[:~.                                                  Deduplicate
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.