Gibt die Primfaktorisierung des größten gemeinsamen Divisors zweier Zahlen aus

17

Titel sagt alles. Zwei positive 32-Bit-Ganzzahlen m, n >= 2, Ausgabe gcd(m,n)in Form einer Primfaktorisierung.

Eingang

Kommandozeilen-Argumente oder 1 Zeile Standard, was auch immer für das Golfen besser ist.

Ausgabe

Mit Exponenten begrenztes einzelnes Leerzeichen (keine zusätzlichen Leerzeichen). Gib nichts aus, wenn die Eingänge relativ prim sind.

Beispiele:

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

$ ./factorize 14 15


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

Regeln

  • Sie dürfen keine externen Ressourcen, mathematischen Bibliotheken oder integrierten Funktionen für die Faktorisierung oder GCD verwenden. Beispiele: Java, nein java.lang.Math. Rubin, nein prime_division, Perl, nein factor, etc.
durron597
quelle
1
Welche Ausgabe suchen Sie, wenn gcd(n,m) == 1?
undergroundmonorail
Ist es in Ordnung, wenn ich mit einer Ausnahme beende? Es würde mir ein paar Bytes sparen.
undergroundmonorail
Eigentlich habe ich meinen Ansatz geändert und muss nicht mit einer Ausnahme beenden. Andere möchten es vielleicht wissen.
undergroundmonorail
Beenden Sie nicht mit einer Ausnahme. Nichts
ausgeben
Technisch q:a+.boder __ q:a+.bin J nicht verwendet external resources or math libraries, aber ich werde es nicht posten, da es zu weit vom Geist der Frage entfernt ist. Ich dachte nur, ich würde es hier teilen.
Dienstag,

Antworten:

10

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

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)

Es ist erstaunlich, wie sehr ich dies verkürzen könnte, indem ich nur Sachen überspringe (wie, wissen Sie, das Finden des GCD)! Außerdem könnte ich 10 Zeichen mehr reduzieren, indem ich dies zu einer Funktion mache, die wie einige andere Antworten 2 Zoll erwartet, anstatt von stdin zu lesen.

Tal
quelle
Das ist intensiv! Ich lerne viel, indem ich deine Änderungen beobachte und versuche, dich zu schlagen, lol. Ich denke , man könnte diese eine hat aber (aus dem Python Antworten)
Rainbolt
1
Sie können 1 Charakter speichern, indem Sie while g<a and g<b:zuwhile(g<a)*(g<b):
Rainbolt
@ Rusher Danke Kumpel! Ihre Antwort hat mich motiviert, härter daran zu arbeiten :) Auch der von Ihnen empfohlene Trick hat mich dazu inspiriert, das a%g+b%gBit herauszufinden
Tal
Ich denke nicht, dass die else-Klausel notwendig ist. else:g+=1könnte nur sein g+=1, es sei denn mir fehlt etwas.
isaacg
@isaacg Du scheinst recht zu haben, danke!
Tal
8

Rubin - 168 117 114 101 100 97

Edit: Nachdem ich darüber nachgedacht hatte, wurde mir klar, dass ich das Sieb nicht brauchte, da die Primalität des Faktors in der Faktorisierungsschleife berücksichtigt wird. Wie aus den Antworten anderer hervorgeht ( Laindirs und Tals sind die, in denen ich es gesehen habe, obwohl es so aussieht, als hätten andere es auch getan), wurde die separate GCD-Berechnung entfernt, da dies auch in der Faktorisierung vorkommt.
Edit 2: Nicht brauchen do.
Edit 3: Drücke es weiter runter.
Edit 4: Noch ein Leerzeichen herausgezogen.
Edit 5: uptostatt 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}

Ausgabe (gleich nach der Bearbeitung):

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

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

Sicher könnte besser gemacht werden, aber nicht schlecht für meine erste.

Setzen Sie Monica wieder ein - notmaynard
quelle
Sie können durch Ändern 4 Bytes entfernen map{|i|i.to_i}zu map &:to_i. Sie können ein 5. Byte entfernen, indem Sie den Zeilenumbruch am Ende der Datei nicht mitzählen. Ruby funktioniert ohne es.
Kernigh
Sie können auch $*anstelle von verwenden ARGV.
Daniero
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`,

Dolmetscher

repl.it

Beispiel Eingabe - stdin

100 50

Beispielausgabe - stdout

2 ^ 1 5 ^ 2

Regenblitz
quelle
1
Was ist …`a`+'^'+`f.count(a)`…?
Ry
Ziemlich sauber, ich mag es
qwr
@ qwr Danke. Ich hoffe ich kann die anderen Python-Antworten verstehen, String formatieren und ein paar Zeichen rasieren.
Rainbolt
Tauschen Sie f.append(i)gegen f+=[i], um 5 Zeichen zu speichern.
Nolen Royalty
1
Und jetzt brauchen Sie f überhaupt nicht zu verwenden: p (warum ist f=''noch da?)
Nolen Royalty
4

Java - 184 175

Dies ist inspiriert durch die Antwort von @Geobits (und ein wenig von @Tals Antwort), aber genug davon ist anders, dass ich beschlossen habe, meine eigene Antwort zu erstellen.

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

Ungolfed (Art) mit (menschlicher Überprüfung) Testgeschirr:

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
quelle
4

Gleichstrom, 96 Bytes

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

Es liest eine Zeile der Standardeingabe. Die Ausgabe endet nicht mit einem Zeilenumbruch. (BEARBEITEN: Es wird auch nach jeder Faktorisierung ein zusätzliches Leerzeichen ausgegeben. Einige der anderen Antworten kürzen das Leerzeichen, dieses jedoch nicht.)

Beispiel:

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

Code mit Kommentaren:

# 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
quelle
3

PowerShell - 82

$a,$b=$args
2..$a|%{$p=0;while(!($a%$_+$b%$_)){$a/=$_;$b/=$_;$p++}if($p){"$_^$p"}}
Rynant
quelle
Dieser ist kurz und leicht zu lesen. Es leitet den Bereich 2..$ain eine Foreach-Object-Schleife %{...}. Die Schleife sammelt die Werte von if($p){"$_^$p"}.
Kernigh
3

JavaScript (ECMAScript 6 Draft) - 89 Zeichen

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

Konvertiert die ursprüngliche (iterative) Antwort unten in eine rekursive.

Erläuterung

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.

Iterative Antwort: JavaScript (ECMASCript 6) - 108 (oder 121) 98 Zeichen

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:

Beantwortung der Frage wie ursprünglich gestellt:

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

Oder um die Regeländerungen nachträglich einzuhalten:

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

Erläuterung

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

Ausgabe

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
quelle
Hey, kannst du f(158,237)bitte testen
durron597
Es ist ein mit Exponenten abgegrenzter Raum (er hat einfach viel Platz)" 79^1"
MT0
Richtig, die anderen Lösungen haben das nicht und das Beispiel auch nicht. Bitte
korrigieren
Nichts in der Frage definiert, wie viel Leerraum ursprünglich gestellt wurde oder nicht erlaubt ist - aus meiner Sicht entspricht dies den Anforderungen, da es sich um Leerraum handelt, der durch Exponenten begrenzt ist. Aber Sie werden jetzt die Regeln ändern, nicht wahr?
MT0
2
Unter den vorbestehenden Regeln könnte man sagen, dass diese Implementierung die Anforderung "Nichts ausgeben, wenn die Eingaben relativ prim sind" weglässt. Es scheint immer noch falsch, den so hübschen Golfcode zu verunstalten. Wie kurz können Sie filter()telefonieren?
Keen
3

Perl 6: 90 Zeichen, 94 Bytes

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

Etwas entgolft und kommentiert:

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

Die Verwendung ist wie folgt:

$ 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
quelle
⊎ ist ein Symbol in Perl? Ich wusste das nicht.
Durron597
@ Durron597 Nur 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 ";}

Ungolfed-Version:

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

Ich habe gerade erst angefangen, Perl zu lernen, um diese Frage zu beantworten (dies ist mein erster Perl-Code überhaupt), und ich vermute, dass dies weiter verbessert werden kann.

Tal
quelle
Ja, ich habe mir Ihren Code nicht genau angesehen, ist aber foreachimmer gleichbedeutend mit forPerl 5, sodass 4 Zeichen abgeschnitten werden sollten :)
Mouq,
@Mouq Ich habe noch nie eine Sprache mit so viel Redundanz gesehen ... danke :)
Tal
2

Java: 247 241

Verfolgt die Faktoren in einem Array und druckt sie einfach in einer Schleife aus.

Anständige Größe für Java, so scheint es.

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++);
    }
}
Geobits
quelle
Sie können die anderen Variablen so belassen int, dass Sie 4 an die verlieren, int aber Sie gewinnen sie mit new int[-> zurück new Integer[, es ist also eine Wäsche.
Durron597
Ja, und ich habe noch drei bekommen, indem ich zu gewechselt n%i<1&&m%i<1habe n%i+m%i<1.
Geobits
Das brauchst du nicht (). Wenn n==mja, wird es m+1sowieso standardmäßig verwendet .
Geobits
2
Sie können ersetzen m/=i;i=1;mit m/=i--;schneller läuft auch :)
durron597
1
Sind die Zahnspangen nach der ersten forSchleife notwendig?
Ypnypn
2

JavaScript (ECMAScript 5) 170 164 163 113

Ich konnte nicht widerstehen, MT0s Führung zu folgen. Ich hatte schon früher über Rekursion nachgedacht, aber es schien zu einfach, Fehler zu machen. Und das ist es wirklich. Die geringste Abweichung zerstört alles.

Es gibt eine Geige für diejenigen, die Geigen mögen.

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

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

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

Hier sind einige Tests:

[
    f(4, 12),
    f(80, 80),
    f(96,162),
    f(196,294)
];
Daran interessiert
quelle
Diese rekursive Funktion ist f(301343045, 421880263);wahrscheinlich fehlgeschlagen, weil mein Browser mich nicht so tief rekursiv arbeiten lässt. Dummer gebrochener Firefox!
Kernigh
Bestimmt. In der Praxis würde ich eine rekursive Funktion nur verwenden, wenn ich wirklich eine Art Stapel benötige, beispielsweise für die Baumnavigation oder andere inhärent rekursive Datenstrukturen. (Sicher, Zahlen können als rekursive Datenstrukturen behandelt werden, aber wir haben alle Arten von netten Abstraktionen, die uns helfen, diese Tatsache zu ignorieren.)
Keen
2

GolfScript, 68 Bytes

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

Beachten Sie, dass für diesen Ansatz O (b 2 ) Zeit und Platz für die Ganzzahlen „a“ und „b“ erforderlich sind .

Auf Kosten eines zusätzlichen Bytes sind "nur" O (b) Zeit und Raum erforderlich:

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

Wie es funktioniert

~.        # 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
quelle
1

Python 3 (123)

Dies verwendet im Grunde die gleiche Struktur wie Tals Antwort .

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)

Es reicht aus, bis zu p = a-1 zu schleifen, da wir sofort inkrementieren, um p = a und a> = min (a, b) zu erhalten. Wenn b> a ist, schadet es nicht, nutzlose Werte von p über a zu versuchen.

In 2.X, denke ich , dass wir Zeichen durch Drucken jedes Stück retten könnte , wie wir es bekommen , anstatt einen String Akkumulieren: if c:print'%d^%d'%(p,c),. Python 3 scheint leider keine kompakte Art zu haben, ohne eine nachgestellte Zeile zu drucken.

xnor
quelle
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
quelle
Wir haben fast genau den gleichen Code! Meine einzige Verbesserung besteht darin, p=0;g+=1zu einer Zeile zu kombinieren , indem Sie gstattdessen bei 1 beginnen , was Sie dann g<aeher tun lassen als g<=a. Ich hoffe du wirst Python mögen.
Xnor
@ xnor Ich habe deinen Code verpasst. In der Tat ist es fast das gleiche. Ich habe mein Python-Skript entfernt. Ich hoffe, ich muss Python nicht mögen, ich brauche Hosenträger
mleko
Sie müssen Ihren Code nicht entfernen, sondern haben ihn selbst erstellt. Ich habe mir auch im Grunde genommen das Spiel Tal ausgedacht, also sieht es so aus, als würde der Python-Golf genau so aussehen.
spätestens
1

awk - 115 111 96 85

Neue Version kann nur eine Eingabezeile verarbeiten. Vielen Dank an durron597 für den Hinweis, dass ich nur dafür sorgen muss 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;
}

Zuvor konnten immer wieder Zahlenpaare genommen werden

{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;
}
Laindir
quelle
Sie braucht &&i<=b?
Durron597
Nun, ich werde ... du hast recht, wenn nicht i > b, dann b % i != 0... danke :)
laindir
Dieses Programm funktioniert nicht mit awk in OpenBSD 5.5, da NF=0;$ 1 und $ 2 nicht gelöscht werden können. Die Ausgabe von echo 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g'ist, 5 7 1021^1 59029^1weil $ 1 5 und $ 2 7 ist. Die Sed quetscht die zusätzlichen Leerzeichen, die beim Drucken von $ 1022, $ 1023, $ 1024, ..., $ 59028 als leere Zeichenfolgen entstehen, die durch Leerzeichen verbunden sind.
Kernigh
Danke @kernigh, es funktioniert in Nawk, Mawk und Gawk. Überprüfen Sie nochmals, ob Posix nichts über die Zuweisung zu NF aussagt, und ersetzen Sie es durch$0=z;
laindir
@laindir Diese Änderung behebt das Programm für mich. Für Code Golf müssen keine Programme portabel sein. Zum Glück $0=z;ist die gleiche Anzahl von Zeichen wie NF=0;. Wenn $0=z;es länger wäre, würde ich dir sagen, dass du es behalten sollst NF=0;.
Kernigh
1

Pip , 41 Bytes

Keine konkurrierende Antwort, da die Sprache neuer ist als die Frage. Die GolfScript-Marke von 68 musste jedoch herabgesetzt werden.

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

Die Ausgabe endet in einem Leerzeichen. Wenn das ein Problem ist, ist die folgende Version auch 41 Bytes (einschließlich des -sFlags):

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

Formatiert mit Erläuterungen:

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, im Gegensatz zu GolfScript, CJam et al. ist eine imperative Sprache mit Infix-Operatoren; Es lässt sich auch von Array-Programmiersprachen inspirieren. Diese Aufgabe zeigt gut beide Paradigmen bei der Arbeit.

(Beachten Sie, dass das 2015-4-20-Commit erforderlich ist, um dies auszuführen, da ich gerade ein paar Fehler behoben habe.)

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

Zeile 6 braucht Arbeit.

untergrundbahn
quelle
1
Was ist …`a`+'^'+`f.count(a)`…?
Ry
Ich habe keine Ahnung, wie ich das verpasst habe. Herrgott. Vielen Dank.
bahnmonorail
0

Groovy: 174 Zeichen

Dies ist eine Portierung der Geobits-Lösung für 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 ":""}"}

Hier ist die ungolfed Version:

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
quelle
Überrascht haben Sie sich entschieden, die Lösung von Geobits anstelle meiner zu portieren, da meine 56 Zeichen kürzer ist
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])," ")}

Mit Einrückungen:

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

Verwendung:

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