พิมพ์การแยกตัวประกอบเฉพาะของตัวหารร่วมมากของตัวเลขสองตัว


17

ชื่อกล่าวมันทั้งหมด อินพุตจำนวนเต็มบวกจำนวน 32 บิตm, n >= 2สองเอาต์พุตgcd(m,n)ในรูปแบบการแยกตัวประกอบเฉพาะ

อินพุต

บรรทัดคำสั่ง args หรือ stdin 1 บรรทัดโอเคอะไรก็ตามที่ดีกว่าสำหรับการเล่นกอล์ฟ

เอาท์พุต

พื้นที่เดียวคั่นด้วย exponents (ไม่มีช่องว่างเพิ่มเติม) เอาท์พุทไม่มีอะไรถ้าอินพุตค่อนข้างสำคัญ

ตัวอย่าง:

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

$ ./factorize 14 15


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

กฎระเบียบ

  • คุณไม่สามารถใช้ทรัพยากรภายนอกห้องสมุดคณิตศาสตร์หรือฟังก์ชันในตัวสำหรับการแยกตัวประกอบหรือ GCD ตัวอย่าง: Java, no java.lang.Math. ruby, no prime_division, perl, no factor, etc.

1
คุณกำลังมองหาอะไรเอาท์พุทถ้าgcd(n,m) == 1?
undergroundmonorail

ไม่เป็นไรถ้าฉันออกโดยมีข้อยกเว้น? มันจะช่วยฉันสักสองสามไบต์
undergroundmonorail

ที่จริงฉันเปลี่ยนแนวทางและไม่จำเป็นต้องออกด้วยข้อยกเว้น คนอื่นอาจต้องการทราบว่า
undergroundmonorail

อย่าออกโดยมีข้อยกเว้น ไม่เอาท์พุท :)
durron597

ในทางเทคนิคq:a+.bหรือ__ q:a+.bใน J ใช้ไม่external resources or math librariesได้ แต่ฉันจะไม่โพสต์มันเพราะมันอยู่ไกลจากจิตวิญญาณของคำถาม ฉันแค่คิดว่าฉันจะแบ่งปันที่นี่
12ıʇǝɥʇuʎs

คำตอบ:


10

Python 3, 255 250 237 226 188 180 150 142 137 136 ตัวอักษร

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)

มันยอดเยี่ยมมากที่ฉันสามารถย่อให้สั้นลงได้โดยเพียงแค่ข้ามสิ่งต่าง ๆ (เช่นคุณรู้การหา gcd)! นอกจากนี้ฉันสามารถลด 10 ตัวอักษรได้มากขึ้นด้วยการทำให้ฟังก์ชั่นนี้คาดว่า 2 ints เหมือนกับคำตอบอื่น ๆ แทนที่จะอ่านจาก stdin


นี่มันเข้มข้นมาก! ฉันเรียนรู้มากมายจากการดูการแก้ไขของคุณและพยายามเอาชนะคุณได้ ฉันคิดว่าคุณอาจมีสิ่งนี้แม้ว่า (จากคำตอบของ Python)
Rainbolt

1
คุณสามารถบันทึก 1 ตัวละครโดยเปลี่ยนwhile g<a and g<b:เป็นwhile(g<a)*(g<b):
Rainbolt

@Rusher ขอบคุณเพื่อน! คำตอบของคุณคือสิ่งที่กระตุ้นให้ฉันทำงานหนักขึ้นในเรื่องนี้ :) นอกจากนี้เคล็ดลับที่คุณแนะนำให้ฉันเป็นแรงบันดาลใจให้คิดออกa%g+b%gเล็กน้อย
Tal

ฉันไม่คิดว่าจำเป็นต้องใช้ประโยคอื่น else:g+=1อาจเป็นได้g+=1เว้นแต่ฉันจะพลาดบางสิ่งบางอย่าง
isaacg

@isaacg คุณดูเหมือนจะถูกต้องขอขอบคุณ!
Tal

8

ทับทิม - 168 117 114 101 100 97

แก้ไข: หลังจากคิดเกี่ยวกับมันฉันก็ตระหนักว่าฉันไม่ต้องการตะแกรงเนื่องจากความเป็นอันดับหนึ่งของปัจจัยได้รับการดูแลในห่วงการแยกตัวประกอบ นอกจากนี้ตามที่ได้รับคำตอบจากคนอื่น ๆ ( laindir'sและTal'sคือสิ่งที่ฉันได้เห็นมันแม้ว่าจะดูเหมือนว่าคนอื่น ๆ ทำไปแล้วก็ตาม) ให้ลบการคำนวณ gcd แยกต่างหากเนื่องจากมันเกิดขึ้นในการแยกตัวประกอบ
แก้ไข 2: doไม่จำเป็นต้อง
แก้ไข 3: บีบมันลงอีก
แก้ไข 4: ดึงที่ว่างออกอีกหนึ่งช่อง
แก้ไข 5: uptoแทน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}

เอาท์พุท (เหมือนกันหลังจากแก้ไข):

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

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

แน่นอนว่าสามารถทำให้ดีขึ้นได้ แต่ก็ไม่เลวสำหรับคนแรกของฉัน


คุณสามารถลบ 4 ไบต์โดยการเปลี่ยนไปmap{|i|i.to_i} map &:to_iคุณสามารถลบไบต์ที่ 5 โดยไม่นับบรรทัดใหม่ที่ท้ายไฟล์; ทับทิมทำงานได้โดยปราศจากมัน
kernigh

นอกจากนี้คุณยังสามารถใช้แทน$* 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`,

ล่าม

repl.it

ตัวอย่างอินพุต - stdin

100 50

ตัวอย่างผลลัพธ์ - stdout

2 ^ 1 5 ^ 2


1
เกี่ยวกับ…`a`+'^'+`f.count(a)`…อะไร
Ry-

พริตตี้ที่สะอาดผมชอบมัน
qwr

@qwr ขอบคุณ ฉันหวังว่าฉันจะเข้าใจคำตอบอื่น ๆ ของ Python การจัดรูปแบบ String และโกนอักขระบางตัว
Rainbolt

Swap f.append(i)สำหรับf+=[i]ที่จะบันทึก 5 ตัวอักษร
Nolen Royalty

1
และตอนนี้คุณไม่จำเป็นต้องใช้ f เลย: p (ทำไมf=''ยังอยู่ที่นั่น?)
Nolen Royalty

4

Java - 184 175

นี่เป็นคำตอบที่ได้รับแรงบันดาลใจจาก @Geobits (และคำตอบของ @ Tal เล็กน้อย) แต่พอมันแตกต่างกันมากที่ฉันตัดสินใจสร้างคำตอบของฉันเอง

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 (sort) กับ (การตรวจสอบโดยมนุษย์) สายรัดทดสอบ:

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

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

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

4

dc, 96 ไบต์

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

มันอ่านหนึ่งบรรทัดของอินพุตมาตรฐาน เอาต์พุตไม่ได้ลงท้ายด้วยการขึ้นบรรทัดใหม่ (แก้ไข: มันยังส่งออกพื้นที่พิเศษหลังจากแยกตัวประกอบทุกคำตอบอื่น ๆ บางส่วนตัดพื้นที่ แต่อันนี้ไม่ได้)

ตัวอย่าง:

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

รหัสที่มีความคิดเห็น:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3

PowerShell - 82

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

อันนี้สั้นและง่ายต่อการอ่าน มันท่อช่วงเป็นห่วง2..$a Foreach วัตถุ ห่วงเก็บค่าของ%{...} if($p){"$_^$p"}
kernigh

3

JavaScript (ฉบับร่าง ECMAScript 6) - 89 ตัวอักษร

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

แปลงคำตอบเดิม (ซ้ำ) ด้านล่างให้เป็นคำตอบแบบเรียกซ้ำ

คำอธิบาย

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.

คำตอบซ้ำ: JavaScript (ECMASCript 6) - 108 (หรือ 121) 98 ตัวอักษร

รุ่น 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()}

รุ่น 1:

ตอบคำถามตามที่ถามมา แต่เดิม:

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

หรือเพื่อให้สอดคล้องกับการเปลี่ยนแปลงกฎหลังจากข้อเท็จจริง:

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

คำอธิบาย

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

เอาท์พุต

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

f(14,15)
""

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

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

สวัสดีคุณลองทดสอบf(158,237)ดูได้
ไหม

มันเป็นพื้นที่ที่คั่นด้วยเลขชี้กำลัง (มันเพิ่งเกิดขึ้นจะมีพื้นที่มาก)" 79^1"
MT0

ใช่แล้วโซลูชันอื่น ๆ ไม่มีและก็ไม่มีตัวอย่าง โปรดแก้ไข :)
durron597

ไม่มีสิ่งใดในคำถามตามที่ได้ถามมา แต่เดิมกำหนดว่าช่องว่างเป็นเท่าใดหรือไม่ได้รับอนุญาต - อย่างที่ฉันเห็นมันเป็นไปตามข้อกำหนดเนื่องจากเป็นช่องว่างที่คั่นด้วย exponents อย่างไรก็ตามคุณจะไปและเปลี่ยนกฎตอนนี้ไม่ใช่คุณหรือไม่
MT0

2
ภายใต้กฎที่มีอยู่ก่อนใครสามารถพูดได้ว่าการใช้งานนี้ละเว้นข้อกำหนด "ไม่มีอะไรส่งออกถ้าอินพุตค่อนข้างดี" ยังคงดูเหมือนผิดที่ทำให้รหัสกอล์ฟที่ออกมาสวยมาก สั้นแค่ไหนที่คุณสามารถfilter()โทร?
แหลม

3

Perl 6: 90 ตัวอักษร 94 ไบต์

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

ค่อนข้างเดอกอล์ฟและแสดงความคิดเห็น:

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

การใช้งานเป็นเช่น:

$ 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

⊎เป็นสัญลักษณ์ในภาษา Perl หรือไม่? ฉันไม่รู้
durron597

@ durron597 เฉพาะ 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 ";}

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

ฉันเพิ่งเริ่มเรียนรู้ Perl เพียงเพื่อตอบคำถามนี้ (นี่เป็นรหัส Perl แรกของฉันตลอดไป) ดังนั้นฉันจึงสงสัยว่านี่จะสามารถเล่นกอล์ฟต่อไปได้


ใช่ฉันยังไม่ได้ดูที่รหัสของคุณอย่างใกล้ชิด แต่foreachก็มักจะตรงกันกับforใน Perl 5 เพื่อที่จะตัดออก 4 ตัวอักษร :)
Mouq

@Mouq ผมไม่เคยเห็นภาษาที่มีความซ้ำซ้อนมากดังนั้น ... ขอบคุณ :)
Tal

2

Java: 247 241

ติดตามปัจจัยในอาร์เรย์และพิมพ์ออกมาเป็นวง

ขนาดที่เหมาะสมสำหรับ Java ดูเหมือนว่า

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

คุณสามารถทิ้งตัวแปรอื่น ๆ ไว้ได้เพราะintคุณสูญเสีย 4 ถึงint แต่คุณจะได้รับกลับมาพร้อมกับnew int[-> new Integer[ดังนั้นมันจึงเป็นการล้าง
durron597

ใช่แล้วฉันมีสามอันด้วยการเปลี่ยนn%i<1&&m%i<1ไปn%i+m%i<1ใช้
Geobits

()คุณไม่จำเป็นต้อง ถ้าn==mมันจะเริ่มต้นที่จะm+1อยู่แล้ว
Geobits

2
คุณสามารถแทนที่m/=i;i=1;ด้วยm/=i--;มันจะทำงานได้เร็วขึ้นเช่นกัน :)
durron597

1
การจัดฟันหลังforห่วงแรกจำเป็นหรือไม่?
Ypnypn

2

JavaScript (ECMAScript 5) 170 164 163 113

ฉันสวยมากไม่สามารถต้านทานการเป็นผู้นำของ MT0 ก่อนหน้านี้ฉันเคยคิดว่าจะมีการสอบถามซ้ำ แต่มันก็ดูง่ายเกินไปที่จะทำให้ยุ่งเหยิง และมันคือเรื่องจริง รูปแบบที่น้อยที่สุดทำลายทุกอย่าง

มีซอสำหรับผู้ที่ชอบเล่นซอ

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

เวอร์ชั่นเก่า

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

นี่คือการทดสอบบางอย่าง:

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

ฟังก์ชั่นการเรียกซ้ำนี้f(301343045, 421880263);อาจล้มเหลวเนื่องจากเบราว์เซอร์ของฉันจะไม่ให้ฉันชดเชยสิ่งที่อยู่ลึก โง่ Firefox เสีย!
kernigh

อย่างแน่นอน ในทางปฏิบัติฉันจะใช้ฟังก์ชันเรียกซ้ำถ้าฉันต้องการกองซ้อนบางประเภทเช่นการนำทางต้นไม้หรือโครงสร้างข้อมูลแบบเรียกซ้ำ (แน่นอนว่าตัวเลขนั้นสามารถใช้เป็นโครงสร้างข้อมูลแบบเรียกซ้ำได้ แต่เรามี abstractions ที่ดีทุกชนิดที่จะช่วยให้เราเพิกเฉยต่อข้อเท็จจริงนั้น)
Keen

2

GolfScript, 68 ไบต์

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

โปรดทราบว่าวิธีการนี้ต้องใช้ O (b 2 ) และพื้นที่สำหรับจำนวนเต็ม“ a” และ“ b”

ด้วยค่าใช้จ่ายของหนึ่งไบต์พิเศษต้องใช้เวลาและพื้นที่ "O (b)" เท่านั้น:

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

มันทำงานอย่างไร

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

1

Python 3 (123)

นี้ใช้พื้นโครงสร้างเช่นเดียวกับคำตอบของ 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)

มันพอเพียงที่จะวนซ้ำได้ถึง p = a-1 เนื่องจากเราเพิ่มขึ้นทันทีเพื่อรับ p = a และ a> = min (a, b) หาก b> a ไม่มีอันตรายใด ๆ ในการลองค่า p ที่ไม่มีประโยชน์ข้างต้น a

ใน 2.X if c:print'%d^%d'%(p,c),ผมคิดว่าเราสามารถบันทึกตัวอักษรโดยการพิมพ์แต่ละชิ้นที่เราได้รับมันมากกว่าสะสมสตริง: Python 3 น่าเสียดายที่ไม่มีวิธีการพิมพ์ที่กะทัดรัดโดยไม่ต้องขึ้นบรรทัดใหม่


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

เราได้รหัสเดียวกันเกือบทั้งหมดแล้ว! ปรับปรุงหนึ่งของฉันคือการรวมp=0;g+=1เป็นหนึ่งในสายโดยเริ่มต้นgวันที่ 1 แทนซึ่งจะช่วยให้คุณแล้วทำมากกว่าg<a g<=aฉันหวังว่าคุณจะชอบงูใหญ่
xnor

@xnor ฉันพลาดรหัสของคุณ แน่นอนมันเกือบจะเหมือนกัน ฉันลบสคริปต์ของหลามออก ฉันหวังว่าฉันจะไม่ต้องชอบงูใหญ่ฉันต้องจัดฟัน
mleko

ไม่จำเป็นต้องลบรหัสของคุณคุณมาด้วยตัวเอง ฉันก็คิดเรื่องของเกมเป็น Tal ดังนั้นดูเหมือนว่านี่เป็นเพียงสิ่งที่ Python Golf มาบรรจบกัน
xnor

1

awk - 115 111 96 85

เวอร์ชันใหม่สามารถจัดการอินพุตหนึ่งบรรทัดเท่านั้น ขอบคุณdurron597 ที่ชี้ให้เห็นว่าฉันต้องทำให้แน่ใจ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;
}

ก่อนหน้านี้อาจใช้ตัวเลขเป็นคู่ซ้ำ ๆ

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

คุณต้องการ&&i<=bไหม
durron597

ดีฉันจะ ... คุณกำลังขวาคุณไม่ได้: ถ้าi > bแล้วb % i != 0... ขอบคุณ :)
laindir

โปรแกรมนี้ใช้ไม่ได้กับawkใน OpenBSD 5.5 เพราะNF=0;ไม่สามารถลบ $ 1 และ $ 2 ผลลัพธ์จากecho 301343045 421880263 | awk -f factorize.awk | sed 's/ */ /g'เป็น5 7 1021^1 59029^1เพราะ $ 1 คือ 5 และ $ 2 คือ 7 sed บีบพื้นที่พิเศษที่มาจากการพิมพ์ $ 1,022, $ 1023, $ 1024, ... , $ 59028 เป็นสตริงว่างร่วมกับช่องว่าง
kernigh

ขอบคุณ @ kernigh มันใช้งานได้ใน nawk, mawk และ gawk ตรวจสอบอีกครั้งที่ posix ไม่ได้พูดอะไรเกี่ยวกับการกำหนดให้กับ NF และถูกแทนที่ด้วย$0=z;
laindir

@laindir การเปลี่ยนแปลงนั้นแก้ไขโปรแกรมสำหรับฉัน รหัสกอล์ฟไม่ต้องการโปรแกรมพกพา โชคดี$0=z;ที่มีจำนวนอักขระเท่าNF=0;กัน ถ้าเป็นอีกต่อไปฉันจะบอกคุณเพื่อให้$0=z; NF=0;
kernigh

1

จุดเล็ก ๆ , 41 ไบต์

ไม่ใช่คำตอบที่แข่งขันกันเนื่องจากภาษานั้นใหม่กว่าคำถาม แต่เครื่องหมาย GolfScript ที่ 68 จำเป็นต้องลดลง

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

เอาต์พุตสิ้นสุดในพื้นที่ หากเป็นปัญหารุ่นต่อไปนี้จะเป็น 41 ไบต์ (รวมถึงการ-sตั้งค่าสถานะ)

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

จัดรูปแบบพร้อมคำอธิบาย:

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 ไม่เหมือน GolfScript, CJam, et al. เป็นภาษาที่จำเป็นสำหรับโอเปอเรเตอร์ infix; มันยังใช้แรงบันดาลใจบางอย่างจากภาษาโปรแกรมอาร์เรย์ งานนี้แสดงทั้งกระบวนทัศน์ในที่ทำงาน

(โปรดทราบว่าจำเป็นต้องใช้การมอบหมาย 2015-4-20 เพื่อดำเนินการนี้เนื่องจากฉันเพิ่งแก้ไขข้อบกพร่องสองสามข้อ)


0

Python 2 - 262 ไบต์

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

บรรทัด 6 ต้องการงาน


1
เกี่ยวกับ…`a`+'^'+`f.count(a)`…อะไร
Ry-

ฉันไม่รู้ว่าฉันพลาดมันไปได้อย่างไร Jeez ขอบคุณ
undergroundmonorail

0

Groovy: 174 ตัวอักษร

นี่เป็นพอร์ตของโซลูชันของGeobitsสำหรับ 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 ":""}"}

นี่คือรุ่นที่ไม่ได้แต่งแต้ม:

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

ประหลาดใจที่คุณเลือกที่จะแก้ปัญหาพอร์ต Geobits แทนที่จะเป็นของฉันเพราะของฉันมีความยาว 56 ตัวอักษร
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])," ")}

ด้วยการเยื้อง:

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

การใช้งาน:

> 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  
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.