Cetak faktorisasi utama pembagi umum terbesar dari dua angka

17

Judul mengatakan itu semua. Dua input bilangan bulat 32-bit positif m, n >= 2, output gcd(m,n)dalam bentuk faktorisasi prima.

Memasukkan

Baris perintah args atau 1 baris stdin oke, apa pun yang lebih baik untuk golf.

Keluaran

Satu ruang dibatasi dengan eksponen (tanpa spasi tambahan). Tidak menghasilkan apa-apa jika inputnya relatif prima.

Contoh:

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

$ ./factorize 14 15


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

Aturan

  • Anda tidak boleh menggunakan sumber daya eksternal, perpustakaan matematika atau fungsi bawaan untuk faktorisasi atau GCD. Contoh: Java, no java.lang.Math. ruby, tidak prime_division, perl, tidak factor, dll.
durron597
sumber
1
Output apa yang Anda cari jika gcd(n,m) == 1?
undergroundmonorail
Apakah saya tetap bisa jika saya keluar dengan pengecualian? Itu akan menyelamatkan saya beberapa byte.
undergroundmonorail
Sebenarnya, saya telah mengubah pendekatan saya dan tidak perlu keluar dengan pengecualian. Orang lain mungkin ingin tahu.
undergroundmonorail
Jangan keluar dengan pengecualian. Output apa-apa :)
durron597
Secara teknis, q:a+.batau __ q:a+.bdi J menggunakan tidak external resources or math libraries, tapi saya tidak akan mempostingnya, karena terlalu jauh dari semangat pertanyaan. Saya hanya berpikir saya akan membagikannya di sini.
12ıʇǝɥʇu

Jawaban:

10

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

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)

Sungguh menakjubkan betapa saya bisa mempersingkat ini dengan hanya melewatkan hal-hal (seperti, Anda tahu, menemukan gcd)! Saya juga bisa mengurangi 10 karakter lagi dengan membuat ini fungsi yang mengharapkan 2 int, seperti beberapa jawaban lain, daripada membaca dari stdin.

Tal
sumber
Ini intens! Saya belajar banyak dengan menonton suntingan Anda dan mencoba untuk mengalahkan Anda lol. Saya pikir Anda mungkin memiliki yang satu ini (dari jawaban Python)
Rainbolt
1
Anda dapat menyimpan 1 karakter dengan mengubah while g<a and g<b:kewhile(g<a)*(g<b):
Rainbolt
@Rusher Terima kasih sobat! Jawaban Anda adalah salah satu yang memotivasi saya untuk bekerja lebih keras dalam hal ini :) Juga trik yang Anda rekomendasikan mengilhami saya untuk mencari tahu a%g+b%gsedikit
Tal
Saya tidak berpikir klausa lain diperlukan. else:g+=1bisa saja g+=1, kecuali saya kehilangan sesuatu.
isaacg
@isaacg Anda sepertinya benar, terima kasih!
Tal
8

Ruby - 168 117 114 101 100 97

Sunting: Setelah memikirkannya, saya menyadari bahwa saya tidak memerlukan saringan karena faktor yang utama diperhatikan dalam loop faktorisasi. Juga, sebagaimana diinformasikan oleh jawaban orang lain (yang laindir dan Tal adalah yang saya lihat di dalamnya, meskipun sepertinya orang lain juga melakukannya), menghapus perhitungan gcd terpisah, karena itu juga terjadi dalam faktorisasi.
Sunting 2: Tidak perlu do.
Sunting 3: Peras lebih banyak.
Sunting 4: Ditarik satu ruang lagi.
Sunting 5: uptoalih-alih 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}

Output (sama setelah diedit):

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

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

Tentu saja bisa dibuat lebih baik, tapi tidak buruk untuk yang pertamaku.

Pasang kembali Monica - notmaynard
sumber
Anda dapat menghapus 4 byte dengan mengubah map{|i|i.to_i}ke map &:to_i. Anda dapat menghapus byte ke-5 dengan tidak menghitung baris baru di akhir file; Ruby bekerja tanpa itu.
kernigh
Juga, Anda dapat menggunakan $*bukan 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`,

Penerjemah

repl.it

Contoh Input - stdin

100 50

Contoh Output - stdout

2 ^ 1 5 ^ 2

Rainbolt
sumber
1
Bagaimana dengan …`a`+'^'+`f.count(a)`…?
Ry-
Cukup bersih, saya suka
qwr
@ qw Terima kasih. Saya harap saya bisa mengerti jawaban Python lainnya. Format string dan mencukur beberapa karakter.
Rainbolt
Tukar f.append(i)untuk f+=[i]menyimpan 5 karakter.
Nolen Royalty
1
Dan sekarang Anda tidak perlu menggunakan f sama sekali: p (mengapa f=''masih ada di sana?)
Nolen Royalty
4

Jawa - 184 175

Ini terinspirasi oleh jawaban @Geobits (dan sedikit jawaban @ Tal), tetapi cukup berbeda sehingga saya memutuskan untuk membuat jawaban sendiri.

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

Harness uji (tidak dikelompokkan) dengan (verifikasi manusia):

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

dc, 96 byte

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

Bunyinya satu baris input standar. Outputnya tidak berakhir dengan baris baru. (EDIT: Ini juga menghasilkan ruang ekstra setelah setiap faktorisasi. Beberapa jawaban lain memangkas ruang, tetapi yang ini tidak.)

Contoh:

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

Kode dengan komentar:

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

PowerShell - 82

$a,$b=$args
2..$a|%{$p=0;while(!($a%$_+$b%$_)){$a/=$_;$b/=$_;$p++}if($p){"$_^$p"}}
Berasal
sumber
Yang ini pendek dan mudah dibaca. Ini pipa rentang 2..$amenjadi loop Foreach-Object %{...}. Loop mengumpulkan nilai dari if($p){"$_^$p"}.
kernigh
3

JavaScript (ECMAScript 6 Draft) - 89 Karakter

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

Mengonversi jawaban asli (berulang), di bawah, menjadi jawaban rekursif.

Penjelasan

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.

Jawaban Iteratif: JavaScript (ECMASCript 6) - 108 (atau 121) 98 Karakter

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

Versi 1:

Menjawab pertanyaan seperti aslinya:

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

Atau untuk mematuhi perubahan aturan setelah fakta:

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

Penjelasan

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

Keluaran

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
sumber
Hei, f(158,237)tolong coba pengujian
durron597
Ini adalah ruang yang dibatasi oleh eksponen (kebetulan memiliki banyak ruang)" 79^1"
MT0
Benar, solusi lain tidak memiliki itu dan begitu pula contohnya. Silakan perbaiki :)
durron597
Tidak ada dalam pertanyaan, seperti yang ditanyakan semula, yang menentukan seberapa banyak ruang putih atau tidak diizinkan - seperti yang saya lihat, ini memenuhi persyaratan karena ruang putih dibatasi dengan eksponen. Namun, Anda akan pergi dan mengubah peraturan sekarang bukan?
MT0
2
Di bawah aturan yang sudah ada sebelumnya, orang bisa mengatakan bahwa implementasi ini menghilangkan persyaratan "Output apa-apa jika input relatif prima." Tampaknya masih salah untuk menghapus kode golf yang keluar begitu cantik. Seberapa singkat Anda bisa filter()menelepon?
Tertarik
3

Perl 6: 90 karakter, 94 byte

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

Agak de-golf dan berkomentar:

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

Penggunaannya seperti:

$ 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
sumber
⊎ apakah simbol dalam perl? Saya tidak tahu itu.
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 ";}

Versi tidak disatukan:

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

Saya benar-benar baru mulai belajar Perl hanya untuk menjawab pertanyaan ini (ini adalah kode Perl pertama saya), jadi saya curiga bahwa ini dapat diturunkan lebih lanjut.

Tal
sumber
Ya, saya belum melihat kode Anda dengan cermat, tetapi foreachselalu identik dengan fordi Perl 5, sehingga harus memotong 4 karakter :)
Mouq
@Mouq Saya belum pernah melihat bahasa dengan redundansi yang begitu banyak ... terima kasih :)
Tal
2

Jawa: 247 241

Melacak faktor dalam array dan hanya mencetaknya dalam satu lingkaran.

Ukuran yang layak untuk Java, tampaknya.

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++);
    }
}
Geobit
sumber
Anda benar-benar dapat meninggalkan variabel lain sebagai int, Anda kehilangan 4 ke int tetapi Anda mendapatkannya kembali dengan new int[-> new Integer[jadi itu adalah cuci.
durron597
Ya, dan saya mendapat tiga lagi dengan beralih n%i<1&&m%i<1ke n%i+m%i<1.
Geobits
Anda tidak membutuhkannya (). Jika n==m, itu akan m+1tetap default .
Geobits
2
Anda dapat menggantinya m/=i;i=1;dengan m/=i--;Ini akan berjalan lebih cepat juga :)
durron597
1
Apakah kawat gigi setelah forloop pertama diperlukan?
Ypnypn
2

JavaScript (ECMAScript 5) 170 164 163 113

Saya tidak bisa menahan diri mengikuti petunjuk MT0. Saya telah mempertimbangkan rekursi sebelumnya, tetapi sepertinya terlalu mudah untuk dikacaukan. Dan memang benar. Variasi sekecil apa pun menghancurkan segalanya.

Ada biola bagi mereka yang suka biola.

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

Tidak Disatukan:

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

Versi lama

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

Tidak Disatukan:

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

Berikut ini beberapa tes:

[
    f(4, 12),
    f(80, 80),
    f(96,162),
    f(196,294)
];
Tajam
sumber
Fungsi rekursif ini gagal f(301343045, 421880263);mungkin karena browser saya tidak akan membiarkan saya mengulanginya sedalam itu. Firefox rusak yang bodoh!
kernigh
Pasti. Dalam praktiknya, saya hanya akan menggunakan fungsi rekursif jika saya benar-benar membutuhkan semacam tumpukan, seperti untuk navigasi pohon atau struktur data rekursif lainnya. (Tentu, angka dapat diperlakukan sebagai struktur data rekursif, tetapi kami memiliki semua jenis abstraksi yang bagus untuk membantu kami mengabaikan fakta itu.)
Keen
2

GolfScript, 68 byte

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

Perhatikan bahwa pendekatan ini membutuhkan O (b 2 ) waktu dan ruang untuk bilangan bulat "a" dan "b".

Dengan biaya satu byte tambahan, "hanya" O (b) waktu dan ruang yang diperlukan:

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

Bagaimana itu bekerja

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

Python 3 (123)

Ini pada dasarnya menggunakan struktur yang sama dengan jawaban 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)

Cukuplah untuk mengulang hingga p = a-1, karena kita segera menambah p = a dan a> = min (a, b). Jika b> a, tidak ada salahnya mencoba nilai p yang tidak berguna di atas a.

Dalam 2.x, saya pikir kami bisa menghemat karakter dengan mencetak masing-masing bagian seperti yang kita mendapatkannya daripada mengumpulkan string: if c:print'%d^%d'%(p,c),. Sayangnya, Python 3 tampaknya tidak memiliki cara yang ringkas untuk mencetak tanpa baris baru.

Tidak
sumber
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
sumber
Kami mendapat kode yang hampir persis sama! Satu peningkatan saya adalah menggabungkan p=0;g+=1menjadi satu baris dengan mulai gdari 1 sebagai gantinya, yang memungkinkan Anda melakukannya g<adaripada g<=a. Saya harap Anda tumbuh seperti python.
xnor
@ xnatau saya ketinggalan kode Anda. Memang hampir sama. Saya menghapus skrip python saya. Saya harap saya tidak harus menyukai python, saya PERLU kawat gigi
mleko
Tidak perlu menghapus kode Anda, Anda membuatnya sendiri. Saya juga datang dengan dasarnya hal permainan sebagai Tal, jadi sepertinya ini adalah apa yang konvergen golf Python.
xnor
1

awk - 115 111 96 85

Versi baru hanya dapat menangani satu jalur input. Terima kasih kepada durron597 untuk menunjukkan bahwa saya hanya perlu memastikan 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

Tidak Disatukan:

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

Sebelumnya bisa mengambil pasangan angka berulang kali

{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

Tidak Disatukan:

{
    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
sumber
Apakah Anda perlu &&i<=b?
durron597
Yah aku akan ... kamu benar, kamu tidak: jika i > b, maka b % i != 0... terima kasih :)
laindir
Program ini tidak berfungsi dengan awk di OpenBSD 5.5, karena NF=0;gagal menghapus $ 1 dan $ 2. Output dari echo 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g'adalah 5 7 1021^1 59029^1karena $ 1 adalah 5 dan $ 2 adalah 7. Sed meremas ruang tambahan yang berasal dari mencetak $ 1022, $ 1023, $ 1024, ..., $ 59028 sebagai string kosong yang bergabung dengan spasi.
kernigh
Terima kasih @kernigh, ini berfungsi dalam nawk, mawk, dan gawk. $0=z;
Memeriksa ulang bahwa posix
@laindir Perubahan itu memperbaiki program untuk saya. Code golf tidak memerlukan program yang portabel. Untungnya $0=z;jumlah karakternya sama dengan NF=0;. Jika $0=z;lebih lama, saya akan memberitahu Anda untuk menyimpannya NF=0;.
kernigh
1

Pip , 41 byte

Bukan jawaban yang bersaing, karena bahasa lebih baru dari pertanyaan. Tapi itu tanda GolfScript dari 68 perlu turun.

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

Output berakhir di spasi; jika itu masalah, versi berikut ini juga 41 byte (termasuk -sbendera):

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

Diformat, dengan penjelasan:

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, tidak seperti GolfScript, CJam, dkk. adalah bahasa imperatif dengan operator infiks; itu juga mengambil beberapa inspirasi dari bahasa pemrograman array. Tugas ini dengan baik menampilkan kedua paradigma di tempat kerja.

(Perhatikan bahwa komit 2015-4-20 diperlukan untuk menjalankan ini, karena saya baru saja memperbaiki beberapa bug.)

DLosc
sumber
0

Python 2 - 262 byte

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

Jalur 6 perlu bekerja.

monmon bawah tanah
sumber
1
Bagaimana dengan …`a`+'^'+`f.count(a)`…?
Ry-
Saya tidak tahu bagaimana saya melewatkan itu. Astaga. Terima kasih.
undergroundmonorail
0

Groovy: 174 karakter

Ini adalah port solusi Geobits untuk 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 ":""}"}

Ini adalah versi yang tidak disunat:

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
sumber
Terkejut Anda memilih untuk mem-port solusi Geobits alih-alih milik saya, karena milik saya 56 karakter lebih pendek
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])," ")}

Dengan lekukan:

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

Pemakaian:

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