Asal güç çarpanlarına ayırma işleminden bölen toplamı


11

Görev, asal çarpanlarına ayırma işlemi verildiğinde bir sayının bölen toplamını hesaplamaktır.

Giriş

Biri asal çarpanı ve diğeri karşılık gelen üssü içeren iki uzunluk (ya da eşdeğeri) n uzunluğunda diziler .

Çıktı

Tüm bölenlerin toplamı (sayının kendisi dahil).

Misal

240 sayısı, ilgili üsler olarak 4, 1 ve 1 ile asal faktörler olarak 2, 3 ve 5'e sahiptir. Beklenen çıktı 744 olur.

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

puanlama

Bayt cinsinden en kısa kod kazanır!

Çözümünüzün çalışma süresi karmaşıklığı O (üslerin toplamı) yerine O (üslerin toplamı) ise, puanınız 0,8 ile çarpılabilir.


Burada da benzer bir soru yayınlandı, ancak bu bir meydan okuma değildi. Sorunun golf oynamak için yeterli olduğunu düşünüyorum.

Kazanan bu hafta sonu seçilecek


Asal faktör dizisi her zaman birinci ve üs dizisi olmak zorunda mıdır yoksa dizilerin başka bir şekilde girildiğini varsayabilir miyiz?
Sp3000

Önerilen biçime benzer herhangi bir giriş biçimini kabul edebilirsiniz
Moartem

Şu anda bulamıyorum, ancak bence bu ya da benzer bir şey projecteuler.net'te
flawr

Yanıtlar:


3

Pyth, 13 bayt * 0.8 = 10.4

*Fms^LhdhedCQ

Gösteri.

Bu cevap, yukarıdakilerden biraz farklıdır. Sayının asal kuvvetlerinin faktörlerinin toplamını hesaplamak için, aritmetik bir formül kullanmak yerine, faktörler açıkça inşa edilmiş ve toplanmıştır.

Örneğin [asal; üs] çifti [2, 4], biz harita 2 ^ xüzerinde 0, 1, 2, 3, 4vererek [1, 2, 4, 8, 16]daha sonra 31 toplanır, hangi.

Sonuçlar daha sonra birlikte çoğaltılır ve yazdırılır.

Üstelleştirme düzgün bir şekilde uygulanırsa veya ara sonuç önbelleği varsa, bu olur O(sum of exponents).


Bağımsız uygulama, bunu ilk hesaplamak mümkün olduğunu sanmıyorum n gücünü bir o çarpma O (1) olduğunu varsayalım sürece, O (n) zamanında.
Dennis

@Dennis Peki, daha yüksek sıra terimleri hakimdir, bu yüzden muhtemelen en yüksek sıra çarpımının çalışma zamanına sahip olur, yani O(n)üssün sabit olduğunu varsayabiliriz.
isaacg

9

CJam, 15 bayt * 0.8 = 12

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

Çevrimiçi deneyin . Girdi sırası ilk önce üs listesi, ardından asal listesi (@Dennis sayesinde -3 bayt) .

Her bir üs-üs çifti için (p, e)bul

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

sonra tüm bunların ürününü bulun. Örneğin 240 için bu

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

Üstelleştirmenin nasıl uygulandığına bağlı olarak, bu daha iyi olabilir O(sum of exponents).


6

APL, 18 13 bayt * 0.8 = 10.4

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

Bu, soldaki faktörleri ve sağdaki üsleri alan bir ikili fonksiyon dizisi oluşturur.

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

Çevrimiçi deneyin . Bunun Sp3000'in harika akıllıca CJam cevabı ile aynı yaklaşım olduğunu unutmayın .

Dennis sayesinde 5 bayt tasarruf etti!


2

TI-BASIC, 17 bayt * 0.8 = 13.6

Ayrıca bağımsız olarak buldum rağmen Sp3000'in yöntemini kullanır. Girişten bir liste ve ana ekrandan bir liste alır.

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

Prod (iki kat daha küçüktür, çünkü açık parantezleri ücretsiz olarak kullanmamıza izin verir.) Bu cevabın boş dizileri desteklemediğini unutmayın, çünkü TI-BASIC'te boş diziler yoktur.


2

Haskell, 38 * 0.8 = 30.4

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

Kullanımı:

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

Anonim işlev, geometrik seri toplamı yoluyla (p,e)bölen p^etoplamını alır. Bu iki listeyi birleştirmek ve ürünü almak gibi bir sonuç elde edersiniz.

Aritmetik ifadeden daha kısa bir şey bulamadım

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

Belki ondan kurtulmanın bir yolu var (\p e->_).

Infix işlev tanımı aynı uzunluğu verir (38):

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

2

C ++, 111 80 77 bayt * 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;}

Bu, (p ^ (e + 1) -1) / (p-1) değerini hesaplar ve tüm faktörleri özyinelemeli olarak çarpar. Bir yıl önce kendimi buldum.

Yardım için teşekkür ederim, c ++ tarzı boole kullanımını tamamen unuttum.


1
n==0basitleştirir !n- ya da sonuçları tersine çevirebilir ve sadece kullanabilirsinizn
Toby Speight

2

Matlab, 53

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

Misal:

>> f([2 3 5], [4 1 1])
ans =
   744

Görünüşe göre 0.8 bonus ekleyebilirsin
Moartem

@Moartem Teşekkürler! Ama bundan emin değilim. Ben numarayı hesaplamak sve o andan itibaren tüm olası bölenler sınamak 1için s. Yani (en azından) O (lar), muhtemelen O (üslerin toplamı) ve O (üslerin çarpımı) arasındadır
Luis Mendo

Evet, doğru, O'dan bile daha büyük (üslerin
çarpımı

1

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

Giriş

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

Çıktı

744

açıklama

Bu program 2 listenin listesini alır: faktörler ve üsler.

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

Sonra üs listesinin tüm olası kombinasyonlarının listesini oluşturun.

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

ve faktörlerle sıkıştırın:

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

Üslerin gücüne etki eden faktörleri hesaplayın:

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

ve her listeyi çarpın (bu bize tüm bölenleri verir):

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]

Son olarak, tüm listeleri toplayın ve yazdırın:

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

Kısaca kodunuzun ne yaptığını açıklayabilir misiniz (python'a aşina olmadığım gibi), böylece kodunuzun karmaşıklığını değerlendirebilir miyim?
Moartem

Bu akıllıca bir yaklaşım, ancak karmaşıklık üslerin ürünüdür
Moartem

@Moartem Evet, karmaşıklığı azaltmak için fazla zaman
harcamadım

1

Python 3, 134 , 120 117

Girdi: virgülle ayrılmış iki virgülle ayrılmış dizi.

Misal:

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

NumPy ile 100 bayta düşürülebilir:

import numpy
a=eval(input())
print(numpy.product([sum(x**j for j in range(y+1))for x,y in zip(*a)]))

1
İlk Örneğin, sadece bu yüzden yerine ithal, biliyorum operatorkullandığınız için mulbir kez kullanabileceğiniz float.__mul__bayt bir demet kaydedin.
Kade

1

Jöle, rakipsiz

Bu cevap rakipsizdir, çünkü meydan okuma Jelly'nin yaratılmasından önce gelir.

5 bayt (bonus yok)

*PÆDS

Çevrimiçi deneyin!

Nasıl çalışır

*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 bayt (bonustan sonra 5,6 bayt)

*‘}’:’{P

Nasıl çalışır

×*’:’{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.

Çevrimiçi deneyin!


1

APL, 12 bayt * 0.8 = 9.6

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

Bu, klavyeden iki liste okur, önce üsler, yani:

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

Açıklama:

  • : klavyeden bir liste oku (üsler)
  • ⍳¨: listedeki her numara için bir liste oluşturun [1..n].
  • ⎕*: klavyeden (asal sayılar) başka bir liste okuyun ve her asaleti karşılık gelen listelerdeki üslerin her birine yükseltin
  • +/¨: her listeyi topla
  • 1+: x^0listelerin her birinde eksik olanı telafi etmek için her sonuca bir tane ekleyin
  • ×/: sonuçların ürününü al

1

Raket (Şema), 65 * 0.8 = 52 bayt

Herkesle aynı aritmetik

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

Açıklama:

(λ (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

0

Python 2,80 Bayt * 0,8 = 64

Bu, girdinin birbiri ardına geldiğini varsayar. Sp3000'in CJam cevabında belirtilen formülün aynısını takip eder.

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

Buna izin verilmiyorsa, bunu 84 bayt * 0.8 = 67.2 puan alan bir çözüm olarak kullanacağım. Giriş virgülle ayrılmalıdır, yani [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))

Pşşt. Hey! Bu sembolik bir çözüm, üzerinde çalıştığım bir şey:Ƥ(П([~-(x**-~y)/~-xϝx,yϊʐ(Ί,Ί)],1))


0

Mathematica, 40 bayt

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

Bölücülerle ilgilenen iç kısımları kullanmadan, iş parçacığındaki diğer matematik çözümlerinden ayırmak için.

Girdi (örnek kullanarak) [{2, 3, 5}, {4, 1, 1}]


0

Perl 5, 96 bayt

Açıkçası bu kazanmıyor ama eğlenmek için yazmaya karar verdim.

Bu bir altyordamdır:

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

Bu yüzden iş başında görün:

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

Nasıl çalışır:

  • ($b,$e)=@_dizi girişlerini $b(baz) okur ve$e (üsler) .
  • $s=1 ürünü başlatır.
  • map$s*=$b->[$_]**$e->[$_],0..@$b-1$sardışık üs üsleri ile çarpılır . şimdi$s bileşik sayı.
  • $_=1x$suzun $_bir dizeye eşit ayarlar $s.$i0 değerinde başlatılır.
  • for$j(1..$s){$i+=$j*/^(.{$j})*$/}$j1 ile arasındaki her sayı için, karakterler herhangi bir sayıda tekrarlandığında $sparçalanmaya çalışır . Olabilirse, bölünür ve 1'dir (aksi takdirde 0'dır) ve tarafından artırılır . Böylece, eşit boyutlu bir bölümdeki bölüm sayısını ekliyoruz . As Ömer E. Pol işaret , biz aradığınız sayıdır.$_$j$j$s/^(.{$j})*$/$i$j$i$_$i
  • $isonunda geri döner $i.

0

J, 14 bayt * 0.8 = 11.2

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

kullanım

   f =: [:*/(^>:)%&<:[
   2 3 5 f 4 1 1
744
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.