Надрукуйте просту факторизацію найбільшого спільного дільника двох чисел


17

Назва говорить все це. Два вхідні 32-бітні додатні цілі числа m, n >= 2, вихід gcd(m,n)у формі простих факторів.

Вхідні дані

Арг командного рядка або 1 рядок стродінь добре, що краще для гольфу.

Вихідні дані

Єдиний простір, розмежований експонентами (без додаткових пробілів). Вихід нічого, якщо входи відносно прості.

Приклади:

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

$ ./factorize 14 15


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

Правила

  • Ви не можете використовувати зовнішні ресурси, математичні бібліотеки або вбудовані функції для факторизації або GCD. Приклади: Java, ні java.lang.Math. ruby, no prime_division, perl, no factoretc.

1
Який вихід ви шукаєте, якщо gcd(n,m) == 1?
підземниймонорельс

Чи добре, якщо я виходжу з виключенням? Це врятувало б мені кілька байт.
підземниймонорельс

Насправді я змінив свій підхід і не потрібно виходити за винятком. Інші, можливо, хочуть знати.
підземниймонорельс

Не виходьте за винятком. Виведіть нічого :)
durron597

Технічно q:a+.bабо __ q:a+.bв J не використовується external resources or math libraries, але я його не публікую, оскільки це занадто далеко від духу питання. Я просто думав, що поділюсь цим тут.
ɐɔıʇǝɥʇuʎs

Відповіді:


10

Пітон 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 вкладиші, як і деякі відповіді, замість читання з stdin.


Це інтенсивно! Я багато навчаюсь, спостерігаючи за вашими правками та намагаючись перемогти вас хаха. Думаю, у вас це може бути (хоч із відповідей Python)
Rainbolt

1
Ви можете зберегти 1 персонаж, змінивши while g<a and g<b:наwhile(g<a)*(g<b):
Rainbolt

@Rusher Спасибі товариш! Ваша відповідь така, що мотивувала мене до цього більше працювати :) Також трюк, який ви рекомендували, надихнув мене розібратися в цьому a%g+b%gшматочку
Тал

Я не думаю, що інше застереження не потрібно. else:g+=1могло бути просто g+=1, якщо я чогось не пропускаю.
isaacg

@isaacg Ви, здається, маєте рацію, дякую!
Тал

8

Ruby - 168 117 114 101 100 97

Редагувати: Подумавши про це, зрозумів, що мені не потрібно сито, оскільки первинність фактора піклується в циклі факторизації. Крім того, як повідомили відповіді інших ( лайндір і Тал - це ті, з ким я це бачив, хоча, схоже, це зробили і інші), вилучили окремий розрахунок 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

Пітон 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)`…?
Ри-

Досить чисто, мені це подобається
qwr

@qwr Дякую Я сподіваюся, що я можу зрозуміти інші відповіді Python на формат струн і поголити кілька символів.
Rainbolt

Переключити f.append(i)на , f+=[i]щоб зберегти 5 символів.
Nolen Royalty

1
А тепер вам взагалі не потрібно використовувати f: p (чому це f=''все-таки є?)
Nolen Royalty

4

Ява - 184 175

На це надихає відповідь @Geobits (і трохи відповіді @ Тала), але досить багато іншого, що я вирішив створити свою власну відповідь.

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

Невикольований (тип) з тестовим джгутом (перевірка людиною):

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

постійного струму, 96 байт

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

Він читає один рядок стандартного вводу. Його вихід не закінчується новим рядком. (EDIT: Він також видає додатковий простір після кожної факторизації. Деякі з інших відповідей обробляють простір, але цей не робить.)

Приклад:

$ 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-Object %{...}. Цикл збирає значення 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)будь ласка
durron597

Це простір, розмежований експонентами (у нього просто трапляється багато місця)" 79^1"
MT0

Правильно, інших рішень цього немає, як і приклад. Виправте :)
durron597

Нічого в питанні, як спочатку задавали, не визначає, скільки пробілів є чи заборонено - як я бачу, це відповідає вимогам, оскільки це пробіли, розмежовані експонентами. Однак зараз ти збираєшся змінити правила, чи не так?
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 Я ніколи не бачив мови з такою надмірністю ... дякую :)
Тал,

2

Ява: 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.
Геобіць

Вам це не потрібно (). Якщо n==mвона все m+1одно буде за замовчуванням .
Геобіць

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

Безголовки:

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

Безголовки:

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!
Керніг

Звичайно. На практиці я використовував би рекурсивну функцію лише в тому випадку, якщо мені дійсно потрібен якийсь стек, наприклад, для навігації по дереву або інших притаманних їм рекурсивних структур даних. (Звичайно, цифри можна розглядати як рекурсивні структури даних, але у нас є всілякі приємні абстракції, які допомагають нам ігнорувати цей факт.)
Кін

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

Пітон 3 (123)

Це в основному використовує ту саму структуру, що і відповідь Тала .

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 Я пропустив ваш код. Дійсно, це майже те саме. Я видалив свій скрипт python. Я сподіваюся, що мені не доведеться сподобатися python, Я
ТРЕБУЮ

Не потрібно видаляти код, ви придумали його самостійно. Я також придумав в основному ігрову річ, як Тал, тому схоже, що це саме те, до чого сходиться гольф Python.
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

Безголовки:

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

Безголовки:

{
    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 > bb % i != 0
знаєш

Ця програма не працює з 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. Сед видаляє додаткові пробіли, що надходять з друку $ 1022, $ 1023, $ 1024, ..., 59028 $ як порожні рядки, з'єднані пробілами.
kernigh

Завдяки @kernigh, він працює в nawk, mawk та gawk. Повторно перевірив, що позиція нічого не говорить про присвоєння до NF, і замінив його$0=z;
laindir

@laindir Ця зміна виправляє програму для мене. Код гольфу не вимагає, щоб програми були портативними. На щастя $0=z;, така ж кількість символів, як і NF=0;. Якби $0=z;було довше, я б сказав вам зберегти NF=0;.
Керніг

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 та ін. - імперативна мова з операторами інфікування; це також потребує певного натхнення з мов програмування масиву. Це завдання чудово відображає обидві парадигми на роботі.

(Зауважте, що для виконання цього потрібно виконати комісію 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)`…?
Ри-

Я поняття не маю, як я це пропустив. Jeez. Спасибі.
підземниймонорельс

0

Грувий: 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  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.