Wydrukuj pierwszą faktoryzację największego wspólnego dzielnika dwóch liczb

17

Tytuł mówi wszystko. Dwie wejściowe 32-bitowe liczby całkowite dodatnie m, n >= 2, wyjście gcd(m,n)w postaci pierwszej faktoryzacji.

Wejście

Argumenty linii poleceń lub 1 linia stdin w porządku, cokolwiek jest lepsze dla golfa.

Wynik

Pojedyncza spacja rozdzielana wykładnikami (bez dodatkowych spacji). Nie wysyłaj nic, jeśli dane wejściowe są względnie pierwsze.

Przykłady:

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

$ ./factorize 14 15


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

Zasady

  • Nie można używać zasobów zewnętrznych, bibliotek matematycznych ani wbudowanych funkcji do faktoryzacji lub GCD. Przykłady: Java, no java.lang.Math. ruby, nie prime_division, perl, nie factoritp.
durron597
źródło
1
Jakiej wydajności szukasz, jeśli gcd(n,m) == 1?
metro
Czy mogę wyjść z wyjątkiem? Zaoszczędzi mi to kilka bajtów.
metro
Właściwie zmieniłem podejście i nie muszę wychodzić z wyjątkiem. Inni mogą jednak chcieć wiedzieć.
metro
Nie wychodź z wyjątkiem. Nic nie
wysyłaj
Technicznie q:a+.blub __ q:a+.bw J używa nie external resources or math libraries, ale nie opublikuję tego, ponieważ jest to zbyt dalekie od ducha pytania. Myślałem, że podzielę się tutaj.
Mayıʇǝɥʇuʎs

Odpowiedzi:

10

Python 3, 255 250 237 226 188 180 150 142 137 136 znaków

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)

To niesamowite, jak bardzo mogłem to skrócić, po prostu pomijając różne rzeczy (na przykład znalezienie gcd)! Mógłbym również zmniejszyć 10 dodatkowych znaków, czyniąc tę ​​funkcję, która oczekuje 2 ints, jak niektóre inne odpowiedzi, zamiast czytać ze standardowego wejścia.

Tal
źródło
To jest intensywne! Dużo się uczę, oglądając twoje zmiany i próbując cię pokonać lol. Myślę, że możesz mieć ten (z odpowiedzi na Python)
Rainbolt
1
Możesz uratować 1 postać, zmieniając while g<a and g<b:nawhile(g<a)*(g<b):
Rainbolt
@Rusher Dzięki kolego! Twoja odpowiedź jest jedna, że zmotywowało mnie do cięższej pracy na ten temat :) Również podstęp ty polecany zainspirowało mnie, aby dowiedzieć się a%g+b%gbit
Tal
Nie sądzę, aby klauzula else była konieczna. else:g+=1może być g+=1, chyba że coś mi umknie.
isaacg
@isaacg Wygląda na to, że masz rację, dziękuję!
Tal
8

Ruby - 168 117 114 101 100 97

Edycja: Po zastanowieniu się, zdałem sobie sprawę, że nie potrzebuję sita, ponieważ pierwszeństwo czynnika jest załatwione w pętli faktoryzacji. Ponadto, jak poinformowały odpowiedzi innych ( laindir i Tal to te, w których widziałem go, choć wygląda na to, że inni też to zrobili), usunąłem osobne obliczenia gcd, ponieważ ma to również miejsce w faktoryzacji.
Edycja 2: Nie potrzebuję do.
Edycja 3: ściśnij to bardziej.
Edycja 4: Wyciągnąłem jeszcze jedno miejsce.
Edycja 5: uptozamiast 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}

Dane wyjściowe (to samo po edycji):

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

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

Z pewnością można by poprawić, ale nieźle jak na mój pierwszy.

Przywróć Monikę - notmaynard
źródło
Możesz usunąć 4 bajty, zmieniając map{|i|i.to_i}na map &:to_i. Możesz usunąć 5. bajt, nie licząc nowego wiersza na końcu pliku; Ruby działa bez tego.
kernigh
Możesz także użyć $*zamiast 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`,

Interpretator

repl.it

Przykładowe dane wejściowe - standardowe

100 50

Przykładowe dane wyjściowe - standardowe wyjście

2 ^ 1 5 ^ 2

Rainbolt
źródło
1
Co …`a`+'^'+`f.count(a)`…?
Ry-
Całkiem czyste, podoba mi się
qwr
@qwr Thanks. Mam nadzieję, że rozumiem inne odpowiedzi w języku Python Formatowanie ciągów i golenie kilku znaków.
Rainbolt
Zamień f.append(i)na, f+=[i]aby zapisać 5 znaków.
Nolen Royalty
1
A teraz nie musisz wcale używać f: p (dlaczego f=''wciąż tam jest?)
Nolen Royalty
4

Java - 184 175

Zainspirowane jest to odpowiedzią @Geobits (i odrobiną odpowiedzi @ Tal), ale dość jej jest inaczej, że postanowiłem stworzyć własną odpowiedź.

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

Pasy testowe bez golfa (w pewnym sensie) z (weryfikacją przez człowieka):

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
źródło
4

dc, 96 bajtów

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

Czyta jeden wiersz standardowego wejścia. Jego wynik nie kończy się na nowej linii. (EDYCJA: Po każdym rozkładzie na czynniki generuje również dodatkowe miejsce. Niektóre inne odpowiedzi zmniejszają przestrzeń, ale ta nie.)

Przykład:

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

Kod z komentarzami:

# 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
źródło
3

PowerShell - 82

$a,$b=$args
2..$a|%{$p=0;while(!($a%$_+$b%$_)){$a/=$_;$b/=$_;$p++}if($p){"$_^$p"}}
Rynant
źródło
Ten jest krótki i łatwy do odczytania. Przesyła zasięg 2..$ado pętli Foreach-Object %{...}. Pętla zbiera wartości if($p){"$_^$p"}.
kernigh
3

JavaScript (wersja robocza ECMAScript 6) - 89 znaków

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

Konwertuje pierwotną (iteracyjną) odpowiedź poniżej na rekurencyjną.

Wyjaśnienie

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.

Iteracyjna odpowiedź: JavaScript (ECMASCript 6) - 108 (lub 121) 98 znaków

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

Wersja 1:

Odpowiadając na pierwotnie zadane pytanie:

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

Lub w celu zachowania zgodności ze zmianą reguły po fakcie:

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

Wyjaśnienie

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

Wynik

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
źródło
Hej można spróbować testowania f(158,237)proszę
durron597
Jest spacja rozdzielona wykładnikami (zdarza się, że ma dużo miejsca)" 79^1"
MT0
Racja, inne rozwiązania tego nie mają, podobnie jak przykład. Proszę naprawić :)
durron597
Nic w pytaniu, jak pierwotnie zadawano, nie określa, ile białych znaków jest dozwolone, czy nie jest dozwolone - jak widzę, spełnia to wymagania, ponieważ białe znaki są ograniczone wykładnikami wykładniczymi. Jednak zamierzasz teraz zmienić zasady, prawda?
MT0
2
Zgodnie z istniejącymi regułami można powiedzieć, że ta implementacja pomija wymóg „Nic nie generuj, jeśli dane wejściowe są względnie pierwsze”. Nadal wydaje się niewłaściwe, aby znieść tak ładny kod golfowy. Jak krótko możesz nawiązać filter()połączenie?
Gorliwy
3

Perl 6: 90 znaków, 94 bajty

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

Nieco golfa i skomentował:

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

Użycie jest jak:

$ 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
źródło
⊎ jest symbolem w perlu? Nie wiedziałem tego
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 ";}

Wersja bez golfa:

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

Dosłownie zacząłem uczyć się Perla, aby odpowiedzieć na to pytanie (jest to mój pierwszy kod Perla w historii), więc podejrzewam, że można go jeszcze pograć w golfa.

Tal
źródło
Tak, nie przyjrzałem się dokładnie twojemu kodowi, ale foreachzawsze jest to synonim forPerla 5, więc to powinno odciąć 4 znaki :)
Mouq
@Mouq Nigdy nie widziałem języka z taką redundancją ... dzięki :)
Tal
2

Java: 247 241

Śledzi czynniki w tablicy i po prostu drukuje je w pętli.

Wygląda na to, że Java ma przyzwoity rozmiar.

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++);
    }
}
Geobity
źródło
Możesz zostawić pozostałe zmienne, ponieważ inttracisz 4, int ale odzyskujesz je za pomocą new int[->, new Integer[więc jest to pranie.
durron597
Tak, a ja dostałem kolejne trzy, zmieniając n%i<1&&m%i<1na n%i+m%i<1.
Geobity
Nie potrzebujesz (). Jeśli n==m, to i tak ustawi się domyślnie m+1.
Geobity
2
Można wymienić m/=i;i=1;z m/=i--;Nim będzie działał szybciej też :)
durron597
1
Czy nawiasy klamrowe po pierwszej forpętli są konieczne?
Ypnypn
2

JavaScript (ECMAScript 5) 170 164 163 113

Prawie nie mogłem się oprzeć podążaniu za tropem MT0. Wcześniej zastanawiałem się nad rekurencją, ale wydawało się to zbyt łatwe do zepsucia. I tak naprawdę jest. Najmniejsza odmiana niszczy wszystko.

Dla tych, którzy lubią skrzypce, jest skrzypce.

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

Nie golfowany:

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

Stara wersja

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

Nie golfowany:

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

Oto kilka testów:

[
    f(4, 12),
    f(80, 80),
    f(96,162),
    f(196,294)
];
Zapalony
źródło
Ta funkcja rekurencyjna nie zadziałała f(301343045, 421880263);prawdopodobnie dlatego, że moja przeglądarka nie pozwala mi na tak głębokie rekurencje . Głupi zepsuty Firefox!
kernigh
Na pewno. W praktyce używałbym funkcji rekurencyjnej tylko wtedy, gdy naprawdę potrzebowałem jakiegoś stosu, takiego jak nawigacja w drzewie lub inne z natury rekurencyjne struktury danych. (Oczywiście liczby można traktować jako rekurencyjne struktury danych, ale mamy wiele ładnych abstrakcji, które pomogą nam zignorować ten fakt.)
Keen
2

GolfScript, 68 bajtów

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

Zauważ, że takie podejście wymaga O (b 2 ) czasu i przestrzeni dla liczb całkowitych „a” i „b”.

Kosztem jednego dodatkowego bajtu konieczne są tylko „O” (b) czas i przestrzeń:

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

Jak to działa

~.        # 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
źródło
1

Python 3 (123)

Wykorzystuje to w zasadzie taką samą strukturę jak odpowiedź 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)

Wystarczy zapętlić w górę do p = a-1, ponieważ natychmiast zwiększamy, aby otrzymać p = a i a> = min (a, b). Jeśli b> a, nie zaszkodzi wypróbować bezużytecznych wartości p powyżej a.

W 2.X, myślę, że możemy zaoszczędzić, drukując znaki każdy kawałek jak mamy to zamiast gromadzenia ciąg: if c:print'%d^%d'%(p,c),. Niestety, Python 3 nie ma kompaktowego sposobu drukowania bez końcowego znaku nowej linii.

xnor
źródło
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
źródło
Mamy prawie dokładnie ten sam kod! Moim jedynym ulepszeniem jest połączenie p=0;g+=1w jedną linię, zaczynając god 1 zamiast tego, co pozwala ci to zrobić g<azamiast g<=a. Mam nadzieję, że polubisz pytona.
xnor
@ xnor Brakuje mi twojego kodu. Rzeczywiście jest prawie tak samo. Usunąłem swój skrypt Pythona. Mam nadzieję, że nie będę lubił pytona, POTRZEBUJĘ
aparatów
Nie musisz usuwać kodu, sam go wymyśliłeś. Wymyśliłem też w zasadzie grę jako Tal, więc wygląda na to, że to właśnie zbiega się golf Python.
xnor
1

awk - 115 111 96 85

Nowa wersja obsługuje tylko jeden wiersz danych wejściowych. Dzięki durron597 za zwrócenie uwagi, że muszę się tylko upewnić 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

Nie golfowany:

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

Wcześniej mógł wielokrotnie pobierać pary liczb

{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

Nie golfowany:

{
    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
źródło
Czy trzeba &&i<=b?
durron597
Cóż, będę ... masz rację, nie wiesz: jeśli i > b, to b % i != 0... dzięki :)
laindir
Ten program nie działa z awk w OpenBSD 5.5, ponieważ NF=0;nie usuwa 1 $ i 2 $. Wynik echo 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g'jest taki, 5 7 1021^1 59029^1że 1 $ to 5, a 2 $ 7. Sed wyciska dodatkowe spacje, które pochodzą z drukowania 1022 $, 1023 $, 1024, ..., 59028 $ jako puste ciągi znaków połączone spacjami.
kernigh
Dzięki @kernigh, działa w nawk, mawk i gawk. $0=z;
Dokładnie
@laindir Ta zmiana naprawia dla mnie program. Code golf nie wymaga przenośności programów. Na szczęście $0=z;jest taka sama liczba znaków jak NF=0;. Jeśli $0=z;byłby dłuższy, powiedziałbym, żebyś zatrzymał NF=0;.
kernigh
1

Pip , 41 bajtów

Nie jest to odpowiedź konkurencyjna, ponieważ język jest nowszy niż pytanie. Ale ten znak GolfScript 68 musiał zejść.

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

Wyjście kończy się spacją; jeśli to problem, następująca wersja ma również 41 bajtów (łącznie z -sflagą):

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

Sformatowane z objaśnieniami:

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, w przeciwieństwie do GolfScript, CJam i in. jest językiem imperatywnym z operatorami infix; czerpie także inspirację z języków programowania tablicowego. To zadanie ładnie wyświetla oba paradygmaty w pracy.

(Zauważ, że zatwierdzenie 2015-4-20 jest potrzebne do uruchomienia tego, ponieważ właśnie naprawiłem kilka błędów.)

DLosc
źródło
0

Python 2 - 262 bajtów

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

Linia 6 wymaga pracy.

podziemny monorail
źródło
1
Co …`a`+'^'+`f.count(a)`…?
Ry-
Nie mam pojęcia, jak to przeoczyłem. Jezu. Dzięki.
undergroundmonorail
0

Groovy: 174 znaków

To jest port rozwiązania Geobits do 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 ":""}"}

Oto wersja bez golfa:

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
źródło
Zaskoczony, że zdecydowałeś się przenieść rozwiązanie Geobits zamiast mojego, ponieważ moje ma 56 znaków krótszych
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])," ")}

Z wcięciami:

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

Stosowanie:

> 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
źródło