Akar Faktor Utama


14

Terinspirasi oleh akar digital, akar faktorial utama dari angka adalah angka yang muncul ketika Anda mengambil faktor prima dari suatu angka, menambahkannya bersama-sama, dan mengulangi proses pada angka yang dihasilkan, terus sampai Anda berakhir dengan nomor prima ( yang memiliki dirinya sendiri sebagai satu-satunya faktor utama, dan dengan demikian merupakan akar faktorial pribadinya sendiri). Akar faktorial utama dari 4 adalah 4, karena 2 * 2 = 2 + 2, dan ini adalah satu-satunya akar faktorial prime non-prima dari bilangan bulat yang lebih besar dari 1 (yang merupakan kasus khusus lainnya, karena tidak memiliki faktor prima). Urutan OEIS yang dibentuk oleh akar faktorial prima adalah A029908 .

Sebagai contoh, akar faktorial utama dari 24 adalah:

24=2*2*2*3

2+2+2+3=9=3*3

3+3=6=2*3

2+3=5, and the only prime factor of 5 is 5.  Therefore, the prime factoral root of 24 is 5.  

Tugas Anda:

Tulis program atau fungsi yang menemukan akar faktorial utama dari integer input.

Memasukkan:

Bilangan bulat, masukan melalui metode apa pun yang masuk akal, antara 2 dan bilangan bulat terbesar yang didukung bahasa Anda (inklusif). Khusus memilih bahasa yang memiliki ukuran bilangan bulat maksimum rendah yang tidak masuk akal tidak diizinkan (dan juga melanggar celah standar ini )

Keluaran:

Integer, akar faktorial utama dari input.

Kasus uji:

4   -> 4
24  -> 5
11  -> 11
250 -> 17

Mencetak:

Ini adalah , skor terendah dalam byte menang!


3
Bisakah Anda menambahkan 4dalam kasus uji, karena ini merupakan pengecualian dan mudah untuk melupakannya saat menguji jawaban?
scottinet

Apakah kita harus menghasilkan 1 untuk 1?
kata ganti saya adalah monicareinstate

@ seseorang menurut urutan OEIS yang ditautkan, harus menghasilkan 0 untuk 1
scottinet

2
@ seseorang Tantangan menyatakan bahwa input akan setidaknya 2.
Martin Ender

@ seseorang Maaf untuk tidak pergi untuk sementara waktu. Seperti yang dikatakan Martin, tantangannya secara spesifik mengatakan bahwa input akan lebih besar dari satu, dan karenanya perilaku ketika input tersebut 1 tidak ditentukan.
Gryphon

Jawaban:



14

Haskell , 61 byte

import Data.Numbers.Primes
until=<<((==)=<<)$sum.primeFactors

Cobalah online!

Penjelasan

until=<<((==)=<<)mengambil fungsi fdan menerapkannya pada input xhingga titik perbaikan tercapai, yaitu f xsama x. primeFactorsmengembalikan daftar faktor prima dari angka, summenghasilkan jumlah dari daftar angka.

Tapi tunggu, mengapa until=<<((==)=<<) pekerjaan itu dan terlihat sangat aneh?

Jika kita mengasumsikan f=sum.primeFactors, definisi yang lebih alami adalah until(\x->f x==x)f, karena untilmengambil predikat (fungsi yang mengembalikan boolean), fungsi yang memiliki input dan tipe pengembalian yang sama (misalnya Int -> Int) dan nilai dari tipe ini, dan kemudian menerapkan fungsi tersebut ke nilai sampai predikat terpenuhi.

until(\x->f x==x)fsama dengan until(\x->(==)(f x)x)f, dan seperti yang berlaku itu g (h x) xsama dengan (g=<<h)x, kita dapatkan until(\x->((==)=<<f)x)f. Setelah konversi Eta , ini menjadi until((==)=<<f)f. Tetapi jika kita sekarang memperlakukan (==)=<<sebagai fungsi yang diterapkan f, kita dapat melihat bahwa until(((==)=<<)f)fitu lagi bentuk g (h x) x, dengan g=until, h=((==)=<<)dan x=f, sehingga dapat ditulis ulang (until=<<((==)=<<))f. Menggunakan $operator untuk menghilangkan tanda kurung luar dan menggantikannya fdengan sum.primeFactorsmenghasilkan solusi dari atas.


4
=<<((==)=<<)$Whaaaaaat.
totallyhuman

2
@icrieverytim saya menambahkan penjelasan. Jangan ragu untuk bertanya di ruang obrolan Haskell jika Anda memiliki pertanyaan lebih lanjut tentang cara kerja sihir ini.
Laikoni

5

Sekam , 4 byte

ω(Σp

Cobalah online!

Penjelasan:

ω(   -- apply the following function until the result no longer changes (fixpoint)
  Σ  -- sum
   p -- the list of primefactors

4

Pyth , 3 byte

usP

Coba di sini.

Penjelasan:

usPGQ The trailing GQ is implicit
  PG  Get prime factors
 s    Sum
u   Q Repeat until returned value no longer unique starting with the input

Apakah Anda lupa memperbarui penjelasan Anda?
MCMastery

1
@MCMastery Tidak, kode dan penjelasannya sama. The trailing GQ is implicit
manusiawi

@MCMastery apa yang saya katakan setiap saat
Erik the Outgolfer

4

Python 2 , 84 byte

f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))
i=input()
exec'i=f(i);'*i
print i

Cobalah online!


Ini mungkin pertanyaan yang sangat bodoh, tetapi bagaimana cara f=lambda n,d=2:n>1and(n%d and f(n,d+1)or d+f(n/d))kerjanya? Saya tidak pernah memprogram dengan Python (terutama Java dan C #), jadi saya tidak yakin apa hasil dari fungsi ini. Apakah fungsi ini memodifikasi input ndan mengembalikannya setelahnya, atau apakah mirip dengan boolean di mana n>1and(n%d and f(n,d+1)or d+f(n/d))0 atau 1, atau 0 atau n, atau yang lainnya? Saya mencoba memvisualisasikan bagaimana port ini akan terlihat seperti di Java / C #, tapi saya tidak bisa karena saya tidak benar-benar mengerti lambda Python seperti ini secara umum.
Kevin Cruijssen

1
@KevinCruijssen ini setara dengan n>1 ? (n%d!=0 ? f(n, d+1) : d+f(n/d)) : n>1. Secara umum x and ysetara dengan x ? y : x. x and y or zsetara dengan x ? y : zdalam banyak kasus.
Ov

1
@KevinCruijssen port Java akan menjadi sesuatu seperti f=(n,d=2)->n>1?n%d>0?f(n,d+1):d+f(n/d):0.
Ov

Ah baiklah. Terima kasih atas penjelasannya, sekarang lebih masuk akal. Dan saya ingat x and ymenjadi x ? y : xdari JavaScript juga. Terima kasih!
Kevin Cruijssen

4

Java 8, 175 144 142 141 byte

n->{for(int i,t=n,x;;n=t){for(i=2;i<t;t=t%i++<1?0:t);if(t>1|n<5)return n;for(t=0,i=1;i++<n;)for(;n%i<1;n/=i,t+=x)for(x=i;x>9;x/=10)t+=x%10;}}

-1 byte berkat @Nevay .

Tidak seperti byte tunggal dalam beberapa bahasa golf, Java sangat cocok untuk pemeriksaan prima, faktor prima, jumlah digit, dan semacamnya, jadi saya kira kurang dari 200 tidak terlalu buruk.
Kemungkinan besar masih bisa bermain golf dengan menggabungkan loop dan tidak menggunakan metode rekursif terpisah untuk jumlah digit .

Penjelasan:

Coba di sini.

n->{                // Method with integer as both parameter and return-type
  for(int i,        //  Index-integer `i`
          t=n,      //  Temp integer `t`, starting at the input `n`
          x;        //  Temp integer `x`
      ;             //  Loop (1) indefinitely
      n=t){         //    After every iteration, replace `n` with the value `t`
    for(i=2;        //   Reset `i` to 2
        i<t;        //   Inner loop (2) from 2 to `t` (exclusive)
        t=t%i++<1?  //    If `t` is divisible by `i`:
           0        //     Set `t` to 0
          :         //    Else:
           t        //     Leave `t` the same
    );              //   End of inner loop (2)
    if(t>1          //   If `t` is not 0 (it means it's a prime),
       |n<5)        //   or if `n` is below 5 (for edge-cases `4` and 'prime' `1`)
      return n;     //    Return `n` as result
    for(t=0,        //   Reset `t` to 0
        i=1;        //   Reset `i` to 1
        i++<n;)     //   Inner loop (3) from 2 to `n` (inclusive)
      for(;n%i<1;   //    Inner loop (4) as long as `n` is divisible by `i`
          n/=i,     //      After every iteration: Divide `n` by `i`,
          t+=x)     //      and increase `t` by `x`
        for(x=i;    //     Reset `x` to `i`
            x>9;    //     Inner loop (5) as long as `x` contains more than 1 digit
            x/=10)  //       After every iteration, remove the trailing digit
          t+=n%10;  //      Increase `t` with the trailing digit of `n`
                    //     End of inner loop (5) (implicit / single-line body)
                    //    End of inner loop (4) (implicit / single-line body)
                    //   End of inner loop (3) (implicit / single-line body)
  }                 //  End of loop (1)
}                   // End of method

6
+1 karena repot-repot menulis penjelasan dengan kata-kata seolah-olah ini adalah bahasa golf.
kata ganti saya adalah monicareinstate

@ seseorang Terima kasih! Karena seseorang bertanya kepada saya tentang penjelasan tentang jawaban Java saya di masa lalu, saya telah menambahkannya ke semua jawaban saya. :)
Kevin Cruijssen

i,t=n,xsepertinya itu milik Python, haha
ETHproduk

@ ETHproductions Hehe, sayang sekali saya masih harus menambahkan yang terkemuka int (tidak seperti Python). ;)
Kevin Cruijssen

Anda bisa menggunakan i++<nbukan ++i<=n.
Nevay


3

Retina , 30 byte

{+`(\1|\b11+?\B)+$
$1;$#1$*
;

Input dan output di unary .

Cobalah online! (Melakukan konversi desimal / unary untuk kenyamanan.)

Penjelasan

{+`(\1|\b11+?\B)+$
$1;$#1$*

The {menginstruksikan Retina untuk menjalankan seluruh program dalam satu lingkaran sampai lulus penuh gagal untuk memodifikasi string, yaitu sampai titik tetap tercapai. Akibatnya, program itu sendiri menghitung satu langkah menjumlahkan faktor utama dari nilai saat ini.

Tahap ini sendiri menghitung faktor utama dari input. The +mirip dengan {tetapi loop hanya tahap ini sampai berhenti mengubah string. Regex mencoba mencocokkan run terakhir 1dengan berulang kali mencocokkan substring yang sama (yaitu faktor). Cara ini dilakukan agak berbelit-belit karena referensi ke depan \1. Pada iterasi pertama, grup 1belum menangkap apa pun, jadi \1gagal tanpa syarat. Sebagai gantinya, kami harus mencocokkan \b11+?\Byang merupakan substring sekecil mungkin yang dimulai pada awal jalankan, berisi setidaknya dua 1s dan tidak mencakup keseluruhan proses. Iterasi berikutnya tidak akan dapat menggunakan alternatif ini lagi, karena\b . Jadi pada semua iterasi lebih lanjut, kami cocok\1, yaitu substring yang sama berulang-ulang. Proses ini harus mengenai ujung string persis ( $) untuk memastikan kami telah menangkap dan pembagi yang sebenarnya. Keuntungan menggunakan pendekatan yang agak rumit ini adalah bahwa grup 1akan digunakan tepat n / d d . kali, yaitu apa yang tersisa setelah membagi pembagi

Kami mengganti kecocokan ini dengan d ( $1), pemisah ;dan n / d ( $#1$*, yang menyisipkan $#1salinan 1, di mana$#1 jumlah tangkapan yang dibuat oleh kelompok 1).

Proses ini berhenti setelah menjalankan terakhir dalam string itu sendiri adalah yang utama, karena kemudian regex tidak lagi cocok.

;

Yang perlu kita lakukan untuk menjumlahkan bilangan prima adalah menghapus semua pemisah.


3

Ohm v2 , 4 byte

·ΘoΣ

Cobalah online!

Penjelasan:

·Θ    evaluate the block until the result returned has already been seen
   Σ  sum
  o   the full prime factorization

2

Sebenarnya , 7 byte

⌠w♂πΣ⌡Y

Cobalah online!

Penjelasan:

⌠w♂πΣ⌡Y
⌠    ⌡Y  do this until output stops changing (fixed-point combinator)
 w         factor into [prime, exponent] pairs
  ♂π       product of each pair
    Σ      sum of products

2

R + pracma , 53 byte

function(n){for(i in 1:n)n=sum(pracma::factors(n))
n}

Cobalah online! (r-biola)

R tidak memiliki faktor prima builtin, tapi banyak paket ( pracma, numbers, dll) lakukan, jadi saya mengambil yang nyaman singkat.


1

Jeli , 6 byte

Jawaban ini menggunakan salah satu dari bawaan faktorisasi utama Jelly, dan jawaban cepat untuk repeat until the results are no longer unique.

ÆfSµÐL

Cobalah online!


kupikir Anda sudah dikalahkan tetapi, mengingat pendekatan Anda, saya tidak yakin apakah jawaban itu berhasil
caird coinheringaahing

@cairdcoinheringaahing Saya baru saja memeriksa jawabannya (atau lebih tepatnya, setara dengan Python) dari 1 hingga 100000 dan berfungsi. Saya pikir 1adalah satu-satunya kasus di mana jumlah langkah yang dibutuhkan sama dengan n(yang baik-baik saja; dengan 1kita hanya perlu menjalankannya sekali), dan sepertinya tidak ada kasus di mana jumlah langkah lebih besar dari n(yaitu sepertinya tidak ada contoh tandingan). Ah well, aku sudah kalah besar: D
Sherlock9

Ya itu terjadi. Meskipun +1 menjadi kode yang sama persis seperti yang saya pikirkan ketika saya melihat tantangan ini
caird coinheringaahing

Jumlah faktor prima dari n selalu kurang dari atau sama dengan n, yang membuatnya cukup mudah untuk membuktikan bahwa n selalu lebih dari cukup.
Chris

1

MATL , 6 byte

Menggunakan gagasan scottinet untuk mengulang lebih dari yang dibutuhkan. Terima kasih juga kepada Shaggy untuk menunjukkan kesalahan, sekarang diperbaiki.

t:"Yfs

Cobalah online!

Penjelasan

t       % Take input (implicit). Duplicate
:"      % Do the following that many times
  Yf    %   Array of prime factors
  s     %   Sum of array
        % End (implicit). Display (implicit)

Ini tampaknya gagal 4.
Shaggy

@Shaggy Terima kasih! Mengerjakannya
Luis Mendo

@Shaggy Dipecahkan sekarang
Luis Mendo

1

PowerShell , 124 byte

function f($a){for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}
for($x=$args[0];$l-ne$x){$l=$x;$x=(f($x))-join'+'|iex}$x

Cobalah online!

PowerShell tidak memiliki built-in faktorisasi utama, jadi ini menggunakan kode dari jawaban saya pada Prime Factors Buddies (baris teratas) untuk melakukan perhitungan faktorisasi.

Baris kedua adalah daging dari program ini. Kami mengambil masukan dari $argske $x, maka forloop sampai $ladalah -not equal untuk $x. (Iterasi pertama,$l adalah $nulldan$x merupakan bilangan bulat, jadi kami akan mengulang setidaknya sekali).

Di dalam loop, kami mengatur kami $l = $xuntuk menentukan apakah kami telah mencapai ujung loop atau tidak. Kemudian kita mendapatkan faktor-faktor $xdengan f($x), faktor-faktor -joinbersama +dan|iex mereka (singkatan Invoke-Expressiondan mirip dengan eval). Itu disimpan kembali $x. Jadi, kita telah mencapai "akhir" di mana faktorisasi utama yang dirangkum bersama kembali ke dirinya sendiri. Kemudian, kita cukup letakkan $xdi pipeline dan output tersirat.


0

Mathematica, 35 byte

#//.x_:>Tr[1##&@@@FactorInteger@x]&

Cobalah online!

(Matematika tidak mendukung Tr. Saya harus menerapkannya secara manual)


4
1##&adalah kependekan dari Timesdan FixedPointhampir selalu dapat dipersingkat dengan //.:#//.x_:>Tr[1##&@@@FactorInteger@x]&
Martin Ender

@ MartinEnder Terima kasih! Seharusnya saya sudah tahu Times, tapi saya belum tahu tentang FixedPointtriknya.
user202729

Kode Anda ditulis dalam Mathematica. Ini bukan fungsi Matematika. Anda harus mengubah nama bahasa ke Mathematica atau Tr ke Total
J42161217

@ {tidak ada} Maaf, nama bahasa (Matematika) adalah sebuah kesalahan. {i cri evritime} memperbaikinya.
user202729


0

Ruby , 63 byte

->n{n.times{n=n.prime_division.map{|x|x.reduce:*}.sum};n}

Cobalah online!

Gunakan -rprimeflag untuk +6 byte untuk menggunakan Prime # prime_division .

prime_divisionmengembalikan pasangan [prime, exponent](misalnya, untuk 24 kita memiliki faktor [2, 2, 2, 3]sehingga memberi [[2, 3], [3, 1]]) jadi dalam setiap langkah kita hanya mengalikan anggota pasangan tersebut bersama-sama dan menjumlahkan hasilnya.


0

Javascript (ES6), 63 byte

f=n=>(q=(p=(m,x)=>m<x?0:m%x?p(m,x+1):x+p(m/x,x))(n,2))^n?f(q):q
<input id=i type=number min=0 value=0 oninput="o.innerText=f(i.value)">
<p id=o></p>

Tidak Disatukan:

f=n=>(                  // Recursive function `f`
    p=(m,x=2)=>(        //   Recursive function `p`, used to sum prime factors
        m<x?            //     If m (the number to be factored) is less than x (the current
            0           //     iteration), return 0
        :m%x?           //     Else if m doesn't divide x
            p(m,x+1)    //     run the next iteration
        :               //     Else (if m divides x)
            x+p(m/x,x)  //     Divide m by x and repeat the current iteration
    ),
    q=p(n),             //   Set q to the sum of the prime factors of n
    q^n?                //   If q != n then
        f(q)            //     repeat f with q
    :                   //   else
        q               //     return q
)

0

Java 8, 101 byte

n->{for(int i=n;i-->0;n=f(n,2));return n;}int f(int n,int d){return n>1?n%d>0?f(n,d+1):d+f(n/d,2):0;}

Port of @ovs menakjubkan jawaban Python 2 .

Penjelasan:

Coba di sini.

n->{                  // Method with integer as both parameter and return-type
  for(int i=n;i-->0;  //  Loop the input amount of times
    n=f(n,2)          //   And change `n` that many times with a separate method call
  );                  //  End of loop
  return n;           //  Then return the integer `n` as result
}                     // End of method

int f(int n,int d){   // Separated method with 2 integer parameters and integer return-type
                      // (`d` is 2 when we initially call this recursive-method)
  return n>1?         //  If input `n` is larger than 1:
    n%d>0?            //   And it's not divisible by `d`:
     f(n,d+1)         //    Do a recursive-call with `n, d+1`
    :                 //   Else:
     d                //    Sum `d` with
      +f(n/d,2)       //    a recursive call with `n/d, 2`
   :                  //  Else:
    0;                //   Simply return 0
}                     // End of separated method
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.