Temukan faktor prima


23

Dalam tugas ini, Anda harus menulis sebuah program, yang menghitung faktor prima dari sebuah angka. Masukan adalah bilangan asli 1 <n <2 ^ 32. Outputnya adalah daftar faktor prima dari angka dalam format berikut. Eksponen harus dihilangkan jika mereka 1. Hanya menampilkan bilangan prima. (Dengan asumsi input adalah 131784):

131784 = 2 ^ 3 * 3 * 17 ^ 2 * 19

Tidak perlu menggunakan jumlah spasi yang sama; spasi putih dapat dimasukkan di mana saja sesuai kebutuhan. Program Anda harus selesai dalam waktu kurang dari 10 menit untuk setiap input. Program dengan jumlah karakter terpendek akan menang.


9
Poin bonus jika program Anda dapat memberikan faktor 685759991434940397765474496717275817990411426461294732612716997613329698095145053073010755507864648023040197954027546706603 saja jika kurang dari 7612 hari kerja
Joey Adams

@ Joey Adams: Faktorisasi dimulai dengan 17 * 71 * 113 * 997 * 313597 ...
FUZxxl

3
@ FuZxxl: Saya pikir Anda membuat kesalahan dengan menyalin nomor tersebut. Ini adalah produk dari dua bilangan prima besar .
Joey Adams

@ Joey Bisakah kita menggunakan Algoritma Shor?
Mateen Ulhaq

23
@ Joey Saya tidak sengaja menumpahkan kopi di komputer kuantum saya, dan teman saya menggunakannya untuk "meretas ke dalam Pemerintah AS" atau sesuatu yang tidak penting, jadi, tidak. :(
Mateen Ulhaq

Jawaban:


11

SageMath, 31 Bytes

N=input()
print N,"=",factor(N)

Uji kasus: 83891573479027823458394579234582347590825792034579235923475902312344444 Keluaran:

83891573479027823458394579234582347590825792034579235923475902312344444 = 2^2 * 3^2 * 89395597 * 98966790508447596609239 * 263396636003096040031295425789508274613


Selamat telah memenangkan tantangan dengan kiriman pertama Anda, kerja bagus! Dan selamat datang di situs ini!
DJMcMayhem

8

Ruby 1.9, 74 70 karakter

#!ruby -plrmathn
$_+=?=+$_.to_i.prime_division.map{|a|a[0,a[1]]*?^}*?*

Suntingan:

  • (74 -> 70) Cukup gunakan eksponen sebagai panjang irisan alih-alih secara eksplisit memeriksa exponent > 1

7

Perl 5.10, 73 88

perl -pe '$_=`factor $_`;s%( \d+)\K\1+%-1-length($&)/length$1%ge;y, -,*^,;s;\D+;=;'

Mengambil nomor input dari input standar. Akan menghitung faktor untuk beberapa input jika disediakan.

Dihitung sebagai perbedaan perl -e. 5,10 diperlukan untuk \Kmetacharacter regex.


+1 untuk digunakan factor.
st0le

Bukankah Anda seharusnya menghitung ppilihan?
Joey

@ Joey memang seharusnya begitu. Maaf soal itu. Pemasangan.
JB

Belum menguji ini, tetapi bukannya split/\D/,~factor $_~;$_="@_";Anda bisa menulis $_=~factor $_~;s/\D/ /g;? (Tentu saja ganti ~dengan backtick.)
Timwi

Maksudmu $_=`factor $_`;s/\D/ /g;? Membungkus backtick ganda membantu.
aaaaaaaaaaaa

5

OCaml, 201 karakter

Terjemahan imperatif langsung dari kode Python terbaik:

let(%)s d=if!d>1then Printf.printf"%s%d"s!d
let f n=let x,d,e,s=ref n,ref 1,ref 0,ref"="in""%x;while!d<65536do
incr d;e:=0;while!x mod!d=0do x:=!x/ !d;incr e
done;if!e>0then(!s%d;"^"%e;s:="*")done;!s%x

Sebagai contoh,

# f 4294967292;;
4294967292=2^2*3^2*7*11*31*151*331- : unit = ()

(perhatikan bahwa saya telah menghilangkan keluaran endline akhir.) Hanya untuk bersenang-senang, pada 213 karakter, versi murni fungsional, dikaburkan secara menyeluruh melalui penggunaan liberal operator:

let(%)s d=if d>1then Printf.printf"%s%d"s d
let f x=let s=ref"="in""%x;let rec(@)x d=if d=65536then!s%x else
let rec(^)x e=if x/d*d<x then x,e else x/d^e+1in
let x,e=x^0in if e>0then(!s%d;"^"%e;s:="*");x@d+1in x@2

5

Python, 140 135 133 karakter

M=N=input()
s=''
f=1
while f<4**8:
 f+=1;e=0
 while N%f<1:e+=1;N/=f
 if e:s+='*%d'%f+'^%d'%e*(e>1)
print M,'=',(s+'*%d'%N*(N>1))[1:]

Saya pikir output membutuhkan beberapa ruang lebih, misalnya ' * %d'... Dan dua hal lagi: 65536 == 4**8; Jalur 7:if e:s+='*%d'%f+'^%d'%e*(e>1)
Oleh Prypin

@BlaXpirit: "jumlah spasi yang sama tidak diperlukan". Terima kasih untuk dua lainnya, saya akan menggabungkannya.
Keith Randall

5

J, 72

(":*/f),'=',([,'*',])/(":"0~.f),.(('^',":)`(''"0)@.(=&1))"0+/(=/~.)f=.q:161784

Khas J. Dua karakter untuk melakukan sebagian besar pekerjaan, enam puluh karakter untuk menyajikannya.

Sunting: Memperbaiki jumlah karakter.


2
Bagi saya ini bukan 62 karakter. Bahkan ketika asumsi 161784adalah input Anda, itu masih 72 karakter.
Ventero

Bukankah lebih pendek |: __ q: y?
Eelvex

2
@Ventero: JB khas. Dua jam bermain golf, lima belas detik untuk mengacaukan jumlah karakter.
JB

5

J, 53 52 karakter

Solusi ini mengambil rplctrik dari solusi randomra tetapi muncul dengan beberapa ide orisinal juga.

":,'=',(":@{.,'^','*',~":@#)/.~@q:}:@rplc'^1*';'*'"_

Dalam notasi diam-diam, fungsi ini menjadi

f =: 3 : 0
(": y) , '=' , }: (g/.~ q: y) rplc '^1*' ; '*'
)

dimana gdidefinisikan sebagai

g =: 3 : 0
": {. y) , '^' , (": # y) , '*'
)
  • q: yadalah vektor faktor prima dari y. Misalnya, q: 60hasil 2 2 3 5.
  • x u/. yberlaku uuntuk y dikunci oleh x, yaitu, uditerapkan pada vektor elemen yyang entri dalam xadalah sama. Ini agak rumit untuk dijelaskan, tetapi dalam kasus khusus y u/. yatau u/.~ y, uditerapkan pada setiap vektor elemen yang berbeda y, di mana setiap elemen diulangi sesering seperti yang terlihat di y. Misalnya, </.~ 1 2 1 2 3 1 2 2 3hasil

    ┌─────┬───────┬───┐
    │1 1 1│2 2 2 2│3 3│
    └─────┴───────┴───┘
    
  • # yadalah penghitungan dari y, yaitu, jumlah item dalam y.

  • ": y format y sebagai string.
  • x , y menambahkan x dan y.
  • {. yadalah kepala y , yaitu, item pertama.
  • Dengan demikian, (": {. y), '^' , (": # y) , '*'memformat vektor n pengulangan angka k menjadi string bentuk k ^ n *. Frasa ini dalam notasi diam-diam adalah :@{.,'^','*',~":@#, yang kami sampaikan ke keterangan yang /.dijelaskan lebih lanjut di atas.
  • x rplc yadalah fungsi perpustakaan menggantikan karakter. ymemiliki bentuk a ; bdan setiap contoh string adi xdigantikan oleh b. xdiratakan (yaitu, dibentuk kembali sedemikian rupa sehingga memiliki peringkat 1) sebelum operasi berlangsung, yang digunakan di sini. Kode ini menggantikan ^1*dengan *untuk mematuhi format output yang diamanatkan.
  • }: yadalah batasan dari y, yaitu, semua kecuali item terakhirnya. Ini digunakan untuk menghapus trailing *.

Tidak bisakah Anda menghemat banyak pekerjaan dengan menggunakan __ q:? Cobalah online!
Adám

@ Adám Memang, ide bagus!
FUZxxl

4

PHP, 112

echo$n=$_GET[0],'=';$c=0;for($i=2;;){if($n%$i<1){$c++;$n/=$i;}else{if($c){echo"$i^$c*";}$c=0;if(++$i>$n)break;}}

118

echo $n=$_GET[0],'=';for($i=2;;){if(!($n%$i)){++$a[$i];$n/=$i;}else{if($a[$i])echo "$i^$a[$i]*";$i++;if($i>$n)break;}}

3

Python 119 Chars

M=N=input()
i=1
s=""
while N>1:
 i+=1;c=0
 while N%i<1:c+=1;N/=i
 if c:s+=" * %d"%i+['','^%d'%c][c>1]
print M,'=',s[3:]

1
Itulah yang saya coba pertama, tetapi terlalu lambat untuk bilangan prima besar, seperti 4294967291.
Keith Randall

@Keith. Pertanyaannya bisa sampai 10 menit. Apakah ini akan memakan waktu lebih dari 10 menit untuk kasus terburuk?
fR0DDY

2
Butuh 32 menit pada mesin saya untuk nomor itu.
Keith Randall

3

JavaScript, 124 122 119

for(s='',i=2,o=p=prompt();i<o;i++){for(n=0;!(p%i);n++)p/=i;n?s+=i+(n-1?'^'+n:'')+'*':0}alert(s.substring(0,s.length-1))

3

Perl, 78

use ntheory":all";say join" * ",map{(join"^",@$_)=~s/\^1$//r}factor_exp(shift)

Ia menggunakan fitur s ///r dari Perl 5.14 untuk menghilangkan ^ 1s. 81 karakter untuk dijalankan dalam satu lingkaran:

perl -Mntheory=:all -nE 'chomp;say join" * ",map{(join"^",@$_)=~s/\^1$//r}factor_exp($_);'

Anda dapat meninggalkan ruang jika mau. Ini akan menghemat dua karakter. Solusi bagus!
FUZxxl

2

PHP, 236 karakter

$f[$n=$c=$argv[1]]++;echo"$n=";while($c){$c=0;foreach($f as$k=>$n)for($r=~~($k/2);$r>1;$r--){if($k%$r==0){unset($f[$k]);$f[$r]++;$f[$k/$r]++;$c=1;break;}}}foreach($f as$k=>$n)if(--$n)$f[$k]="$k^".++$n;else$f[$k]=$k;echo implode("*",$f);

Output untuk 131784: 2 ^ 3 * 3 * 17 ^ 2 * 19

Menyelesaikan semua angka dalam beberapa detik saat pengujian.

4294967296=2^32
Time: 0.000168

Input tidak pernah ditentukan, jadi saya memilih untuk menyebutnya menggunakan argumen baris perintah.

php factorize.php 4294967296

2

Scala 374:

def f(i:Int,c:Int=2):List[Int]=if(i==c)List(i)else 
if(i%c==0)c::f(i/c,c)else f(i,c+1)
val r=f(readInt)
class A(val v:Int,val c:Int,val l:List[(Int,Int)])
def g(a:A,i:Int)=if(a.v==i)new A(a.v,a.c+1,a.l)else new A(i,1,(a.v,a.c)::a.l)
val a=(new A(r.head,1,Nil:List[(Int,Int)])/:(r.tail:+0))((a,i)=>g(a,i))
a.l.map(p=>if(p._2==1)p._1 else p._1+"^"+p._2).mkString("", "*", "")

ungolfed:

def factorize (i: Int, c: Int = 2) : List [Int] = {
  if (i == c) List (i) else 
    if (i % c == 0) c :: f (i/c, c) else 
      f (i, c+1)
}
val r = factorize (readInt)
class A (val value: Int, val count: Int, val list: List [(Int, Int)])
def g (a: A, i: Int) = 
  if (a.value == i) 
    new A (a.value, a.count + 1, a.list) else 
    new A (i, 1, (a.value, a.count) :: a.list)
val a = (new A (r.head, 1, Nil: List[(Int,Int)]) /: (r.tail :+ 0)) ((a, i) => g (a, i))
a.l.map (p => if (p._2 == 1) p._1 else
  p._1 + "^" + p._2).mkString ("", "*", "")

2

J, 74 karakter

f=.3 :0
(":y),'=',' '-.~('^1 ';'')rplc~}:,,&' *'"1(,'^'&,)&":/"{|:__ q:y
)

   f 131784
131784=2^3*3*17^2*19

64 karakter dengan input dalam variabel x:

   x=.131784

   (":x),'=',' '-.~('^1 ';'')rplc~}:,,&' *'"1(,'^'&,)&":/"{|:__ q:x
131784=2^3*3*17^2*19

Jika Anda berhasil mengubah ini menjadi definisi diam-diam, Anda dapat menghindari melarikan diri dari semua kutipan. Anda juga bisa menggunakan 3 : 0definisi.
FUZxxl

@ FuZxxl saya berharap saya bisa memasukkan string yang 3 : 0tidak terhapuskan dalam versi tetapi tidak berhasil. Saya mungkin mencoba diam-diam nanti. Ini adalah 3: 0 yang saya coba: pastebin.com/rmTVAk4j .
randomra

Itu harus bekerja. Saya tidak mengerti mengapa. Apakah Anda menyebutkan argumen yAnda seperti yang seharusnya?
FUZxxl

@FUZxxl Ini adalah 3: 0 Saya mencoba: pastebin.com/rmTVAk4j .
random

3: 0 yang Anda coba tidak sama persis dengan one-liner yang Anda berikan. Ini digunakan ''alih-alih a:di satu tempat. Mungkin itu bedanya?
FUZxxl

2

Java 10, 109 108 byte (fungsi lambda) (tidak bersaing berdasarkan permintaan OP)

n->{var r=n+"=";for(int i=1,f;i++<n;r+=f<1?"":(f<2?i:i+"^"+f)+(n>1?"*":""))for(f=0;n%i<1;n/=i)f++;return r;}

Cobalah online.

Java 6+, 181 byte (program lengkap)

class M{public static void main(String[]a){long n=new Long(a[0]),i=1,f;String r=n+"=";for(;i++<n;r+=f<1?"":(f<2?i:i+"^"+f)+(n>1?"*":""))for(f=0;n%i<1;n/=i)f++;System.out.print(r);}}

Cobalah online.

-1 byte terima kasih kepada @ceilingcat .

Penjelasan:

n->{                // Method with integer parameter and String return-type
  var r=n+"=";      //  Result-String, starting at the input with an appended "="
  for(int i=1,f;i++<n;
                    //  Loop in the range [2, n]
      r+=           //    After every iteration: append the following to the result-String:
        f<1?        //     If the factor `f` is 0:
         ""         //      Append nothing
        :           //     Else:
         (f<2?      //      If the factor `f` is 1:
           i        //       Append the current prime `i`
          :         //      Else:
           i+"^"+f) //       Append the current prime `i` with it's factor `f`
         +(n>1?     //      And if we're not done yet:
            "*"     //       Also append a "*"
           :        //      Else:
            ""))    //       Append nothing more
    for(f=0;        //   Reset the factor `f` to 0
        n%i<1;      //   Loop as long as `n` is divisible by `i`
      n/=i)         //    Divide `n` by `i`
      f++;          //    Increase the factor `f` by 1
  return r;}        //  Return the result-String

@ceilingcat Terima kasih!
Kevin Cruijssen

Didiskualifikasi sebagai Java 10 dibuat setelah tugas ini diterbitkan.
FUZxxl

@FUZxxl Saya telah menandai Java 10 lambda sebagai tidak bersaing, dan menambahkan program Java 6, yang dirilis pada Desember 2006 .
Kevin Cruijssen

Oke, keren. Itu berhasil untuk saya!
FUZxxl

2

Japt , 28 27 26 byte

-1 byte terima kasih kepada Shaggy

+'=+Uk ü ®ÊÉ?ZÌ+'^+Zl:ZÃq*

Cobalah


Didiskualifikasi karena bahasa Anda dibuat setelah tugas ini diterbitkan.
FUZxxl


Itu tidak diizinkan kembali ketika tantangan diposting. Saya menganggap tidak adil untuk mengubah aturan tantangan setelah tantangan dipasang, jadi bahasa yang diterbitkan setelah tantangan ini tetap ilegal.
FUZxxl

1
@ FuZxxl Anda tidak harus menerima jawaban saya, tetapi saya diizinkan untuk menjawabnya.
Oliver


1

Powershell, 113 97 byte

Terinspirasi oleh jawaban Joey . Ini lambat tapi pendek.

param($x)(2..$x|%{for(;!($x%$_)){$_
$x/=$_}}|group|%{$_.Name+"^"+$_.Count-replace'\^1$'})-join'*'

Script tes yang dijelaskan:

$f = {

param($x)               # let $x stores a input number > 0
(2..$x|%{               # loop from 2 to initial input number
    for(;!($x%$_)){     # loop while remainder is 0
        $_              # push a current value to a pipe
        $x/=$_          # let $x is $x/$_ (new $x uses in for condition only)
    }
}|group|%{              # group all values
    $_.Name+"^"+$_.Count-replace'\^1$'  # format and remove last ^1
})-join'*'              # make string with *

}

&$f 2
&$f 126
&$f 129
&$f 86240
#&$f 7775460

Keluaran:

2
2*3^2*7
3*43
2^5*5*7^2*11

1

Jelly , 16 byte (tidak bersaing berdasarkan permintaan OP)

³”=³ÆFḟ€1j€”^j”*

Salah satu jawaban Jelly pertama saya, jadi pasti bisa bermain golf (terutama ³”=³) ..

Cobalah online.

Penjelasan:

³                 # Push the first argument
 ”=               # Push string "="
   ³ÆF            # Get the prime factor-exponent pairs of the first argument
      ḟ€1         # Remove all 1s from each pair
         j€”^     # Join each pair by "^"
             j”*  # Join the pair of strings by "*"
                  # (implicitly join the entire 'stack' together)
                  # (which is output implicitly as result)

Didiskualifikasi karena bahasa Anda dibuat setelah tugas ini diterbitkan.
FUZxxl

@FUZxxl Sejak pertengahan 2017 non-bersaing tidak ada dalam meta lagi , kecuali tantangannya secara eksplisit menyatakan bahwa bahasa harus lebih tua dari waktu posting. Tetapi jika Anda sebagai orang yang memposting tantangan memilih untuk tidak mengizinkan bahasa yang lebih baru daripada tantangan Anda pasca-tanggal, saya akan mengedit jawaban saya untuk menambahkan secara eksplisit (non-competing). :)
Kevin Cruijssen

Saya percaya konsensus situs yang ada ketika tantangan ini diposting harus menentukan aturan untuk jawaban. Segala sesuatu yang lain (yaitu aturan yang berubah setelah tantangan diposting) tidak adil. Harap tandai jawaban Anda sebagai tidak bersaing.
FUZxxl

@ FuZxxl Saya telah menandai jawaban saya sebagai tidak bersaing, seperti yang diminta.
Kevin Cruijssen

Terima kasih untuk bantuannya.
FUZxxl

1

05AB1E , 22 20 byte (tidak bersaing berdasarkan permintaan OP)

ÐfsÓ0Køε1K'^ý}'*ý'=ý

-2 byte terima kasih kepada @Emigna .

Cobalah online.

Penjelasan:

Ð                # Triplicate the (implicit) input-integer
 f               # Pop and push all prime factors (without counting duplicates)
  s              # Swap to take the input again
   Ó             # Get all prime exponents
    0K           # Remove all 0s from the exponents list
      ø          # Zip it with the prime factors, creating pairs
       ε         # Map each pair to:
        1K       #  Remove all 1s from the pair
        '^ý     '#  And then join by "^"
       }'*ý     '# After the map: join the string/integers by "*"
           '=ý  '# And join the stack by "=" (with the input we triplicated at the start)
                 # (after which the result is output implicitly)

1Kharus bekerja alih-alih `≠ iy di loop.
Emigna

@Emigna Ah lol .. Saya benar-benar melakukan itu dalam jawaban Jelly yang baru saja saya posting . Tidak yakin mengapa saya tidak memikirkannya sebelumnya di sini. :)
Kevin Cruijssen

Didiskualifikasi karena bahasa Anda dibuat setelah tugas ini diterbitkan.
FUZxxl

1

APL (NARS), 66 karakter, 132 byte

{(⍕⍵),'=',3↓∊{m←' * ',⍕↑⍵⋄1=w←2⊃⍵:m⋄m,'^',⍕w}¨v,¨+/¨{k=⍵}¨v←∪k←π⍵}

tes dan komentar:

  f←{(⍕⍵),'=',3↓∊{m←' * ',⍕↑⍵⋄1=w←2⊃⍵:m⋄m,'^',⍕w}¨v,¨+/¨{k=⍵}¨v←∪k←π⍵}
  f 131784
131784=2^3 * 3 * 17^2 * 19
  f 2
2=2
  f (2*32)
4294967296=2^32

{(⍕⍵),'=',3↓∊{m←' * ',⍕↑⍵⋄1=w←2⊃⍵:m⋄m,'^',⍕w}¨v,¨+/¨{k=⍵}¨v←∪k←π⍵}
k←π⍵      find the factors with repetition of ⍵ and assign that array to k example for 12 k is 2 2 3
v←∪       gets from k unique elements and put them in array v
+/¨{k=⍵}¨ for each element of v count how many time it appear in k (it is array exponents)
v,¨       make array of couples from element of v (factors unique) and the array above (exponents unique)
∊{m←' * ',⍕↑⍵⋄1=w←2⊃⍵:m⋄m,'^',⍕w}¨ pretty print the array of couples factor exponent as array chars
3↓                                 but not the first 3 chars
(⍕⍵),'='  but print first the argument and '=' in char format

jika seseorang memiliki banyak waktu dengan primitif ini, kenal mereka dengan baik mereka, bagi saya ada kemungkinan bahwa kode lebih jelas dari komentar ... jadi kode lebih jelas daripada komentar, komentar tidak berguna ...


0

JavaScript, 107

n=prompt()
s=n+'='
c=0
for(i=2;;){if(n%i<1){c++
n/=i}else{if(c)s+=i+'^'+c+'*'
c=0
if(++i>n)break}}
alert(s)

120

n=prompt()
o={2:0}
for(i=2,c=n;i<=c;)!(c%i)?++o[i]?c/=i:0:o[++i]=0
s=n+'='
for(i in o)s+=o[i]?i+'^'+o[i]+'*':''
alert(s)

1
Memiliki *jejak dalam output dan mencetak eksponen bahkan jika itu 1.
Ventero

tidak perlu downvote. Tidak ada tempat yang mengatakan bahwa itu tidak bisa mencetak eksponen jika itu 1. Juga, trailing *menganggap mengalikan oleh 1. Jika itu masalah besar, saya akan memperbaikinya.
zzzzBov

1
»Dalam format berikut« dalam uraian tugas cukup banyak menyiratkan bahwa eksponen 1tidak boleh dicetak. Dan tidak, trailing *juga menentang itu. Jika seseorang dapat memilih format output yang bebas, maka factor(1)membayar adalah yang termudah. Jawaban hanya dapat dibandingkan secara wajar jika mereka semua memecahkan masalah yang sama.
Joey

3
Sebagai pencipta tugas ini, saya katakan, bahwa eksponen harus dihilangkan jika 1 dan hanya bilangan prima yang dapat menjadi faktor.
FUZxxl


0

PHP, 93 byte

<?=$n=$argn;for($i=2;$n>1;$k&&$p=print($p?"*":"=")."$i^$k",$i++)for($k=0;$n%$i<1;$n/=$i)$k++;

Saya bisa melakukan 89 byte dengan PHP 5.5 (atau lebih baru), tetapi itu lebih dari 2 tahun setelah tantangan:

<?=$n=$argn;for($i=2;$n>1;$k&&$p=print"=*"[$p]."$i^$k",$i++)for($k=0;$n%$i<1;$n/=$i)$k++;

Jalankan sebagai pipa dengan -nFatau coba online .

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.