Imprima a fatoração primária do maior divisor comum de dois números


17

O título diz tudo. Dois inteiros positivos de 32 bits de entrada m, n >= 2, saída gcd(m,n)em forma de fatoração primária.

Entrada

Args da linha de comando ou 1 linha de stdin ok, o que for melhor para o golfe.

Resultado

Espaço único delimitado por expoentes (sem espaços adicionais). Não produza nada se as entradas forem relativamente primárias.

Exemplos:

$ ./factorize 96 162
2^1 3^1

$ ./factorize 14 15


$ ./factorize 196 294
2^1 7^2

Regras

  • Você não pode usar recursos externos, bibliotecas matemáticas ou funções internas para fatoração ou GCD. Exemplos: Java, no java.lang.Math. ruby, não prime_division, perl, não factor, etc.

11
Que saída você está procurando se gcd(n,m) == 1?
Undergroundmonorail

Tudo bem se eu sair com uma exceção? Isso me pouparia alguns bytes.
Undergroundmonorail

Na verdade, mudei de abordagem e não preciso sair com uma exceção. Outros podem querer saber, no entanto.
Undergroundmonorail

Não saia com uma exceção. Saída nada :)
durron597

Tecnicamente, q:a+.bou __ q:a+.bem J não usa external resources or math libraries, mas não vou publicá-lo, pois está muito longe do espírito da pergunta. Eu apenas pensei em compartilhar aqui.
ɐɔıʇǝɥʇuʎs

Respostas:


10

Python 3, 255 250 237 226 188 180 150 142 137 136 caracteres

a,b=map(int,input().split())
t,g='',1
while g<a:
 g,p=g+1,0
 if a%g+b%g<1:
  while a%g+b%g<1:a/=g;b/=g;p+=1
  t+='%d^%d '%(g,p)
print(t)

É incrível o quanto eu poderia encurtar isso apenas pulando coisas (como, você sabe, encontrando o gcd)! Também eu poderia reduzir mais 10 caracteres, tornando isso uma função que espera 2 polegadas, como algumas outras respostas, em vez de ler a partir de stdin.


Isso é intenso! Estou aprendendo muito assistindo suas edições e tentando bater em você, lol. Eu acho que você pode ter um presente que (fora das respostas Python)
Rainbolt

11
Você pode salvar 1 caractere alterando while g<a and g<b:parawhile(g<a)*(g<b):
Rainbolt

@Rusher Obrigado companheiro! A sua resposta é o que me motivou a trabalhar mais neste :) Também o truque que você recomendado me inspirou a descobrir a a%g+b%gpouco
Tal

Não acho que a cláusula else seja necessária. else:g+=1poderia ser g+=1, a menos que eu esteja perdendo alguma coisa.
Isaacg

@isaacg Você parece estar certo, obrigado!
Tal

8

Ruby - 168 117 114 101 100 97

Edit: Depois de pensar sobre isso, percebi que não precisava da peneira, já que a primalidade do fator é tratada no ciclo de fatoração. Além disso, conforme informado pelas respostas de outras pessoas (as de Laindir e Tal são as que eu já tinha visto, embora pareça que outras pessoas também o fizeram), removeram o cálculo separado do MDC, pois isso também ocorre na fatoração.
Edit 2: Não precisa do.
Edit 3: Apertando-o mais.
Edit 4: Puxou mais um espaço.
Editar 5: em uptovez de each; ?^ == "^"!

a,b=ARGV.map{|i|i.to_i}
2.upto(a){|d|c=0
[c+=1,a/=d,b/=d]while a%d+b%d<1
print d,?^,c," "if c>0}

Saída (o mesmo após a edição):

$ ruby factorize.rb 96 162
2^1 3^1 
$ ruby factorize.rb 14 15

$ ruby factorize.rb 196 294
2^1 7^2 

Certamente poderia ser melhorado, mas não ruim para o meu primeiro.


Você pode remover 4 bytes mudando map{|i|i.to_i}para map &:to_i. Você pode remover um 5º byte sem contar a nova linha no final do arquivo; Ruby funciona sem ele.
kernigh

Além disso, você pode usar em $*vez de ARGV.
Daniero 11/05

6

Python 2 - 254 252 196 185 156 151 134 126 121

i=1
a,b=map(int,raw_input().split())
while b:a,b=b,a%b
while~-a:
 i+=1;j=0
 while a%i<1:j+=1;a/=i
 if j:print`i`+'^'+`j`,

Intérprete

repl.it

Exemplo de entrada - stdin

100 50

Saída de exemplo - stdout

2 ^ 1 5 ^ 2


11
Que tal …`a`+'^'+`f.count(a)`…?
Ry-

Muito limpo, eu gosto
qwr

@qwr Obrigado. Espero poder entender as outras respostas em Python da formatação String e raspar alguns caracteres.
Rainbolt

Troque f.append(i)para f+=[i]salvar 5 caracteres.
Nolen Royalty

11
E agora você não precisa usar f em tudo: p (por que f=''ainda está aí?)
Nolen Royalty

4

Java - 184 175

Isso é inspirado na resposta do @Geobits (e um pouco da resposta do @ Tal), mas o suficiente é diferente que eu decidi criar minha própria resposta.

class G{public static void main(String[]a){for(Integer i=1,q,n=i.valueOf(a[0]),m=i.valueOf(a[1]);m>=++i;System.out.print(q>0?i+"^"+q+" ":""))for(q=0;n%i+m%i<1;n/=i,m/=i)q++;}}

Arnês de teste não testado (tipo de) com (verificação humana):

class G {
    public static void mainMethod(String[] a) {
        for (Integer i = 1, q, n = i.valueOf(a[0]), m = i.valueOf(a[1]); m >= ++i;
                 System.out.print(q > 0 ? i + "^" + q + " " : ""))
            for (q = 0; n % i + m % i < 1; n /= i, m /= i)
                q++;
    }

    public static void main(String[] a) {
        m(3, 3);
        m(196, 294);
        m(294, 196);
        m(14, 15);
        m(15, 14);
        m(96, 162);
        m(162, 96);
        m(300, 400);
        m(400, 300);
        m(100, 100);
        m(7, 7);
        m(4, 8);
    }

    public static void m(int one, int two) {
        mainMethod(new String[] { String.valueOf(one), String.valueOf(two) });
        System.out.println();
    }
}

4

dc, 96 bytes

?sbsa2sf[q]sk[lalf~lblf~szrlz+0<ksbsale1+selsx]ss[lfn[^]Plen[ ]P]sp[0selsxle0<plf1+dsflb!<w]dswx

Ele lê uma linha de entrada padrão. Sua saída não termina com uma nova linha. (EDIT: Ele também gera um espaço extra após cada fatoração. Algumas das outras respostas diminuem o espaço, mas essa não.)

Exemplo:

$ echo 301343045 421880263 | dc factorize.dc
1021^1 59029^1 $ 

Código com comentários:

# dc(1) is a stack language, like Forth. Programs push values on the
# stack, then operate on them. For example, to calculate
#  (2 + 3) * (9 - 4)
# the dc code is
#  [2 3 + 9 4 - *]

# [?] reads a line of input.  We expect two integers >= 2.
# [sb sa] stores the integers in variables.
? sb sa     # a, b = two integers from input

# This program sucks common factors from a and b, looping for
# f = 2, 3, 4, 5, and so on.  This method only sucks prime factors,
# but wastes time when f is not prime.
2 sf        # f = 2

# Code in [...] does not run until the program calls it.

# k = code to break a loop
[
 q           # [q] breaks two levels of [...]
] sk        # k = break

# s = loop to suck factor f from a and b
#  This loop increments e, the exponent for factor f.
#  Please set e = 0 before entering this loop.
[
 # [la lf] puts ( a f ) on the stack.
 # [~] does division and remainder.
             # STACK:
 la lf ~     # ( a/f a%f )
 lb lf ~     # ( a/f a%f b/f b%f )

 # [r] swaps the top two stack values.
 # Hold z = b%f and swap a%f with b/f.
             # STACK:
 sz r lz     # ( a/f b/f a%f b%f )

 # f is a common factor if a%f and b%f are zero.  Because a and b are
 # non-negative, a%f and b%f are zero only if a%f+b%f is zero.
             # STACK:
 +           # ( a/f b/f a%f+b%f )

 # Call k to break loop unless a%f+b%f is zero.  [<k] conditionally
 # calls k if the comparison is true.  Comparisons in dc are
 # backwards, so [3 0 <k] would check 0 < 3.  Because a%f+b%f is never
 # negative, [0 <k] is golf for [0 !=k].
             # STACK:
 0 <k        # ( a/f b/f )

 # f is a common factor, so suck it!
 sb sa       # a = a/f, b = b/f, STACK: ( )
 le 1 + se   # increment e, the exponent for this factor
 ls x        # continue loop, [x] executes s
] ss        # s = loop

# p = code to print "f^e "
[
 # [n] prints a number without a newline.
 # [P] prints a string.
 lf n [^]P
 le n [ ]P

 # DEBUG: Uncomment to print a and b.
 #[(a = ]P la n [, b = ]P lb n [)]P 10P
] sp        # p = print

# w = loop to iterate factors
[
 # Call s loop to suck factor f from a and b, and set exponent e.
 0 se        # e = 0
 ls x        # call s loop

 # DEBUG: Uncomment [c] to clear the stack.  Loop s leaves two junk
 # values ( a/f b/f ) on the stack.  Deleting [c] for code golf saves
 # 1 byte but leaks junk on the stack.
 #c

 # Print "f^e " if 0 < e.  Comparisons in dc are backwards, so
 # [0 le <p] would check e < 0, [le 0 <p] checks 0 < e.
 le 0 <p

 # Increment f.  [d] duplicates top value on stack.
             # STACK:
 lf 1 +      # ( f+1 )
 d           # ( f+1 f+1 )
 sf          # ( f ) as f+1 becomes f

 # Continue loop if b >= f.  This is golf for f <= a and f <= b, as
 # extra iterations of the loop cause no harm.
             # STACK:
 lb          # ( f b )
 !<w         # ( ), continue loop if not b < f
] d sw      # w = loop; STACK: ( w )
x           # enter loop unconditionally; STACK: ( ) at entrance

3

PowerShell - 82

$a,$b=$args
2..$a|%{$p=0;while(!($a%$_+$b%$_)){$a/=$_;$b/=$_;$p++}if($p){"$_^$p"}}

Este é curto e fácil de ler. Ele canaliza o intervalo 2..$aem um loop Foreach-Object %{...}. O loop coleta os valores de if($p){"$_^$p"}.
kernigh

3

JavaScript (ECMAScript 6 Draft) - 89 caracteres

f=(m,n,i=2,k=0)=>(m%i|n%i?(k?i+'^'+k+' ':'')+(i>m?'':f(m,n,i+1)):f(m/i,n/i,i,k+1)).trim()

Converte a resposta original (iterativa), abaixo, em uma resposta recursiva.

Explicação

f=(m,n,i=2,k=0)=>           // A function with arguments m and n and optional arguments
                            // i (defaults to 2) and k (defaults to 0)
  (
    m%i|n%i                 // if i is not a divisor of m or n then:
      ?(k?i+'^'+k+' '       //   if k is non-zero append  "i^k " to the output
         :'')               //   else append nothing
        +(i>m?''            //   if i>m then terminate
             :f(m,n,i+1))   //   else increment i and reset k to 0
      :f(m/i,n/i,i,k+1)     // else divide m and n by i and increment k
  ).trim()                  // finally strip any extra spaces from the output.

Resposta iterativa: JavaScript (ECMASCript 6) - 108 (ou 121) 98 caracteres

Versão 2:

f=(m,n)=>{for(s='',i=1;++i<=m;s+=k?' '+i+'^'+k:'')for(k=0;m%i+n%i<1;k++)m/=i,n/=i;return s.trim()}

Versão 1:

Respondendo à pergunta como originalmente solicitado:

f=(m,n)=>{for(o=[],i=2;i<=m;)m%i|n%i?i++:(m/=i,n/=i,o[i]=(o[i]|0)+1);return o.map((x,i)=>i+"^"+x).join(' ')}

Ou para cumprir as alterações da regra após o fato:

f=(m,n)=>{for(o=[],i=2;i<=m;)m%i|n%i?i++:(m/=i,n/=i,o[i]=(o[i]|0)+1);return o.map((x,i)=>i+"^"+x).filter(x=>x).join(' ')}

Explicação

f=(m,n)=>                        // Create a function f with arguments m and n
{
  o=[]                           // Initialise an empty array for the output
  i=2                            // Start with a divisor of 2
  for(;i<=m;)                    // Loop while the divisor is not greater than m
    m%i|n%i                      // Test the bitwise OR of m%i and n%1 (i.e. whether
                                 // at least one is non-zero)
      ?i++                       // If m%i>0 or n%i>0 then increment i
      :(m/=i,                    // Otherwise: divide m by i;
        n/=i,                    //                   n by i;
        o[i]=(o[i]|0)+1);        // and add 1 to the i-th element of o
  return o.map((x,i)=>i+"^"+x)   // finally map the sparse array o to a sparse array
                                 // of the strings (index+"^"+value)
          .filter(x=>x)          // turn sparse array into non-sparse array
          .join(' ')             // then concatenate and return.
}

Resultado

f(96,162)
"2^1 3^1"

f(14,15)
""

f(80, 80)
"2^4 5^1"

f(196,294)
"2^1 7^2"

Ei, você pode tentar testar, f(158,237)por favor
durron597

É espaço delimitado com expoentes (que só acontece de ter um monte de espaço)" 79^1"
MT0

Certo, as outras soluções não têm isso e nem o exemplo. Por favor corrija :)
durron597

Nada na pergunta, como originalmente solicitado, define quanto espaço em branco é ou não é permitido - a meu ver, isso atende aos requisitos, pois é delimitado por expoentes. No entanto, você vai mudar as regras agora, não é?
MT0

2
Sob as regras preexistentes, pode-se dizer que essa implementação omite o requisito "Não produza nada se as entradas forem relativamente primárias". Ainda parece errado desfigurar o código de golfe que saiu tão bonito. Quão breve você pode fazer uma filter()ligação?
Keen

3

Perl 6: 90 caracteres, 94 bytes

sub MAIN(*@n){@n.any%$_||(my$p=$p⊎$_;@n»/=»$_;redo)for
2..@n[0];$p.pairs.fmt("%d^%d").say}

Um pouco de-golfed e comentou:

sub MAIN (*@n) { # accept any number of input numbers as @n
    (
        # $p is a Bag, e.g., it holds the primes and the number of times each was added
        my $p = $p ⊎ $_; # Add the prime to the bag
        @n »/=» $_; # Divide all the input numbers by the prime

        redo # Redo the loop iteration with the same prime, in case
             # the numbers can be divided by it multiple times
    )
    if @n.all %% $_ # Do the above only if all of @n are divisible by $_
    for 2..@n[0];   # Do the above for all numbers from 2 .. @n[0]

    $p.pairs.fmt("%d^%d").say # Print join " ", "$prime^$count"
}

O uso é como:

$ perl6 -e'sub MAIN(*@n){@n.any%$_||(my$p=$p⊎$_;@n»/=»$_;redo)for
2..@n[0];$p.pairs.fmt("%d^%d").say}' 51 153
3^1 17^1

⊎ é um símbolo em perl? Eu não sabia disso.
durron597

@ durron597 Only Perl 6 :)
Mouq

3

Perl, 144 133 118 114 97 93

($a,$b)=<>=~/\d+/g;for(2..$a){for($n=0;$a%$_+$b%$_<1;$n++,$a/=$_,$b/=$_){}$n&&print"$_^$n ";}

Versão não destruída:

($a,$b)=<>=~/\d+/g;
for(2..$a){
    for($n=0 ; $a%$_+$b%$_<1 ; $n++,$a/=$_,$b/=$_) {}
    $n&&print"$_^$n ";
}

Eu literalmente comecei a aprender Perl apenas para responder a essa pergunta (este é o meu primeiro código Perl), então eu suspeito que isso possa ser resolvido ainda mais.


Sim, eu não olhei para o seu código de perto, mas foreaché sempre sinônimo de forem Perl 5, de modo que deve cortar 4 caracteres :)
Mouq

@Mouq eu nunca vi uma língua com tanta redundância ... obrigado :)
Tal

2

Java: 247 241

Controla os fatores em uma matriz e apenas os imprime em um loop.

Tamanho decente para Java, ao que parece.

class G{public static void main(String[]a){Integer i=1;int n=i.valueOf(a[0]),m=i.valueOf(a[1]),f[]=new int[n>m?n:m+1];for(;m>=++i||n>i;){if(n%i+m%i<1){f[i]++;n/=i;m/=i--;}}for(i=2;i<f.length;System.out.print(f[i]>0?i+"^"+f[i]+" ":""),i++);}}

// line breaks below

class G{
    public static void main(String[]a){
        Integer i=1;int n=i.valueOf(a[0]),m=i.valueOf(a[1]),f[]=new int[n>m?n:m+1];
        for(;m>=++i||n>i;){
            if(n%i+m%i<1){
                f[i]++;n/=i;m/=i--;
            }
        }
        for(i=1;i<f.length;System.out.print(f[i]>0?i+"^"+f[i]+" ":""),i++);
    }
}

Você pode realmente deixar as outras variáveis ​​como int, você perde 4 para o int mas as recupera com new int[-> new Integer[então é uma lavagem.
durron597

Sim, e eu tenho mais três mudando n%i<1&&m%i<1para n%i+m%i<1.
Geobits

Você não precisa do (). Se n==m, o padrão será o m+1mesmo.
Geobits

2
Você pode substituir m/=i;i=1;com m/=i--;Ele vai correr mais rápido também :)
durron597

11
Os aparelhos após o primeiro forciclo são necessários?
Ypnypn

2

JavaScript (ECMAScript 5) 170 164 163 113

Eu praticamente não pude resistir seguindo a liderança do MT0. Eu já havia considerado recursão antes, mas parecia fácil demais para atrapalhar. E é mesmo. A menor variação destrói tudo.

Há um violino para quem gosta de violino.

function f(a,b,i,e){return i?a%i|b%i?(e?i+'^'+e+' ':'')+(i>a?'':f(a,b,i+1,0)):f(a/i,b/i,i,e+1):f(a,b,2,0).trim()}

Ungolfed:

function f(a,b,i,e){
    return i // Check for factor.
        ?a%i|b%i // Check for indivisibility.
            ?(
                e // Check for exponent.
                    ?i+'^'+e+' ' // Add the current factor to result string.
                    :'' // Omit the current non-factor.
             )+(
                i>a // Check for termination state.
                    ?'' // Stop recursion.
                    :f(a,b,i+1,0) // Go to the next factor.
            )
            :f(a/i,b/i,i,e+1) // Failed indivisibility check. Increment exponent and divide subject values.
        :f(a,b,2,0) // Add default factor and exponent.
        .trim() // Get rid of one extra space that's usually on the end.
}

Versão antiga

function f(a,b){for(var r=[],j=-1,i=2;i<=a;)a%i|b%i?++i:(r[j]&&r[j][0]==i?r[j][1]++:r[++j]=[i,1],a/=i,b/=i);for(j=0;i=r[j];++j)r[j]=i.join('^');return r.join(' ')}

Ungolfed:

function f(a,b){
    for(var r=[],j=-1,i=2;i<=a;)
        // We (mis)use conditional expression `?:` instead of `if(){}else{}`.
        a%i|b%i ? // Bitwise OR saves one character over logical OR, where applicable.
             // In the truth case, `i` has become uninteresting. Just move on.
            ++i : // We don't mind hitting composites because their prime factors have already been drained from `a` and `b`.
            (
                r[j]&&r[j][0]==i ? // Check if `i` is already a listed factor.
                    r[j][1]++ : // Increment the exponent count.
                    r[++j]=[i,1], // Otherwise, add a new factor with exponent 1.

                a/=i,b/=i // Drain a used-up factor from `a` and `b`.
            );

    // The real work's done. Now we just format.
    for(j=0; i=r[j]; ++j)
        r[j]=i.join('^'); // Join each factor to its exponent.

    return r.join(' ') // Join all factors into result string.
}

Aqui estão alguns testes:

[
    f(4, 12),
    f(80, 80),
    f(96,162),
    f(196,294)
];

Essa função recursiva falhou f(301343045, 421880263);provavelmente porque meu navegador não me permite recursar tão profundamente. Estúpido quebrado Firefox!
kernigh

Certamente. Na prática, eu só usaria uma função recursiva se realmente precisasse de algum tipo de pilha, como para navegação em árvore ou outras estruturas de dados inerentemente recursivas. (Claro, os números podem ser tratados como estruturas de dados recursivo, mas temos todos os tipos de abstrações agradáveis para nos ajudar a ignorar esse fato.)
Keen

2

GolfScript, 68 bytes

~..),2>*${1$1$%3$2$%+!{.@@/@2$/.}*;}/;;]:D.&{`.[~]D\/,(`"^"\++}%" "*

Observe que essa abordagem requer tempo e espaço O (b 2 ) para os números inteiros “a” e “b”.

Ao custo de um byte extra, "apenas" O (b) tempo e espaço são necessários:

~.),2>31*${1$1$%3$2$%+!{.@@/@2$/.}*;}/;;]:D.&{`.[~]D\/,(`"^"\++}%" "*

Como funciona

~.        # Interpret the input string (“a” and “b”) and duplicate “b”.
.),2>     # Push the array [ 2 3 4 ... b ].
*$        # Repeat each element b times and sort: [ 2 ... 2 3 ... 3 ... b ... b ]
{         # For each element “d” of the array:
  1$1$%   # Calculate a % d.
  3$2$%   # Calculate b % d.
  +!      # Add and negate.
  {       # If both “a” and “b” are divisible by “d”:
    .@@/  # Calculate a / d.
    @2$/  # Calculate b / d.
    .     # Create a dummy value.
  }*      #
  ;       # Pop the topmost stack element (non-divisor “d” or dummy value).
}/        #
;;]       # Pop “a” and “b” and collect the remaining stack elements in an array.
:|.&      # Save that array in “D” and intersect it with itself to deduplicate it.
{         # For each element “d” of “D”:
  `.[~]   # Push string "d" and array [d].
  D\/,(`  # Split “D” around [d] and take the length minus 1. This count the occurrences.
  "^"\    # Push the string "^" and swap it between "d" and it's number of occurrences.
  ++      # Concatenate the three strings.
}%        # Collect all strings into an array.
]" "*     # Join by spaces.

1

Python 3 (123)

Isso usa basicamente a mesma estrutura da resposta de Tal .

a,b=map(int,input().split())
s='';p=1
while p<a:
 c=0;p+=1
 while a%p+b%p<1:a/=p;b/=p;c+=1
 if c:s+='%d^%d '%(p,c)
print(s)

Basta fazer um loop até p = a-1, pois incrementamos imediatamente para obter p = a e a> = min (a, b). Se b> a, não há mal em tentar valores inúteis de p acima de a.

Em 2.x, eu acho que nós poderíamos salvar caracteres, imprimindo cada peça como obtê-lo, em vez de acumular uma string: if c:print'%d^%d'%(p,c),. Infelizmente, o Python 3 não parece ter uma maneira compacta de imprimir sem uma nova linha à direita.


1

PHP, 96

<?php
list(,$a,$b)=$argv;for($s=1;$s++<$a;$c&&print"$s^$c ")for($c=0;1>$a%$s+$b%$s;$a/=$s,$b/=$s)$c++;

Temos quase exatamente o mesmo código! Minha única melhoria é combinar p=0;g+=1em uma linha começando gem 1, o que permite que você faça em g<avez de g<=a. Espero que você goste de python.
Xnor

@xnor perdi seu código. Na verdade, é quase o mesmo. Eu removi meu script python. Espero não terá que como python, EU PRECISO chaves
mleko

Não há necessidade de remover seu código, você mesmo o criou. Eu também criei basicamente o jogo como Tal, então parece que é exatamente para isso que o golfe Python converge.
xnor 11/05

1

awk - 115 111 96 85

A nova versão pode lidar apenas com uma linha de entrada. Obrigado a durron597 por apontar que eu só preciso ter certeza i <= $1.

{for(i=1;++i<=$1;)for(;$1%i+$2%i==0;f[i]++){$1/=i;$2/=i}$0=z;for(i in f)$i=i"^"f[i]}1

Ungolfed:

{
    #skip finding gcd as a separate step, get it from the factors
    for(i = 1; ++i <= $1;) {
        for(;$1 % i == 0 && $2 % i == 0; f[i]++) {
            $1 /= i;
            $2 /= i;
        }
    }
    $0 = "";
    for(i in f) {
        $i = i "^" f[i];
    }
    print;
}

Anteriormente, poderia levar pares de números repetidamente

{a=$1;b=$2;for($0=c;a-b;)if(a>b)a-=b;else b-=a;for(i=2;i<=a;i++){for(j=0;a%i==0;j++)a/=i;$0=$0(j?i"^"j" ":c)}}1

Ungolfed:

{
    a = $1;
    b = $2;
    $0 = "";
    #rip off Euclid
    for(; a != b;) {
        if(a > b) {
            a = a - b;
        } else {
            b = b - a;
        }
    }
    #but not Eratosthenes
    for(i = 2; i <= a; i++) {
        for(j = 0; a % i == 0; j++) {
            a /= i;
        }
        $0 = $0 (j ? i "^" j " " : "");
    }
    print;
}

Você precisa &&i<=b?
durron597

Bem, eu vou estar ... você está certo, você não: se i > b, então b % i != 0... obrigado :) #
1133 laindir

Este programa não funciona com o awk no OpenBSD 5.5, porque NF=0;falha ao excluir $ 1 e $ 2. A saída de echo 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g'é 5 7 1021^1 59029^1porque $ 1 é 5 e $ 2 é 7. O sed espreme os espaços extras resultantes da impressão de $ 1022, $ 1023, $ 1024, ..., $ 59028 como cadeias vazias unidas por espaços.
kernigh

Obrigado @kernigh, funciona em nawk, mawk e gawk. Verifiquei que posix não diz nada sobre a atribuição de NF, e substituído por$0=z;
laindir

@laindir Essa mudança corrige o programa para mim. O código golf não exige que os programas sejam portáteis. Felizmente, $0=z;é o mesmo número de caracteres que NF=0;. Se $0=z;fosse mais longo, eu diria para você ficar NF=0;.
kernigh

1

Pip , 41 bytes

Não é uma resposta competitiva, pois a linguagem é mais nova que a pergunta. Mas essa marca Golf 68 de 68 precisava diminuir.

Fi2,++a{p:0T$|g%i{++pg/:i}Ipx.:i.'^.p.s}x

A saída termina em um espaço; se houver algum problema, a seguinte versão também terá 41 bytes (incluindo o -ssinalizador):

Fi2,++a{p:0T$|g%i{++pg/:i}IplAE:i.'^.p}l

Formatado, com explicações:

F i 2,++a {      For i in range(2,a+1); note ++ used to avoid parentheses in 2,(a+1)
  p:0            p will store the greatest power of i that divides both numbers
  T $+(g%i) {    Loop till the sum of g%i is nonzero, where g is a list initialized
                  from cmdline args
    ++p          As long as g%i is [0 0], increment p...
    g/:i         ...and divide both numbers in g by i
  }
  I p            If p is nonzero, i went into both numbers at least once
    x.:i.'^.p.s  Append i^p and a space to the result
}
x                Print the result

Pip, diferentemente de GolfScript, CJam, et al. é uma linguagem imperativa para operadores de infix; Ele também se inspira nas linguagens de programação de array. Essa tarefa exibe bem os dois paradigmas no trabalho.

(Observe que o commit 2015-4-20 é necessário para executar isso, pois acabei de corrigir alguns bugs.)


0

Python 2 - 262 bytes

n,m=input(),input()
f=lambda i:set(filter(lambda x:i%x<1,range(1,i+1)))
g=max(f(n)&f(m))
p=[]
while g-1:
 p+=[min(filter(lambda x:x>1 and x%2!=(x==2)and not any(map(lambda y:x%y<1,range(2,x))),f(g)))]
 g/=p[-1]
print ' '.join(`a`+^+`p.count(a)`for a in set(p))

A linha 6 precisa de trabalho.


11
Que tal …`a`+'^'+`f.count(a)`…?
Ry-

Não faço ideia de como senti falta disso. Eita. Obrigado.
Undergroundmonorail

0

Groovy: 174 caracteres

Esta é uma porta da solução da Geobits para o Groovy 2.2.1:

int i=1, n=args[0]as int, m=args[1]as int;s=n>m?n:m+1;f=new int[s];while(m>=++i||n>i){if(n%i+m%i<1){f[i]++;n/=i;m/=i--;}};(s-1).times{y=it+1;x=f[y];print"${x>0?"$y^$x ":""}"}

Aqui está a versão não destruída:

int i = 1, n = args[0] as int, m = args[1] as int

s = n>m?n:m+1
f = new int[s]

while (m>=++i||n>i) {
    if (n%i+m%i<1) {
        f[i]++;n/=i;m/=i--;
    }
}
(s-1).times {
    y=it+1
    x=f[y]
    print"${x>0?"$y^$x ":""}"
}

Surpreso que você escolheu a solução em vez do meu Geobits portuárias, como o meu é 56 caracteres mais curto
durron597

0

R: 139

a=scan();q=1:a[1];n=max(q[!a[1]%%q&!a[2]%%q]);m=rep(0,n);for(i in 2:n){while(!n%%i){m[i]=m[i]+1;n=n/i};if(m[i])cat(paste0(i,"^",m[i])," ")}

Com recuos:

a=scan() #Take space-separated numeric input from stdin
q=1:a[1]
n=max(q[!a[1]%%q&!a[2]%%q]) #gcd
m=rep(0,n)
for(i in 2:n){
    while(!n%%i){ #prime factorization
        m[i]=m[i]+1
        n=n/i
        }
    if(m[i])cat(paste0(i,"^",m[i])," ")
    }

Uso:

> a=scan();q=1:a[1];n=max(q[!a[1]%%q&!a[2]%%q]);m=rep(0,n);for(i in 2:n){while(!n%%i){m[i]=m[i]+1;n=n/i};if(m[i])cat(paste0(i,"^",m[i])," ")}
1: 196 294
3: 
Read 2 items
2^1  7^2  
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.