Imprimer la décomposition en facteurs premiers du plus grand commun diviseur de deux nombres

17

Le titre dit tout. Deux entiers positifs 32 bits d'entrée m, n >= 2, sortie gcd(m,n)sous forme de factorisation principale.

Contribution

Arguments de ligne de commande ou 1 ligne de stdin ok, quoi de mieux pour le golf.

Production

Espace unique délimité d'exposants (aucun espace supplémentaire). Rien de sortie si les entrées sont relativement principales.

Exemples:

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

$ ./factorize 14 15


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

Règles

  • Vous ne pouvez pas utiliser des ressources externes, des bibliothèques mathématiques ou des fonctions intégrées pour la factorisation ou GCD. Exemples: Java, non java.lang.Math. rubis, non prime_division, perl, non factor, etc.
durron597
la source
1
Quelle sortie recherchez-vous si gcd(n,m) == 1?
métro
Est-ce correct si je quitte avec une exception? Cela me ferait économiser quelques octets.
métro
En fait, j'ai changé d'approche et je n'ai pas besoin de sortir avec une exception. Mais d'autres voudront peut-être le savoir.
métro
Ne quittez pas avec une exception. Sortie rien :)
durron597
Techniquement, q:a+.bou __ q:a+.ben J utilise non external resources or math libraries, mais je ne le posterai pas, car c'est trop loin de l'esprit de la question. Je pensais juste que je le partagerais ici.
ɐɔıʇǝɥʇuʎs

Réponses:

10

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

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)

C'est incroyable à quel point je pourrais raccourcir cela en sautant juste des trucs (comme, vous savez, trouver le gcd)! Je pourrais également réduire 10 caractères supplémentaires en faisant de cette fonction une fonction qui attend 2 ints, comme certaines autres réponses, au lieu de lire depuis stdin.

Tal
la source
C'est intense! J'apprends beaucoup en regardant vos modifications et en essayant de vous battre lol. Je pense que vous pourriez avoir celui-ci cependant (hors des réponses Python)
Rainbolt
1
Vous pouvez enregistrer 1 personnage en changeant while g<a and g<b:enwhile(g<a)*(g<b):
Rainbolt
@Rusher Merci mon pote! Votre réponse est celle qui m'a motivé à travailler plus dur sur ce sujet :) L'astuce que vous avez recommandée m'a aussi inspiré à comprendre le a%g+b%gbit
Tal
Je ne pense pas que la clause else soit nécessaire. else:g+=1pourrait juste être g+=1, à moins que je manque quelque chose.
isaacg
@isaacg Vous semblez avoir raison, merci!
Tal
8

Rubis - 168 117 114 101 100 97

Edit: Après y avoir réfléchi, j'ai réalisé que je n'avais pas besoin du tamis car la primauté du facteur est prise en charge dans la boucle de factorisation. En outre, comme l'ont informé les réponses des autres ( ceux de Laindir et Tal sont ceux dans lesquels je l'avais vu, bien qu'il semble que d'autres l'aient également fait), a supprimé le calcul de GCD séparé, car cela se produit également dans la factorisation.
Edit 2: Pas besoin do.
Edit 3: le presser davantage.
Edit 4: Tiré un espace de plus.
Modifier 5: uptoau lieu 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}

Sortie (même après modification):

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

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

Certes, pourrait être amélioré, mais pas mal pour mon premier.

Réintégrer Monica - notmaynard
la source
Vous pouvez supprimer 4 octets en changeant map{|i|i.to_i}pour map &:to_i. Vous pouvez supprimer un 5ème octet en ne comptant pas la nouvelle ligne à la fin du fichier; Ruby fonctionne sans lui.
kernigh
Vous pouvez également utiliser à la $*place de ARGV.
daniero
6

Python deux - 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`,

Interprète

repl.it

Exemple d'entrée - stdin

100 50

Exemple de sortie - stdout

2 ^ 1 5 ^ 2

Rainbolt
la source
1
Et alors …`a`+'^'+`f.count(a)`…?
Ry-
Assez propre, j'aime ça
qwr
@qwr Merci. J'espère que je peux comprendre les autres réponses Python Formatage de chaîne et raser quelques caractères.
Rainbolt
Échangez f.append(i)pour f+=[i]enregistrer 5 caractères.
Nolen Royalty,
1
Et maintenant vous n'avez plus besoin d'utiliser f: p (pourquoi est- f=''il toujours là?)
Nolen Royalty
4

Java - 184 175

Ceci est inspiré par la réponse de @Geobits (et un peu de la réponse de @ Tal), mais suffisamment différente est que j'ai décidé de créer ma propre réponse.

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

Harnais de test (sorte de) non (avec vérification humaine):

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();
    }
}
durron597
la source
4

dc, 96 octets

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

Il lit une ligne d'entrée standard. Sa sortie ne se termine pas par une nouvelle ligne. (EDIT: Il génère également un espace supplémentaire après chaque factorisation. Certaines des autres réponses coupent l'espace, mais celle-ci ne le fait pas.)

Exemple:

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

Code avec commentaires:

# 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
kernigh
la source
3

PowerShell - 82

$a,$b=$args
2..$a|%{$p=0;while(!($a%$_+$b%$_)){$a/=$_;$b/=$_;$p++}if($p){"$_^$p"}}
Rynant
la source
Celui-ci est court et facile à lire. Il 2..$adirige la plage dans une boucle Foreach-Object %{...}. La boucle collecte les valeurs de if($p){"$_^$p"}.
kernigh
3

JavaScript (ECMAScript 6 Draft) - 89 caractères

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()

Convertit la réponse originale (itérative) ci-dessous en une réponse récursive.

Explication

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.

Réponse itérative: JavaScript (ECMASCript 6) - 108 (ou 121) 98 caractères

Version 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()}

Version 1:

Répondre à la question posée à l'origine:

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 pour se conformer aux changements de règles après coup:

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(' ')}

Explication

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

Production

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

f(14,15)
""

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

f(196,294)
"2^1 7^2"
MT0
la source
Hé, pouvez-vous essayer de tester f(158,237)s'il vous plaît
durron597
Il est délimité par des exposants (il se trouve qu'il y a beaucoup d'espace)" 79^1"
MT0
Bon, les autres solutions n'ont pas ça et l'exemple non plus. Veuillez corriger :)
durron597
Rien dans la question, comme demandé à l'origine, ne définit la quantité d'espace blanc autorisée ou non - à mon avis, cela répond aux exigences car elle est délimitée par des exposants. Cependant, vous allez changer les règles maintenant, n'est-ce pas?
MT0
2
En vertu des règles préexistantes, on pourrait dire que cette mise en œuvre omet l'exigence «Ne rien produire si les entrées sont relativement principales». Semble toujours mal de défigurer le code de golf qui est sorti si joli. Combien de temps pouvez-vous passer un filter()appel?
Keen
3

Perl 6: 90 caractères, 94 octets

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

Un peu dé-golfé et commenté:

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

L'utilisation est comme:

$ 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
Mouq
la source
⊎ est un symbole en perl? Je ne le savais pas.
durron597
@ durron597 Seulement Perl 6 :)
Mouq
3

Perl, 144 133 118 114 114 97 93

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

Version non golfée:

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

Je viens littéralement de commencer à apprendre Perl juste pour répondre à cette question (c'est mon premier code Perl jamais), donc je soupçonne que cela peut être approfondi.

Tal
la source
Oui, je n'ai pas regardé votre code de près, mais il foreachest toujours synonyme de forPerl 5, ce qui devrait couper 4 caractères :)
Mouq
@Mouq Je n'ai jamais vu une langue avec autant de redondance ... merci :)
Tal
2

Java: 247 241

Conserve la trace des facteurs dans un tableau et les imprime simplement en boucle.

Taille décente pour Java, semble-t-il.

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++);
    }
}
Géobits
la source
Vous pouvez réellement laisser les autres variables comme int, vous perdez 4 à la int mais vous les récupérez avec new int[-> new Integer[c'est donc un lavage.
durron597
Ouais, et j'en ai eu trois autres en passant n%i<1&&m%i<1à n%i+m%i<1.
Geobits
Vous n'en avez pas besoin (). Si n==m, il sera de m+1toute façon par défaut .
Géobits
2
Vous pouvez également le remplacer m/=i;i=1;par m/=i--;Il fonctionnera plus rapidement :)
durron597
1
Les accolades après la première forboucle sont-elles nécessaires?
Ypnypn
2

JavaScript (ECMAScript 5) 170 164 163 113

Je n'ai pratiquement pas pu résister à suivre l'exemple de MT0. J'avais envisagé la récursivité auparavant, mais cela avait semblé trop facile à gâcher. Et ça l'est vraiment. La moindre variation détruit tout.

Il y a un violon pour ceux qui aiment les violons.

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

Non golfé:

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

Ancienne version

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(' ')}

Non golfé:

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

Voici quelques tests:

[
    f(4, 12),
    f(80, 80),
    f(96,162),
    f(196,294)
];
Enthousiaste
la source
Cette fonction récursive a échoué f(301343045, 421880263);probablement parce que mon navigateur ne me laissera pas rentrer aussi profondément. Stupide cassé Firefox!
kernigh
Certainement. En pratique, je n'utiliserais une fonction récursive que si j'avais vraiment besoin d'une sorte de pile, comme pour la navigation dans les arbres ou d'autres structures de données intrinsèquement récursives. (Bien sûr, les nombres peuvent être traités comme des structures de données récursives, mais nous avons toutes sortes de belles abstractions pour nous aider à ignorer ce fait.)
Keen
2

GolfScript, 68 octets

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

Notez que cette approche nécessite O (b 2 ) temps et espace pour les entiers «a» et «b».

Au prix d'un octet supplémentaire, "seulement" O (b) temps et espace sont nécessaires:

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

Comment ça fonctionne

~.        # 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.
Dennis
la source
1

Python 3 (123)

Cela utilise essentiellement la même structure que la réponse 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)

Il suffit de boucler jusqu'à p = a-1, car nous incrémentons immédiatement pour obtenir p = a et a> = min (a, b). Si b> a, il n'y a aucun mal à essayer des valeurs inutiles de p au-dessus de a.

En 2.X, je pense que nous pourrions économiser des caractères en imprimant chaque pièce que nous obtenons plutôt que d' accumuler une chaîne: if c:print'%d^%d'%(p,c),. Python 3, malheureusement, ne semble pas avoir une manière compacte d'imprimer sans une nouvelle ligne de fin.

xnor
la source
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++;
mleko
la source
Nous avons presque exactement le même code! Ma seule amélioration est de combiner p=0;g+=1en une seule ligne en commençant gà 1 à la place, ce qui vous permet ensuite de faire g<aplutôt que g<=a. J'espère que vous apprendrez à aimer le python.
xnor
@xnor J'ai raté votre code. En effet, c'est presque la même chose. J'ai supprimé mon script python. J'espère que je n'aurai pas à aimer le python, j'ai besoin d'accolades
mleko
Pas besoin de supprimer votre code, vous l'avez créé vous-même. J'ai également proposé essentiellement le jeu en tant que Tal, il semble donc que c'est exactement ce vers quoi le golf Python converge.
xnor
1

awk - 115 111 96 85

La nouvelle version ne peut gérer qu'une seule ligne d'entrée. Merci à durron597 d' avoir souligné que je dois seulement m'en assurer 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

Non golfé:

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

Auparavant, pouvait prendre des paires de nombres à plusieurs reprises

{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

Non golfé:

{
    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;
}
laindir
la source
Avez-vous besoin &&i<=b?
durron597
Eh bien, je serai ... vous avez raison, vous n'avez pas: si i > b, alors b % i != 0... merci :)
laindir
Ce programme ne fonctionne pas avec awk dans OpenBSD 5.5, car il NF=0;ne parvient pas à supprimer $ 1 et $ 2. La sortie deecho 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g' est 5 7 1021^1 59029^1parce que $ 1 est 5 et $ 2 est 7. Le sed comprime les espaces supplémentaires qui proviennent de l'impression de $ 1022, $ 1023, $ 1024, ..., $ 59028 en tant que chaînes vides jointes par des espaces.
kernigh
Merci @kernigh, cela fonctionne en nawk, mawk et gawk. Revérifié que posix ne dit rien sur l'attribution à NF, et remplacé par$0=z;
laindir
@laindir Ce changement corrige le programme pour moi. Le golf de code n'exige pas que les programmes soient portables. Heureusement, $0=z;c'est le même nombre de caractères que NF=0;. Si $0=z;c'était plus long, je vous dirais de garder NF=0;.
kernigh
1

Pip , 41 octets

Pas une réponse concurrente, car la langue est plus récente que la question. Mais cette marque GolfScript de 68 devait descendre.

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

La sortie se termine dans un espace; si c'est un problème, la version suivante est également de 41 octets (y compris l' -sindicateur):

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

Formaté, avec explications:

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, contrairement à GolfScript, CJam et al. est un langage impératif avec des opérateurs infixes; il s'inspire également des langages de programmation de tableaux. Cette tâche affiche joliment les deux paradigmes au travail.

(Notez que la validation 2015-4-20 est nécessaire pour exécuter cela, car je viens de corriger quelques bugs.)

DLosc
la source
0

Python 2 - 262 octets

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

La ligne 6 a besoin de travail.

métro monorail
la source
1
Et alors …`a`+'^'+`f.count(a)`…?
Ry-
Je ne sais pas comment j'ai raté ça. Bon sang. Merci.
métro
0

Groovy: 174 caractères

Il s'agit d'un portage de la solution de Geobits vers 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 ":""}"}

Voici la version non golfée:

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 ":""}"
}
Michael Easter
la source
Surpris que vous ayez choisi de porter la solution de Geobits au lieu de la mienne, car la mienne est 56 caractères plus courte
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])," ")}

Avec indentations:

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])," ")
    }

Usage:

> 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  
plannapus
la source