Jumlah pembagi dari faktorisasi kekuatan utama

11

Tugasnya adalah untuk menghitung jumlah pembagi dari angka yang diberikan factorisation utamanya.

Memasukkan

Dua array (atau sesuatu yang setara) dengan panjang n , satu berisi faktor prima dan lainnya berisi eksponen yang sesuai.

Keluaran

Jumlah semua pembagi (termasuk nomor itu sendiri).

Contoh

Angka 240 memiliki 2, 3, dan 5 sebagai faktor prima dengan 4, 1, dan 1 sebagai masing-masing eksponen. Output yang diharapkan akan menjadi 744.

Input: [2,3,5] [4,1,1]
Output: 744

Mencetak gol

Kode terpendek dalam byte menang!

Jika kompleksitas jangka waktu solusi Anda adalah O (jumlah eksponen) daripada O (produk eksponen), skor Anda dapat dikalikan dengan 0,8.


Ada pertanyaan serupa yang diposting di sini, tapi itu bukan tantangan. Saya pikir masalahnya cukup menarik untuk bisa bermain golf.

Pemenang akan dipilih akhir pekan ini

Moartem
sumber
Apakah array faktor prima selalu harus menjadi yang pertama dan array eksponen kedua atau dapatkah kita berasumsi bahwa array dimasukkan sebaliknya?
Sp3000
Anda dapat mengasumsikan format input yang serupa dengan yang diusulkan
Moartem
Tidak dapat menemukannya sekarang, tapi saya pikir ini atau yang serupa ada di projecteuler.net
flawr

Jawaban:

3

Pyth, 13 byte * 0.8 = 10.4

*Fms^LhdhedCQ

Demonstrasi.

Jawaban ini bekerja agak berbeda dari yang di atas. Untuk menghitung jumlah faktor kekuatan prima dari angka tersebut, alih-alih menggunakan rumus aritmatika, faktor-faktor tersebut secara eksplisit dikonstruksi dan dijumlahkan.

Misalnya, pada pasangan [prima, eksponen] [2, 4], kami memetakan 2 ^ xlebih 0, 1, 2, 3, 4, memberikan [1, 2, 4, 8, 16], yang kemudian dijumlahkan untuk 31.

Hasilnya kemudian dikalikan bersama dan dicetak.

Jika eksponensial diterapkan dengan benar, atau jika ada caching hasil antara, ini akan menjadi O(sum of exponents).

isaacg
sumber
Independen pelaksanaan, saya tidak berpikir itu mungkin untuk menghitung pertama n kekuatan sebuah di O (n) waktu, kecuali jika Anda menganggap bahwa perkalian adalah O (1).
Dennis
@ Dennis Nah, syarat urutan yang lebih tinggi mendominasi, sehingga mungkin akan memiliki rutime dari perkalian urutan tertinggi, yang O(n)jika kita dapat mengasumsikan basis adalah konstan.
isaacg
9

CJam, 15 byte * 0.8 = 12

q~.{_@)#(\(/}:*

Cobalah online . Urutan input adalah daftar eksponen pertama, kemudian daftar bilangan prima (-3 byte terima kasih kepada @Dennis) .

Untuk setiap pasangan prime-eksponen, (p, e)temukan

(p^(e+1) - 1)/(p - 1)

kemudian temukan produk dari semua ini. Misalnya untuk 240 ini akan menjadi

(1 + 2 + 4 + 8 + 16)(1 + 3)(1 + 5) = 31 * 4 * 6 = 744

Bergantung pada bagaimana eksponensial diterapkan, ini bisa lebih baik daripada O(sum of exponents).

Sp3000
sumber
6

APL, 18 13 byte * 0.8 = 10.4

×/(1-⊣×*)÷1-⊣

Ini menciptakan fungsi fungsi diad yang mengambil berbagai faktor di sebelah kiri dan eksponen di sebelah kanan.

×/             ⍝ Vector product of
  (1-⊣×*)      ⍝ each factor^(exponent+1)-1
         ÷1-⊣  ⍝ divided by factor-1

Cobalah online . Perhatikan bahwa ini adalah pendekatan yang sama dengan jawaban CJam yang sangat pintar dari Sp3000 .

Disimpan 5 byte berkat Dennis!

Alex A.
sumber
2

TI-BASIC, 17 byte * 0.8 = 13.6

Juga menggunakan metode Sp3000, meskipun saya menemukannya secara mandiri. Mengambil satu daftar dari Input dan satu dari homescreen.

Input E
prod(AnsAns^∟E-1)/prod(Ans-1

Menggunakan prod (dua kali lebih kecil karena memungkinkan kita menggunakan kurung buka secara gratis. Perhatikan bahwa jawaban ini tidak mendukung array kosong, karena tidak ada array kosong di TI-BASIC.

lirtosiast
sumber
2

Haskell, 38 * 0,8 = 30,4

product$zipWith(\p e->(p*p^e-1)/(p-1))

Pemakaian:

product$zipWith(\p e->(p*p^e-1)/(p-1)) [2,3,5] [4,1,1]
744.0

Fungsi anonim dibawa (p,e)ke jumlah-pembagi untuk p^emelalui jumlah seri geometrik. Menyatukan dua daftar dengan ini sebagai bergabung dan mengambil produk memberikan hasilnya.

Saya tidak dapat menemukan sesuatu yang lebih pendek dari ekspresi aritmatika

(p*p^e-1)/(p-1)
sum$map(p^)[0..e]

Mungkin ada cara untuk menghilangkannya (\p e->_).

Definisi fungsi infix memberikan panjang yang sama (38):

p%e=(p*p^e-1)/(p-1)
product$zipWith(%)
Tidak
sumber
2

C ++, 111 80 77 byte * 0.8 = 61.6

int g(int*p,int*e,int n){return n?g(p+1,e+1,n-1)*(pow(*p,*e-1)-1)/(*p-1):1;}

Ini menghitung (p ^ (e + 1) -1) / (p-1) dan secara berulang melipatgandakan semua faktor. Menemukannya sendiri setahun yang lalu.

Terima kasih telah membantu, benar-benar lupa tentang penggunaan boolean c ++ style.

Moartem
sumber
1
n==0menyederhanakan !n- atau Anda dapat membalikkan hasilnya dan hanya menggunakann
Toby Speight
2

Matlab, 53

function t=f(x,y)
s=1:prod(x.^y);t=s*~mod(s(end),s)';

Contoh:

>> f([2 3 5], [4 1 1])
ans =
   744
Luis Mendo
sumber
Sepertinya Anda dapat menambahkan bonus 0,8
Moartem
@ Moartem Terima kasih! Tapi saya tidak yakin tentang itu. Saya menghitung jumlah sdan kemudian menguji semua pembagi mungkin dari 1ke s. Jadi itu (setidaknya) O (s), yang mungkin antara O (jumlah eksponen) dan O (produk eksponen)
Luis Mendo
Ya, itu benar, bahkan lebih besar dari O (produk eksponen)
Moartem
1

Python 2,156

from itertools import*
from operator import*
i=input()
print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])))

Memasukkan

[[2,3,5],[4,1,1]]

Keluaran

744

Penjelasan

Program ini menerima daftar 2 daftar: faktor dan eksponen.

i=input() # Receive list of 2 lists: i[0] for factors i[1] for exponents

Kemudian buat daftar semua kemungkinan kombinasi dari daftar eksponen.

[x+1 for x in i[1]] # [4,1,1]->[5,2,2] (to include last element)
map(range,[x+1 for x in i[1]]) # [[0, 1, 2, 3, 4], [0, 1], [0, 1]]
product(*map(range,[x+1 for x in i[1]])) # [(0, 0, 0), (0, 0, 1), ..., (4, 1, 1)]

dan zip dengan faktor-faktor:

zip(i[0],p) for p in product(*map(range,[x+1 for x in i[1]])) # [[(2, 0), (3, 0), (5, 0)], ..., [(2, 4), (3, 1), (5, 1)]]

Hitung faktor dengan kekuatan eksponen:

 [a**b for a,b in zip(i[0],p)]for p in product(*map(range,[x+1 for x in i[1]])) # [[1, 1, 1], ..., [16, 3, 5]]

dan gandakan setiap daftar (ini memberi kita semua pembagi):

reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])) # [1, 5, 3, 15, ..., 240]

Akhirnya, jumlahkan semua daftar dan cetak:

print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]]))) # 744
TheCrypt
sumber
Bisakah Anda menjelaskan secara singkat apa yang kode Anda lakukan (karena saya tidak terbiasa dengan python), jadi saya dapat menilai kompleksitas kode Anda?
Moartem
Itu pendekatan yang cerdas, tetapi kerumitannya adalah produk dari para eksponen
Moartem
@ Moartem Ya, saya tidak menghabiskan banyak waktu untuk mengurangi kerumitan
TheCrypt
1

Python 3, 134 120 117

Input: dua array yang dipisahkan koma, dipisahkan dengan koma.

Contoh:

(2,3,7,11),(4,2,3,2)
21439600
from functools import*
a=eval(input())
print(reduce(int.__mul__,(sum(x**j for j in range(y+1))for x,y in zip(*a)),1))

Dengan NumPy dapat dikurangi hingga 100 byte:

import numpy
a=eval(input())
print(numpy.product([sum(x**j for j in range(y+1))for x,y in zip(*a)]))
Trang Oul
sumber
1
Sebagai contoh pertama, supaya Anda tahu, alih-alih mengimpor operatoruntuk menggunakan mulsekali, Anda dapat menggunakan float.__mul__untuk menyimpan banyak byte.
Kade
1

Jelly, tidak bersaing

Jawaban ini tidak bersaing, karena tantangan mendahului pembuatan Jelly.

5 byte (tidak ada bonus)

*PÆDS

Cobalah online!

Bagaimana itu bekerja

*PÆDS    Main link. Left input: p (prime factors). Right input: e (exponents).

*        Elevate the prime factors to the corresponding exponents.
 P       Take the product of all powers.
  ÆD     Find all divisors of the product.
    S    Compute the sum of the divisors.

7 byte (5,6 byte setelah bonus)

*‘}’:’{P

Bagaimana itu bekerja

×*’:’{P  Main link. Left input: p (prime factors). Right input: e (exponents).

 *       Elevate the prime factors to the corresponding exponents.
         This yields p ** e.
×        Multiply the prime factors with the corresponding powers.
         This yields p ** (e + 1).
  ’      Decrement the resulting products.
         This yields p ** (e + 1) - 1.
    ’{   Decrement the prime factors.
         This yields p - 1.
   :     Divide the left result by the right one.
         This yields (p ** (e + 1) - 1) / (p - 1).
      P  Take the product of all quotients.

Cobalah online!

Dennis
sumber
1

APL, 12 byte * 0.8 = 9.6

×/1++/¨⎕*⍳¨⎕

Ini membaca dua daftar dari keyboard, eksponen pertama, yaitu:

      ×/1++/¨⎕*⍳¨⎕
⎕:
      4 1 1
⎕:
      2 3 5
744

Penjelasan:

  • : baca daftar dari keyboard (eksponen)
  • ⍳¨: untuk setiap nomor dalam daftar, buat daftar [1..n].
  • ⎕*: baca daftar lain dari keyboard (bilangan prima), dan naikkan setiap prime ke masing-masing eksponen dalam daftar yang sesuai
  • +/¨: jumlah setiap daftar
  • 1+: tambahkan satu untuk setiap hasil, untuk mengkompensasi yang hilang x^0di setiap daftar
  • ×/: ambil produk dari hasil
marinus
sumber
1

Racket (Skema), 65 * 0,8 = 52 byte

Aritmatika yang sama dengan yang lainnya

(λ(x y)(foldl(λ(m n o)(*(/(-(expt m(+ n 1))1)(- m 1))o))1 x y))

Penjelasan:

(λ (x y)    ;defines anonymous function with two inputs
    (foldl    ;recursively applies the following function to all elements of the lists given to an argument given (foldl function argument lists lists lists...)
        (λ (m n o) (* (/ (- (expt m (+ n 1)) 1) (- m 1)) o))    ;an anonymous function representing the same arithmetic used in the CJam answer, then multiplying it with our incrementor
        1 x y))    ;the incrementor argument is 1, and the input lists are the ones provided into the original function
Kronismage
sumber
0

Python 2, 80 Bytes * 0.8 = 64

Ini mengasumsikan input datang satu demi satu. Mengikuti formula yang sama seperti yang dijabarkan dalam jawaban CJam Sp3000.

print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(input(),input())],1)) 

Jika ini tidak diizinkan, maka saya akan menggunakan ini sebagai solusi, yang mendapat skor 84 byte * 0,8 = 67,2. Input harus dipisahkan dengan koma, yaitu [2,3,5],[4,1,1].

k=input()
print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(k[0],k[1])],1))

Psst. Hei! Ini adalah solusi yang mungkin dalam Symbolic, sesuatu yang saya kerjakan:Ƥ(П([~-(x**-~y)/~-xϝx,yϊʐ(Ί,Ί)],1))

Kade
sumber
0

Mathematica, 40 byte

Total[Outer@@{*}~Join~(#^0~Range~#2),3]&

Tanpa menggunakan inbuilt yang berhubungan dengan pembagi, untuk membedakan dari solusi Mathematica lainnya di utas.

Input adalah (menggunakan contoh) [{2, 3, 5}, {4, 1, 1}]

A Simmons
sumber
0

Perl 5, 96 byte

Jelas ini bukan kemenangan, tetapi saya memutuskan untuk menulisnya untuk bersenang-senang.

Ini adalah subrutin:

{($b,$e)=@_;$s=1;map$s*=$b->[$_]**$e->[$_],0..@$b-1;$_=1x$s;for$j(1..$s){$i+=$j*/^(.{$j})*$/}$i}

Lihat dalam aksi sebagai berikut:

perl -e'print sub{...}->([2,3,5],[4,1,1])'

Bagaimana itu bekerja:

  • ($b,$e)=@_membaca input arrayrefs $b(basis) dan $e(eksponen).
  • $s=1 menginisialisasi produk.
  • map$s*=$b->[$_]**$e->[$_],0..@$b-1dikalikan $sdengan kekuatan basis-eksponen berturut-turut. Sekarang $sadalah angka gabungan.
  • $_=1x$sset $_sama dengan string, $spanjang.$idiinisialisasi pada 0.
  • for$j(1..$s){$i+=$j*/^(.{$j})*$/}mencoba, untuk setiap angka $jantara 1 dan $s, untuk memecah $_sebagai $jkarakter diulang beberapa kali. Jika bisa, maka $jmembagi $s, dan /^(.{$j})*$/adalah 1 (kalau tidak 0), dan $iditambah dengan $j. Dengan demikian, kami menambah $ijumlah partisi dalam partisi berukuran sama $_. Seperti yang ditunjukkan Omar E. Pol , $iadalah angka yang kami cari.
  • $ipada akhirnya kembali $i.
msh210
sumber
0

J, 14 byte * 0.8 = 11.2

[:*/(^>:)%&<:[

Pemakaian

   f =: [:*/(^>:)%&<:[
   2 3 5 f 4 1 1
744
mil
sumber