Encuentra los factores primos

23

En esta tarea, debe escribir un programa que calcule los factores primos de un número. La entrada es un número natural 1 <n <2 ^ 32. El resultado es una lista de los factores primos del número en el siguiente formato. Los exponentes se deben omitir si son 1. Solo emiten números primos. (Suponiendo que la entrada es 131784):

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

No se requiere usar la misma cantidad de espacio en blanco; se puede insertar un espacio en blanco cuando sea apropiado. Su programa debería completarse en menos de 10 minutos para cualquier entrada. El programa con la menor cantidad de caracteres gana.

FUZxxl
fuente
99
Puntos de bonificación si su programa puede factorizar 6857599914349403977654744967172758179904114264612947326127169976133296980951450542789808884504301075550786464802304019795402754670660318614966266413770127 en menos de 3 días.
Joey Adams
@Joey Adams: La factorización comienza con 17 * 71 * 113 * 997 * 313597 ...
FUZxxl
3
@FUZxxl: Creo que cometiste un error al copiar el número. Es el producto de dos grandes números primos .
Joey Adams
@Joey ¿Podemos usar el algoritmo de Shor?
Mateen Ulhaq
23
@Joey Derramé accidentalmente un poco de café sobre mi computadora cuántica, y mi amigo está usando la suya para "piratear el gobierno de los Estados Unidos" o algo sin importancia, así que no. :(
Mateen Ulhaq

Respuestas:

11

SageMath, 31 Bytes

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

Caso de prueba: 83891573479027823458394579234582347590825792034579235923475902312344444 Salidas:

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

12431234123412341234123
fuente
Felicidades por ganar un desafío con tu primera publicación, ¡buen trabajo! ¡Y bienvenido al sitio!
DJMcMayhem
8

Ruby 1.9, 74 70 caracteres

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

Ediciones:

  • (74 -> 70) Simplemente use el exponente como longitud de corte en lugar de verificar explícitamente exponent > 1
Ventero
fuente
7

Perl 5.10, 73 88

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

Toma el número de entrada de la entrada estándar. Calculará factores para múltiples entradas si se proporcionan.

Cuenta como una diferencia para perl -e. 5.10 es necesario para el \Kmetacarácter regex.

JB
fuente
+1 por usar factor.
st0le
¿No deberías contar la popción?
Joey
@Joey de hecho debería. Lo siento por eso. Fijación.
JB
No he probado esto, pero en lugar de ¿ split/\D/,~factor $_~;$_="@_";podrías escribir $_=~factor $_~;s/\D/ /g;? (Por supuesto, reemplácelo ~con el backtick.)
Timwi
Quieres decir $_=`factor $_`;s/\D/ /g;? El revestimiento de doble backtick ayuda.
aaaaaaaaaaaa
5

OCaml, 201 caracteres

Una traducción imperativa directa del mejor código de 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

Por ejemplo,

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

(tenga en cuenta que he omitido la salida de la línea final.) Por diversión, con 213 caracteres, una versión puramente funcional, completamente ofuscada por el uso liberal de los operadores:

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
Matías Giovannini
fuente
5

Python, 140 135 133 caracteres

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:]
Keith Randall
fuente
Creo que la salida requiere algunos espacios más, por ejemplo ' * %d'... Y dos cosas más: 65536 == 4**8; Línea 7:if e:s+='*%d'%f+'^%d'%e*(e>1)
Oleh Prypin el
@BlaXpirit: "no se requiere la misma cantidad de espacios en blanco". Gracias por los otros dos, los incorporaré.
Keith Randall el
5

J, 72

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

Típico J. Dos personajes para hacer la mayor parte del trabajo, sesenta personajes para presentarlo.

Editar: se corrigió el recuento de caracteres.

JB
fuente
2
Esto no parece 62 personajes para mí. Incluso suponiendo que 161784sea ​​su entrada, sigue siendo 72 caracteres.
Ventero
¿No sería más corto con |: __ q: y?
Eelvex
2
@Ventero: típico JB. Dos horas para jugar al golf, quince segundos para desordenar el recuento de personajes.
JB
5

J, 53 52 caracteres

Esta solución toma el rplctruco de la solución de randomra pero también presenta algunas ideas originales.

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

En notación no tácita, esta función se convierte en

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

donde gse define como

g =: 3 : 0
": {. y) , '^' , (": # y) , '*'
)
  • q: yes el vector de factores primos de y. Por ejemplo, q: 60rendimientos 2 2 3 5.
  • x u/. yse aplica ua y keyed by x, es decir, use aplica a vectores de elementos ypara los que las entradas xson iguales. Esto es un poco complejo de explicar, pero en el caso especial y u/. yo u/.~ y, use aplica a cada vector de elementos distintos en y, donde cada elemento se repite tantas veces como aparece y. Por ejemplo, </.~ 1 2 1 2 3 1 2 2 3rendimientos

    ┌─────┬───────┬───┐
    │1 1 1│2 2 2 2│3 3│
    └─────┴───────┴───┘
    
  • # yes el recuento de y, es decir, el número de elementos en y.

  • ": y formatos y como una cadena.
  • x , y Anexa x y y.
  • {. yes la cabeza y , es decir, su primer artículo.
  • Por lo tanto, (": {. y), '^' , (": # y) , '*'formatea un vector de n repeticiones de un número k en una cadena de la forma k ^ n *. Esta frase en notación tácita es :@{.,'^','*',~":@#, que pasamos al adverbio /.descrito más arriba.
  • x rplc yEs la función de la biblioteca reemplazar caracteres. ytiene la forma a ; by cada instancia de secuencia aen xse sustituye por b. xse desmorona (es decir, se reforma de tal manera que tenga rango 1) antes de que se realice la operación, que se utiliza aquí. Este código reemplaza ^1*con *respecto a cumplir con el formato de salida de mandato.
  • }: yes la reducción de y, es decir, todos menos su último elemento. Esto se utiliza para eliminar el final *.
FUZxxl
fuente
¿No podrías ahorrar mucho trabajo usando __ q:? Pruébalo en línea!
Adám
@ Adám De hecho, ¡buena 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;}}
zzzzBov
fuente
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:]
fR0DDY
fuente
1
Eso es lo que probé primero, pero es demasiado lento para grandes números primos, como 4294967291.
Keith Randall
@Keith La pregunta permite hasta 10 minutos. ¿Tardará más de 10 minutos en el peor de los casos?
fR0DDY
2
Tomó 32 minutos en mi máquina para ese número.
Keith Randall el
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))
Ry-
fuente
3

Perl, 78

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

Utiliza la función s /// r de Perl 5.14 para eludir los ^ 1s. 81 caracteres para ejecutar en un bucle:

perl -Mntheory=:all -nE 'chomp;say join" * ",map{(join"^",@$_)=~s/\^1$//r}factor_exp($_);'
DanaJ
fuente
Puedes dejar los espacios si quieres. Esto salvaría a dos personajes. Buena solución!
FUZxxl
2

PHP, 236 caracteres

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

Salida para 131784: 2 ^ 3 * 3 * 17 ^ 2 * 19

Completa todos los números en unos pocos segundos durante la prueba.

4294967296=2^32
Time: 0.000168

La entrada nunca se especificó, por lo que elegí llamarla usando argumentos de línea de comando.

php factorize.php 4294967296
Kevin Brown
fuente
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("", "*", "")

sin golf:

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 ("", "*", "")
usuario desconocido
fuente
2

J, 74 caracteres

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

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

64 caracteres con entrada en variable x:

   x=.131784

   (":x),'=',' '-.~('^1 ';'')rplc~}:,,&' *'"1(,'^'&,)&":/"{|:__ q:x
131784=2^3*3*17^2*19
randomra
fuente
Si logra convertir esto en una definición tácita, puede evitar escapar de todas las citas. También podría usar una 3 : 0definición.
FUZxxl
@FUZxxl Esperaba poder poner la cadena sin escape en la 3 : 0versión, pero no funcionó de alguna manera. Aunque podría intentar tácito más tarde. Este es el 3: 0 que probé: pastebin.com/rmTVAk4j .
randomra
Deberia de funcionar. No veo porque. ¿Has nombrado tu argumento ycomo se supone que debes hacerlo?
FUZxxl
@FUZxxl Este es el 3: 0 que probé: pastebin.com/rmTVAk4j .
randomra
El 3: 0 que probó no coincide exactamente con la línea que proporciona. Se utiliza en ''lugar de a:en un solo lugar. Tal vez esa es la diferencia?
FUZxxl
2

Java 10, 109108 bytes (función lambda) (no competitiva a petición de 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;}

Pruébalo en línea.

Java 6+, 181 bytes (programa 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);}}

Pruébalo en línea.

-1 byte gracias a @ceilingcat .

Explicación:

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
Kevin Cruijssen
fuente
@ceilingcat Gracias!
Kevin Cruijssen
Descalificado como Java 10 se creó después de que se publicó esta tarea.
FUZxxl
@FUZxxl Marqué el lambda de Java 10 como no competitivo, y agregué un programa Java 6, que se lanzó en diciembre de 2006 .
Kevin Cruijssen
De acuerdo, genial. ¡Funciona para mi!
FUZxxl
2

Japt , 28 27 26 bytes

-1 byte gracias a Shaggy

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

Intentalo

Oliver
fuente
Descalificado ya que su idioma fue creado después de que se publicó esta tarea.
FUZxxl
1
@FUZxxl Está permitido usar un idioma más nuevo en un desafío anterior
Oliver
No se permitió volver cuando se publicó el desafío. Considero que es injusto enmendar las reglas de un desafío después de que el desafío se haya publicado, por lo que los idiomas publicados después de este desafío siguen siendo ilegales.
FUZxxl
1
@FUZxxl No tiene que aceptar mi respuesta, pero sí puedo responderla de todos modos.
Oliver
1
24 bytes
Shaggy
1

Powershell, 113 97 bytes

Inspirado por la respuesta de Joey . Es lento pero corto.

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

Script de prueba explicado:

$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

Salida:

2
2*3^2*7
3*43
2^5*5*7^2*11
mazzy
fuente
1

Jalea , 16 bytes (no compite a petición de OP)

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

Una de mis primeras respuestas de Jelly, por lo que definitivamente se puede jugar al golf (especialmente ³”=³ ).

Pruébalo en línea.

Explicación:

³                 # 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)
Kevin Cruijssen
fuente
Descalificado ya que su idioma fue creado después de que se publicó esta tarea.
FUZxxl
@FUZxxl Desde mediados de 2017, la no competencia ya no está en el meta , a menos que el desafío establezca explícitamente que los idiomas deben ser anteriores al momento de la publicación. Pero si usted, como el que publicó el desafío, elige no permitir idiomas más nuevos que la fecha posterior al desafío, editaré mis respuestas para agregar el explícito (non-competing). :)
Kevin Cruijssen
Creo que el consenso del sitio que existía cuando se publicó este desafío debería definir las reglas para las respuestas. Todo lo demás (es decir, las reglas que cambian después de que se publicó el desafío) sería injusto. Por favor marque sus respuestas como no competidoras.
FUZxxl
@FUZxxl He marcado mis respuestas como no competidoras, según lo solicitado.
Kevin Cruijssen
Gracias por tu ayuda.
FUZxxl
1

05AB1E , 22 20 bytes (no competidor a pedido de OP)

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

-2 bytes gracias a @Emigna .

Pruébalo en línea.

Explicación:

Ð                # 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)
Kevin Cruijssen
fuente
1Kdebería funcionar en lugar de `≠ iy en el bucle.
Emigna
@Emigna Ah lol .. De hecho, hago eso en mi respuesta Jelly que acabo de publicar . No estoy seguro de por qué no lo pensé antes aquí. :)
Kevin Cruijssen
Descalificado ya que su idioma fue creado después de que se publicó esta tarea.
FUZxxl
1

APL (NARS), 66 caracteres, 132 bytes

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

prueba y comentario:

  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

si alguien tiene mucho tiempo con estas primitivas, conócelas muy bien, para mí es posible que el código sea más claro de comentarios ... así que codifica más claro que comentarios, comentarios inútiles ...

RosLuP
fuente
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)
zzzzBov
fuente
1
Tiene un final *en la salida e imprime el exponente incluso si es 1.
Ventero
No hay necesidad de votar abajo. No hay ningún lugar que diga que no podría imprimir el exponente si es 1. Además, el final *supone multiplicar por 1. Si es un problema tan grande, lo arreglaré.
zzzzBov
1
»En el siguiente formato« en la descripción de la tarea implica que 1no debe imprimirse un exponente de . Y no, un rastro *también está en contra de eso. Si uno pudiera elegir el formato de salida libremente, factor(1)sería más fácil hacerlo . Las respuestas solo se pueden comparar razonablemente si todas resuelven el mismo problema.
Joey
3
Como creador de esta tarea, digo, que los exponentes deben omitirse si 1 y solo los números primos pueden ser factores.
FUZxxl
0

PHP , 112 bytes

<?=$a=$argn,"=";for($i=2;1<$a;)$a%$i?$i++:$a/=$i+!++$r[$i];foreach($r as$k=>$v)echo$t?"*":!++$t,$v<2?$k:"$k^$v";

Pruébalo en línea!

Jörg Hülsermann
fuente
0

PHP, 93 bytes

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

Podría hacer 89 bytes con PHP 5.5 (o posterior), pero eso es posterior al desafío por más de 2 años:

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

Ejecutar como tubería -nFo probarlos en línea .

Tito
fuente