Trova i fattori primi


23

In questa attività, devi scrivere un programma, che calcola i fattori primi di un numero. L'ingresso è un numero naturale 1 <n <2 ^ 32. L'output è un elenco dei fattori primi del numero nel seguente formato. Gli esponenti devono essere omessi se sono 1. Emettono solo numeri primi. (Supponendo che l'ingresso sia 131784):

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

Non è necessario utilizzare la stessa quantità di spazi bianchi; spazi bianchi possono essere inseriti ove appropriato. Il programma dovrebbe essere completato in meno di 10 minuti per qualsiasi input. Vince il programma con il minor numero di personaggi.


9
Punti bonus se il tuo programma può calcolare 6857599914349403977654744967172758179904114264612947326127169976133296980951450542789808884504301075550786464802304019795402754670660318614966266413770127 in meno di 73!
Joey Adams,

@Joey Adams: la fattorizzazione inizia con 17 * 71 * 113 * 997 * 313597 ...
FUZxxl

3
@FUZxxl: Penso che tu abbia commesso un errore nel copiare il numero. È il prodotto di due numeri primi grandi .
Joey Adams,

@Joey Possiamo usare l'algoritmo di Shor?
Mateen Ulhaq,

23
@Joey Ho accidentalmente rovesciato del caffè sul mio computer quantistico, e il mio amico sta usando il suo per "hackerare il governo degli Stati Uniti" o qualcosa di irrilevante, quindi no. :(
Mateen Ulhaq,

Risposte:


11

SageMath, 31 byte

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

Caso di prova: 83891573479027823458394579234582347590825792034579235923475902312344444 uscite:

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


Complimenti per aver vinto una sfida con il tuo primo post, bel lavoro! E benvenuti nel sito!
DJMcMayhem

8

Ruby 1.9, 74 70 caratteri

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

modifiche:

  • (74 -> 70) Usa l'esponente come lunghezza della sezione invece di controllare esplicitamente exponent > 1

7

Perl 5.10, 73 88

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

Prende il numero di input dall'input standard. Calcolerà i fattori per più input, se forniti.

Contava come una differenza perl -e. 5.10 è necessario per il \Kmetacarattere regex.


+1 per l'utilizzo factor.
via

Non dovresti contare l' popzione?
Joey,

@Joey davvero dovrei. Mi dispiace per quello. Fissaggio.
JB

Non hai provato questo, ma invece di split/\D/,~factor $_~;$_="@_";scrivere $_=~factor $_~;s/\D/ /g;? (Ovviamente sostituirlo ~con il backtick.)
Timwi

Intendi $_=`factor $_`;s/\D/ /g;? La doppia incastonatura posteriore aiuta.
aaaaaaaaaaaa

5

OCaml, 201 caratteri

Una traduzione imperativa diretta del miglior codice Python:

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

Per esempio,

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

(nota che ho omesso di presentare la linea finale). Solo per divertimento, con 213 caratteri, una versione puramente funzionale, completamente offuscata dall'uso liberale degli operatori:

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 caratteri

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

Penso che l'output richieda più spazi, ad es. ' * %d'... E altre due cose 65536 == 4**8:; Linea 7:if e:s+='*%d'%f+'^%d'%e*(e>1)
Oleh Prypin

@BlaXpirit: "non è richiesta la stessa quantità di spazi bianchi". Grazie per gli altri due, li incorporerò.
Keith Randall,

5

J, 72

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

Tipico J. Due personaggi per fare la maggior parte del lavoro, sessanta personaggi per presentarlo.

Modifica: risolto il conteggio dei personaggi.


2
Non mi sembrano 62 caratteri. Anche se supponiamo che 161784sia il tuo input, sono comunque 72 caratteri.
Ventero,

Non sarebbe più corto con |: __ q: y?
Eelvex,

2
@Ventero: tipico JB. Due ore per giocare a golf a quel dannato affare, quindici secondi per rovinare il conteggio dei personaggi.
JB,

5

J, 53 52 caratteri

Questa soluzione prende il rplctrucco dalla soluzione di randomra ma presenta anche alcune idee originali.

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

Nella notazione non tacita, questa funzione diventa

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

dove gè definito come

g =: 3 : 0
": {. y) , '^' , (": # y) , '*'
)
  • q: yè il vettore dei fattori primi di y. Ad esempio, i q: 60rendimenti 2 2 3 5.
  • x u/. yvale ua y keyed da x, che viene, uviene applicato a vettori di elementi yper i quali le voci xsono uguali. Questo è un po 'complesso da spiegare, ma nel caso speciale y u/. yo u/.~ y, uviene applicato a ciascun vettore di elementi distinti in y, in cui ogni elemento viene ripetuto tutte le volte che appare y. Ad esempio, i </.~ 1 2 1 2 3 1 2 2 3rendimenti

    ┌─────┬───────┬───┐
    │1 1 1│2 2 2 2│3 3│
    └─────┴───────┴───┘
    
  • # yè il conteggio di y, cioè, il numero di elementi in y.

  • ": y formati y come una stringa.
  • x , y aggiunge x e y.
  • {. yè la testa y , cioè il suo primo oggetto.
  • Pertanto, (": {. y), '^' , (": # y) , '*'formatta un vettore di n ripetizioni di un numero k in una stringa della forma k ^ n *. Questa frase in notazione tacita è :@{.,'^','*',~":@#, che passiamo all'avverbio /.descritto più sopra.
  • x rplc yè la funzione di libreria sostituire i caratteri. yha la forma a ; bed ogni istanza di stringa aa xè sostituito da b. xè distrutto (cioè rimodellato in modo da avere il rango 1) prima che abbia luogo l'operazione, che viene utilizzata qui. Questo codice sostituisce ^1*con *da rispettare il formato di output mandato.
  • }: yè la riduzione di y, cioè, tranne il suo ultimo elemento. Questo è usato per rimuovere il finale *.

Non potresti risparmiare molto lavoro usando __ q:? Provalo online!
Adám,

@Adám In effetti, buona idea!
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
Questo è quello che ho provato per primo, ma è troppo lento per i numeri primi, come 4294967291.
Keith Randall,

@Keith La domanda richiede fino a 10 minuti. Questo richiederà più di 10 minuti nel caso peggiore?
fR0DDY,

2
Ci sono voluti 32 minuti sulla mia macchina per quel numero.
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)

Usa la funzione s /// r di Perl 5.14 per eludere i ^ 1s. 81 caratteri da eseguire in un ciclo:

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

Puoi lasciare gli spazi se vuoi. Ciò salverebbe due personaggi. Bella soluzione!
FUZxxl

2

PHP, 236 caratteri

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

Uscita per 131784: 2 ^ 3 * 3 * 17 ^ 2 * 19

Completa tutti i numeri in pochi secondi durante il test.

4294967296=2^32
Time: 0.000168

L'input non è mai stato specificato, quindi ho scelto di chiamarlo utilizzando gli argomenti della riga di comando.

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 caratteri

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

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

64 caratteri con input in variabile x:

   x=.131784

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

Se riesci a trasformarlo in una definizione tacita, puoi evitare di sfuggire a tutte le virgolette. Puoi anche usare una 3 : 0definizione.
FUZxxl,

@FUZxxl Mi aspettavo di poter inserire la stringa 3 : 0senza caratteri di escape nella versione, ma non ha funzionato in qualche modo. Potrei provare tacito più tardi però. Questo è il 3: 0 che ho provato: pastebin.com/rmTVAk4j .
randomra,

Dovrebbe funzionare. Non vedo perché. Hai chiamato la tua discussione ycome dovresti?
FUZxxl,

@FUZxxl Questo è il 3: 0 che ho provato: pastebin.com/rmTVAk4j .
randomra,

Il 3: 0 che hai provato non corrisponde esattamente al one-liner che fornisci. Usa ''invece che a:in un unico posto. Forse è questa la differenza?
FUZxxl,

2

Java 10, 109 108 byte (funzione lambda) (non competitiva su richiesta di 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;}

Provalo online.

Java 6+, 181 byte (programma completo)

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

Provalo online.

-1 byte grazie a @ceilingcat .

Spiegazione:

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 Grazie!
Kevin Cruijssen

Squalificato come Java 10 è stato creato dopo la pubblicazione di questa attività.
FUZxxl,

@FUZxxl Ho contrassegnato la Lambda Java 10 come non competitiva e ho aggiunto un programma Java 6, che è stato rilasciato nel dicembre 2006 .
Kevin Cruijssen,

Va bene, d'accordo. Per me va bene!
FUZxxl

2

Japt , 28 27 26 byte

-1 byte grazie a Shaggy

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

Provalo


Squalificato in quanto la tua lingua è stata creata dopo la pubblicazione di questa attività.
FUZxxl


Non è stato permesso di nuovo quando la sfida è stata pubblicata. Ritengo ingiusto modificare le regole di una sfida dopo che la sfida è stata pubblicata, quindi le lingue pubblicate dopo questa sfida rimangono illegali.
FUZxxl

1
@FUZxxl Non devi accettare la mia risposta, ma sono autorizzato a rispondere a prescindere.
Oliver,


1

Powershell, 113 97 byte

Ispirato dalla risposta di Joey . È lento ma corto.

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

Script di prova spiegato:

$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

Produzione:

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

1

Gelatina , 16 byte (non competitiva su richiesta di OP)

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

Una delle mie prime risposte di Jelly, quindi può sicuramente essere giocata a golf (soprattutto ³”=³) ..

Provalo online.

Spiegazione:

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

Squalificato in quanto la tua lingua è stata creata dopo la pubblicazione di questa attività.
FUZxxl,

@FUZxxl Dalla metà del 2017 la non competizione non è più nel meta , a meno che la sfida non stabilisca esplicitamente che le lingue dovrebbero essere più vecchie del tempo di pubblicazione. Ma se tu come colui che ha pubblicato la sfida decidi di non consentire lingue più recenti rispetto alla data della sfida successiva, modificherò le mie risposte per aggiungere l'esplicito (non-competing). :)
Kevin Cruijssen

Credo che il consenso del sito in atto al momento della pubblicazione di questa sfida dovrebbe definire le regole per le risposte. Tutto il resto (ovvero le regole che cambiano dopo la pubblicazione della sfida) sarebbe ingiusto. Si prega di contrassegnare le risposte come non concorrenti.
FUZxxl,

@FUZxxl Ho contrassegnato le mie risposte come non concorrenti, come richiesto.
Kevin Cruijssen,

Grazie per l'aiuto.
FUZxxl

1

05AB1E , 22 20 byte (non in competizione su richiesta di OP)

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

-2 byte grazie a @Emigna .

Provalo online.

Spiegazione:

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

1Kdovrebbe funzionare invece di `≠ iy in the loop.
Emigna

@Emigna Ah lol .. Lo faccio davvero nella mia risposta Jelly che ho appena pubblicato . Non sono sicuro del perché non ci abbia pensato prima qui. :)
Kevin Cruijssen

Squalificato in quanto la tua lingua è stata creata dopo la pubblicazione di questa attività.
FUZxxl,

1

APL (NARS), 66 caratteri, 132 byte

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

testare e commentare:

  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

se qualcuno ha molto tempo con questi primitivi, conoscili molto bene, per me è possibile che il codice sia più chiaro di commenti ... quindi codice più chiaro di commenti, commenti inutili ...


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
Ha un finale *nell'output e stampa l'esponente anche se è 1.
Ventero

non è necessario il voto negativo. Non c'è nulla che abbia detto che non potrebbe stampare l'esponente se è 1. Inoltre, il trailing *presuppone che si moltiplichi per 1. Se è un grosso problema, lo risolverò.
zzzzBov,

1
»Nel seguente formato« nella descrizione dell'attività praticamente implica che un esponente di 1non dovrebbe essere stampato. E no, anche un finale *è contrario. Se uno potesse scegliere il formato di output che liberamente, quindi sborsare factor(1)sarebbe il più semplice. Le risposte possono essere ragionevolmente confrontate solo se risolvono tutti lo stesso problema.
Joey,

3
Come creatore di questo compito, dico, che gli esponenti devono essere omessi se 1 e solo i numeri primi possono essere fattori.
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++;

Potrei fare 89 byte con PHP 5.5 (o successivo), ma questo postdatava la sfida di oltre 2 anni:

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

Esegui come pipe -nFo provali online .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.