Asal faktörleri bulun


23

Bu görevde, bir sayının asal çarpanlarını hesaplayan bir program yazmalısınız. Giriş doğal bir sayı 1 <n <2 ^ 32. Çıktı, aşağıdaki biçimde sayının asal çarpanlarının bir listesidir. Üstler 1 ise ihmal edilmelidir. Yalnızca çıkış asal sayıları. (Girişin 131784 olduğunu varsayarak):

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

Aynı miktarda boşluk kullanılması gerekmez; Boşluk, uygun olan her yere yerleştirilebilir. Herhangi bir giriş için programınız 10 dakikadan az bir sürede tamamlanmalıdır. En kısa karaktere sahip olan program kazanır.


9
Programınız faktörü etkileyebilirse, Bonus puanları 68575999143494039776547449671727581799041142646129473261271699761332964802646422540197954027546706603707707647647507647647507647647507647647507647647507647647507647647647647647647647647647647647647647647647647647647647647647647647647647647647646476464764647646476464764647646476464764647646476464764647646476464764647646464646
Joey Adams

Joey Adams: Faktoring, 17 * 71 * 113 * 997 * 313597 ile başlıyor ...
FUZxxl

3
@ FUZxxl: Numarayı kopyalarken bir hata yaptınız. Bu var iki büyük asal ürünü .
Joey Adams

@Joey Shor's Algoritmasını kullanabilir miyiz?
Mateen Ulhaq

23
@Joey Yanlışlıkla kuantum bilgisayarıma bir miktar kahve döktüm ve arkadaşım onu ​​“ABD Hükümeti'ne sızmak” için ya da önemsiz bir şey için kullanıyor, yani, hayır. :(
Mateen Ulhaq

Yanıtlar:


11

SageMath, 31 Bayt

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

Test durumu: 83891573479027823458394579234582347590825792034579235923475902312344444 Çıkışlar:

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


İlk görevinle iyi iş çıkardın! Ve siteye hoş geldiniz!
DJMcMayhem

8

Yakut 1.9, 74 70 karakter

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

Düzenlemeler:

  • (74 -> 70) Sadece üst öğeyi açıkça denetlemek yerine dilim uzunluğu olarak kullanın exponent > 1

7

Perl 5.10, 73 88

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

Giriş numarasını standart girişten alır. Sağlandığı takdirde çoklu giriş faktörlerini hesaplar.

Fark olarak sayılır perl -e. \KRegex metacharacter için 5,10 gereklidir .


Kullanmak için +1 factor.
st0le

Eğer saymak gerekmez pseçeneği?
Joey

@ Joey gerçekten yapmalıyım. Bunun için üzgünüm. Tamir ediyorum.
JB

Bunu test etmedim, ama bunun yerine split/\D/,~factor $_~;$_="@_";yazabilir $_=~factor $_~;s/\D/ /g;misiniz? (Tabii ki ~backtick ile değiştirin .)
Timwi

Demek $_=`factor $_`;s/\D/ /g;istiyorsun İkili backtick encasing yardımcı olur.
aaaaaaaaaaaa 09:11

5

OCaml, 201 karakter

En iyi Python kodunun doğrudan zorunlu çevirisi:

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

Örneğin,

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

(son bitiş satırını çıkarmayı ihmal etmediğimi not edin.) Sadece eğlence için, 213 karakterde, tamamen işlevsel bir sürüm, operatörlerin liberal kullanımı yoluyla iyice gizlenmiş:

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

Bence çıktı biraz daha fazla alan gerektiriyor, mesela ' * %d'... Ve iki şey daha 65536 == 4**8:; Satır 7:if e:s+='*%d'%f+'^%d'%e*(e>1)
Oleh Prypin

@ Blapirit: "aynı miktarda boşluk gerekli değildir". Diğer ikisi için teşekkürler, onları birleştireceğim.
Keith Randall

5

J, 72

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

Tipik J. İşin çoğunu yapmak için iki karakter, onu sunmak için altmış karakter.

Düzenleme: Karakter sayımı düzeltildi.


2
Bu bana 62 karakter gibi görünmüyor. 161784Senin girişin olsa bile , hala 72 karakter.
Ventero

Daha kısa olmaz mıydı |: __ q: y?
Eelvex

2
@Vero: tipik JB. Lanet olası şeyi golf oynamak için iki saat, karakter sayımını karıştırmak için 15 saniye.
JB,

5

J, 53 52 karakter

Bu çözüm, rplcnumarayı randomranın çözümünden alıyor ama aynı zamanda bazı özgün fikirler ortaya çıkıyor.

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

Yapışkan olmayan gösterimde bu işlev olur

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

nerede gtanımlanır

g =: 3 : 0
": {. y) , '^' , (": # y) , '*'
)
  • q: yvektörü asal faktörlerin arasında y. Örneğin, q: 60verim 2 2 3 5.
  • x u/. ygeçerlidir uiçin y anahtarlı ile x, ki, uelemanların vektörleri uygulandığı yolan girişler xeşittir. Bu açıklamak biraz karmaşık olmakla birlikte, özel bir durumda y u/. yya da u/.~ y, ubelirgin elemanlarının her vektör uygulanan yher bir elemanı, genellikle içinde göründüğü kadar tekrar edilir, y. Örneğin, </.~ 1 2 1 2 3 1 2 2 3verimler

    ┌─────┬───────┬───┐
    │1 1 1│2 2 2 2│3 3│
    └─────┴───────┴───┘
    
  • # yolduğu taksitli ait yolduğunu, içinde öğelerin sayısı y.

  • ": y ybir dize olarak biçimler .
  • x , y ekler x ve y.
  • {. yolan baş y olduğunu, ilk öğe.
  • Bu nedenle, k sayısının n tekrarı (": {. y), '^' , (": # y) , '*'vektörünü k ^ n * biçiminde bir dizgeye formatlar . Zımni gösterimde Bu tabir olduğunu biz zarf geçmek, hangi ayrıca yukarıda açıklanan.:@{.,'^','*',~":@#/.
  • x rplc yKütüphane işlevi karakterleri değiştirir. yforma sahiptir a ; bve dizenin her örneğini aiçinde xdeğiştirilir b. xBurada kullanılan operasyon yapılmadan önce, (1 'e göre yeniden şekillendirilmiş) yeniden şekillendirilir. Bu kod değiştirir ^1*ile *görevlendirilmiş çıkış biçimi uymak olarak.
  • }: yolan bir kısaltma ait ytüm ancak son öğeyi olduğunu. Bu izleri kaldırmak için kullanılır *.

Kullanarak çok iş kurtaramaz mıydınız __ q:? Çevrimiçi deneyin!
Adám

@ Adám Gerçekten, iyi fikir!
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 Karakterler

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
İlk denemem gereken şey buydu, ama büyük asallar için çok yavaş, 4294967291 gibi.
Keith Randall

@Keith Soru 10 dakikaya kadar izin veriyor. Bu en kötü durum için 10 dakikadan fazla sürer mi?
fR0DDY

2
Makinemde bu numara için 32 dakika sürdü.
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)

^ 1'leri seçmek için Perl 5.14'ün s /// r özelliğini kullanır. Döngüde çalıştırılacak 81 karakter:

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

İsterseniz boşlukları bırakabilirsiniz. Bu iki karakter kaydeder. Güzel çözüm!
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);

131784 için çıktı: 2 ^ 3 * 3 * 17 ^ 2 * 19

Test sırasında tüm numaraları birkaç saniye içinde tamamlar.

4294967296=2^32
Time: 0.000168

Giriş hiçbir zaman belirtilmedi, bu yüzden komut satırı argümanlarını kullanarak aramayı seçtim.

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

Değişken değişkenli 64 karakter x:

   x=.131784

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

Bunu tam bir tanımlamaya dönüştürmeyi başarırsanız, tüm tekliflerden kaçmayı önleyebilirsiniz. Bir 3 : 0tanım da kullanabilirsiniz .
FUZxxl

@ FUZxxl Sadece sürümdeki unescaped dizgiyi koyabileceğimi umuyordum 3 : 0ama biraz işe yaramadı. Yine de zımni deneyebilirim. Bu 3: 0 denedim: pastebin.com/rmTVAk4j .
randomra

İşe yaramalı. Neden olduğunu anlamıyorum. Argümanını ygerektiği gibi adlandırdın mı?
FUZxxl

@ FUZxxl Bu 3: 0 denedim: pastebin.com/rmTVAk4j .
randomra

Denediğiniz 3: 0, sağladığınız tek gömlek ile tam olarak uyuşmuyor. Tek bir yerde ''yerine kullanır a:. Belki fark budur?
FUZxxl

2

Java 10, 109 108 bayt (lambda işlevi) (OP isteği üzerine rekabet etmeyen)

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

Çevrimiçi deneyin.

Java 6+, 181 bayt (tam program)

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

Çevrimiçi deneyin.

@Ceilingcat sayesinde -1 bayt .

Açıklama:

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 Teşekkürler!
Kevin Cruijssen

Bu görev yayınlandıktan sonra Java 10 olarak diskalifiye edildi.
FUZxxl

@ Javaxxl Java 10 lambda'yı rakipsiz olarak işaretledim ve Aralık 2006'da piyasaya sürülen bir Java 6 programı ekledim .
Kevin Cruijssen

Peki tamam. Bu benim için çalışıyor!
FUZxxl

2

Japt , 28 27 26 bayt

Shaggy sayesinde -1 bayt

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

Dene


Diliniz bu görev yayınlandıktan sonra oluşturulduğundan diskalifiye edildi.
FUZxxl


Mücadelenin yayınlandığı zaman geri alınmasına izin verilmedi. Meydan okuma yapıldıktan sonra bir meydan okuma kurallarının değiştirilmesinin haksız olduğunu düşünüyorum, bu yüzden bu meydan okumadan sonra yayınlanan diller yasadışı kalıyor.
FUZxxl

1
@FUZxxl Cevabımı kabul etmek zorunda değilsin, ama ne olursa olsun cevap vereyim.
Oliver


1

Powershell, 113 97 bayt

Joey'in cevabından ilham aldı . Yavaş ama kısa.

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

Açıklanan test komut dosyası:

$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

Çıktı:

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

1

Jöle , 16 bayt (OP talebi üzerine rekabet etmeyen)

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

Benim ilk Jelly cevaplarımdan biri, bu yüzden kesinlikle (özellikle ³”=³) golf edilebilir .

Çevrimiçi deneyin.

Açıklama:

³                 # 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)

Diliniz bu görev yayınlandıktan sonra oluşturulduğundan diskalifiye edildi.
FUZxxl

@ FUZxxl 2017 yılının ortalarından beri rekabet etmemek artık metada dahil değil , çünkü zorluk açıkça dillerin ilan süresinden daha eski olması gerektiğini belirtmediği sürece. Ancak, meydan okumayı yayınlayanlardan biri olarak, sınav tarihinizden daha yeni olan dillere izin vermemeyi tercih ederseniz, cevapları açık bir şekilde eklemek için düzenlerim (non-competing). :)
Kevin Cruijssen

Bu zorluğun yayınlandığı tarihte yapılan site görüş birliğinin cevap kurallarını tanımlaması gerektiğine inanıyorum. Diğer her şey (yani görev yüklendikten sonra değişen kurallar) haksızlık olur. Lütfen cevaplarınızı rakipsiz olarak işaretleyin.
FUZxxl

@ FUZxxl Cevaplarımı istenildiği gibi rakipsiz olarak işaretledim.
Kevin Cruijssen

Yardımın için teşekkürler.
FUZxxl

1

05AB1E , 22 20 bayt (OP'nin talebi üzerine yarışmaz )

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

@Emigna sayesinde -2 bayt .

Çevrimiçi deneyin.

Açıklama:

Ð                # 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)

1Kdöngüde `≠ iy yerine çalışmalı .
Emigna

@Emigna Ah lol .. Aslında bunu Jelly cevabımda henüz yayınladım . Bundan daha önce neden düşünemediğimden emin değilim. :)
Kevin Cruijssen

Diliniz bu görev yayınlandıktan sonra oluşturulduğundan diskalifiye edildi.
FUZxxl

1

APL (NARS), 66 karakter, 132 bayt

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

test et ve yorum yap:

  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

eğer birileri bu ilkellerle çok zaman geçirirse, onları çok iyi tanırlar, benim için kodun yorumların daha net olması mümkündür ... bu yüzden kod yorumlardan daha açık, kullanışsız yorumlar ...


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
Bir sondaki Has *çıktı ve 1. olsa bile üs basar
Ventero

Oy kullanmaya gerek yok. Üstelik üsse 1'i basamayacağını söyleyen hiçbir yer yok. Ayrıca, izleyen *çarparak varsayar 1. Bu kadar büyük bir sorun varsa, düzelteceğim.
zzzzBov

1
»Aşağıdaki biçimde« görev tanımında, bir üssünün 1basılmaması gerektiğini belirtir . Ve hayır, bir iz *de buna karşı. Biri serbestçe çıkacak çıktı formatını seçebilse factor(1), en kolay olanı çıkarmak . Cevaplar ancak hepsi aynı sorunu çözerse makul bir şekilde karşılaştırılabilir.
Joey,

3
Bu görevin yaratıcısı olarak, üstatların 1 ve sadece asal sayılar faktör olabilirse ihmal edilmesi gerektiğini söylüyorum.
FUZxxl


0

PHP, 93 bayt

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

PHP 5.5 (veya daha yenisi) ile 89 bayt yapabilirim, ancak bu zorluk 2 yıldan fazla sürüyor:

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

Pipe ile çalıştırın -nFveya çevrimiçi deneyin .

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.