Pozitif bir tamsayının kısmi çarpanlara ayrılması


23

Pozitif tamsayılar koleksiyonu d_1 d_2 ... d_kbir olan factorisation Pozitif tamsayı nise

d_1 * d_2 * ... * d_k = n

Her pozitif tamsayının benzersiz bir ana çarpanlara ayrılması vardır , ancak genel olarak terimlerin bazılarının birleşik olduğu çarpanlara da sahiptir. Örneğin

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

Girdi olarak tek bir pozitif tamsayı alan ve farklı faktörlemelerinin tam bir listesini döndüren ya da basan bir program, işlev, fiil veya benzeri bir şey yazın. Faktoring, herhangi bir sırayla üretilebilir ve terimleri herhangi bir sırayla olabilir, ancak ikisi birbirinin permütasyonu olmamalıdır. Faktoring, 1iki istisna dışında olabilir: giriş niçin, faktoringi n*1yerine n; ve giriş için boş liste yerine 1çarpanlara ayırma verebilirsiniz 1.

Girişin imzalı bir 32 bit tam sayı aralığında olacağını varsayabilirsiniz. Çıktı bir dizge ise, faktörizasyondaki sayıların sınırlandırılması ile faktörizasyonun sınırlandırılması arasında açık bir ayrım olmalıdır, ancak bir faktöre katılması gereken faktörler için (örneğin) gerekli değildir *.

Kodunuz makul bir masaüstünde 10 dakika içerisinde geçerli bir girişi tutabilecek durumda olmalıdır.

Örnekler

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

Bunları kontrol edebileceğimiz bir yerde 901800900ve çarpanlara ayırma listesini gönderebilir misiniz 1338557220? Kodum bana bu numaralar için sırasıyla 2048 ve 1024 faktoringi veriyor, ve neden olduğundan emin değilim.
Sherlock9

@ Sherlock9, eve geldiğimde bunu yapacak. Çevrimiçi bir jeneratör ile yapabileceğim şey size 5336100 için geçerli bir çıktı vermektir .
Peter Taylor

3
Bu bana bir ProjectEuler meydan okumasını hatırlatıyor (ne yazık ki hangisini hatırlamıyorum). Ancak , onları listelemek yerine çarpanlara ayırma sayısını saymanız gerekiyordu.
flawr

İlgili OEIS
Sherlock9

Yanıtlar:


12

Haskell, 56 bayt

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

(2!)(1338557220::Int)derlendiğinde dizüstü bilgisayarımda beş dakikada yazdırıyor ghc -O3.

Haskell, 62 bayt, ancak çok daha hızlı

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)derlendiğinde dizüstü bilgisayarımda saniyenin çeyreğinde yazdırıyor ghc -O3.


Bunu nasıl test ederim? ghcverir Parse error: naked expression at top levelve ghciverirparse error on input `='
Peter Taylor

@PeterTaylor Fonksiyonu programla değiştirin, (2!)ile main = print ((2!) (1338557220::Int))derleyin ghc -O3 factor.hsve ile çalıştırın ./factor.
Anders Kaseorg

7

Pyth, 29 bayt

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)

Çevrimiçi deneyin

1338557220Dizüstü bilgisayarımda yirmi saniye içinde çalışıyor .


@PeterTaylor Her zamanki gibi: pyth factor.pyth(veya pyth -c 'Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2'), 16stdin üzerinde. Geçerli bir Pyth sürümü kullandığınızdan emin olun; örtülü QMart ayında eklendi. Yine de sıfıra nasıl bölündüğünüzü hayal edemiyorum.
Anders Kaseorg

Arrrrgh. Onun "yerine kullanıyordum 've bash !%başka bir şeye genişletiyordu .
Peter Taylor

6

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

Bu büyük ölçüde Anders Kaseorg'un Pyth cevabına dayanıyor . Herhangi bir golf önerileri hoş geldiniz. Çevrimiçi deneyin!

Düzenleme: 19 bayt Dennis sayesinde golf. Koddaki bir yazım hatası düzeltildi ve bir TIO bağlantısı eklendi.

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
**.5ithalattan kurtulur.
Dennis,

4

JavaScript (ES6), 83 bayt

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

Sadece AndersKaseorg'un karekök hilesini ödünç aldım çünkü sonuçta beni bayt kurtardı. 1Girişi için yazdırır 1, aksi takdirde 1s yazdırmaz .


1

Ruby 1.9+, 87 89 87 bayt

Bu cevap Anders Kaseorg'un Pyth cevabına dayanmaktadır . Bu kod yalnızca Ruby 1.9'dan sonraki sürümler için geçerlidir, çünkü stabby lambda'lar ->yalnızca 1.9 sürümünde tanıtılmıştır. Herhangi bir golf önerisi açıktır.

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

Bu özel bir Ruby sürümü gerektiriyor mu? 1.8.7 ile hakkında bir şikayet alıyorum g[n/d,d]:wrong number of arguments (0 for 1)
Peter Taylor

Görünüşe göre stabby lambdas ->Ruby 1.9'da tanıtıldı. Gerekli sürüm numarasını göstermek için cevabı düzenleyeceğim.
Sherlock9

Tamam teşekkürler. Hala merak ediyorum g[n/d,d]. g(n/d,d)daha geriye dönük uyumludur.
Peter Taylor

1
Ah, f[n]genel olarak stabby lambdas ve Ruby lambdas'ı çağırmak gerekiyor. f(n)ve f naramalar gerektirir defve end. Burada ve burada
Sherlock9

1

J, 52 bayt

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

Bazı faktörleşmelerin tekrarlanabileceği ve her bir faktoringi sıraladıktan ve çoğalttıktan sonra son bir geçiş yapılması gerektiğinden, olabileceği kadar verimli değil.

Çevrimiçi deneyin! (Ancak giriş değerlerini küçük tutmaya çalışın).

Masaüstümde zamanlamalar

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

açıklama

Bu yöntem, n tamsayısının asal çarpanları için tüm küme bölümleri oluşturmaya dayanır . N kare olmadığında performans en iyisidir , aksi halde yinelenen çarpanlara ayırma oluşturulur.

[:~.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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.