유클리드 알고리즘 (가장 큰 제수를 찾는 데 사용)


22

도전

프로그램 또는 두 개의 입력 정수 소요 함수 작성 i하고 j, 자신의 최대 공약수를 출력하는 단계; 유클리드 알고리즘 을 사용하여 계산 합니다 (아래 참조).


입력

입력은 공백으로 구분 된 문자열 표현 ij/ 또는 두 개의 개별 정수 로 취할 수 있습니다 . 정수가 10,000보다 작거나 같다고 가정 할 수 있습니다. 입력 정수가 서로 소수가 아니라고 가정 할 수도 있습니다.


유클리드 고장

사이의 더 큰 수 i와는 j가능한 횟수만큼 작은으로 분할된다. 그런 다음 나머지가 추가됩니다. 이 프로세스는 나머지가 이전이 될 때까지 나머지와 이전 숫자로 반복됩니다 0.

예를 들어, 입력이 1599 650다음 과 같은 경우

1599 = (650 * 2) + 299
 650 = (299 * 2) +  52
 299 =  (52 * 5) +  39
  52 =  (39 * 1) +  13
  39 =  (13 * 3) +   0

마지막 숫자 13는 두 입력 정수의 최대 공약수입니다. 다음과 같이 시각화 할 수 있습니다.


산출

출력은 위의 형식으로 분류 한 다음 줄 바꿈과 GCD가 있어야합니다. 모든 매체를 통해 출력 할 수 있습니다.


입력

18 27
50 20
447 501
9894 2628

출력

27 = (18 * 1) + 9
18 =  (9 * 2) + 0
9

50 = (20 * 2) + 10
20 = (10 * 2) +  0
10

501 = (447 * 1) + 54
447 =  (54 * 8) + 15
 54 =  (15 * 3) +  9
 15 =   (9 * 1) +  6
  9 =   (6 * 1) +  3
  6 =   (3 * 2) +  0
3

9894 = (2628 *  3) + 2010
2628 = (2010 *  1) +  618
2010 =  (618 *  3) +  156
 618 =  (156 *  3) +  150
 156 =  (150 *  1) +    6
 150 =    (6 * 25) +    0
6

참고 : 출력이 위와 같이 간격을 둘 필요는 없습니다. 간격은 명확성을위한 것입니다. 괄호가 필요합니다.


보너스

출력이 위와 같이 떨어져 있으면 점수에 -10 %의 보너스를 추가 할 수 있습니다.


1. 가장 큰 숫자가 먼저 주어진다고 가정 할 수 있습니까? 2. 보너스로, 당신은 필드 너비가 일정해야하며 가장 큰 숫자 앞에 한 칸을 허용하기에 충분해야합니까? ( 두 번째 숫자 열의 왼쪽 괄호 앞에 공백 이옵니다.) 출력이 가변적 일 때 "위와 같이"와 같이 모호한 문구를 피해야합니다. 필요한 출력이 고정되어 있으면 괜찮습니다.
Level River St

Ok 몇 개의 사례가 두번째로 큰 것을 보았습니다
Level River St

원래 제목은 괜찮 습니다 . meta.codegolf.stackexchange.com/q/7043/15599 에서 발생한 일에 대해 언급했습니다 . 그러나 "가장 큰 분모"라는 문구는 틀 렸습니다. "분모"는 분획에 관한 것이다. 인터넷 검색 "가장 큰 공분모"는 "가장 큰 공약수 / 인수"에 대한 결과 만 제공합니다.
Level River St

제목은 괜찮다고 생각했지만 다른 사람을 불쾌하게하지 않기 위해 "The"로 변경했습니다. BTW "제수"편집에 감사드립니다. @steveverrill
Zach Gates

답변:


4

Pyth, 33 바이트

ASQWGs[H\=\(G\*/HG\)\+K%HG)A,KG)H

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

ASQWGs[H\=\(G\*/HG\)\+K%HG)A,KG)H
  Q                                read the two numbers from input
 S                                 sort them
A                                  and assign them to G and H
   WG                              while G != 0:
                      K%HG           assign H mod G to K
     s[H\=\(G\*/HG\)\+K   )          join the following list items and print:
                                        H=(G*(H/G))+K
                           A,KG      assign K, G to G, H
                               )   end while
                                H  print H

7

CJam, 46 43 39 바이트

q~]$3*~\{N5$"=("3$:G'*3$Gmd")+"\}h]7>NG

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

q~]    e# Read all input, evaluate it and wrap the results in an array.
$3*    e# Sort the array and repeat it thrice.
~\     e# Dump the array and swap its last two elements.
{      e# Do:
  N    e#   Push a linefeed.
  5$   e#   Copy the sixth topmost element from the stack.
  "=(" e#   Push that string.
  3$:G e#   Copy the fourth topmost element from the stack. Save it in G.
  '*   e#   Push that character.
  3$   e#   Copy the fourth topmost element from the stack.
  Gmd  e#   Push quotient and remainder of its division by G.
  ")+" e#   Push that string.
  \    e#   Swap the string with the remainder.
}h     e#   If the remainder is positive, repeat the loop.
]7>    e# Wrap the stack in an array and discard its first seven elements.
NG     e# Push a linefeed and G.

6

파이썬 2, 70

f=lambda a,b:b and'%d=(%d*%d)+%d\n'%(a,b,a/b,a%b)*(a>=b)+f(b,a%b)or`a`

여러 줄 문자열을 반환하는 재귀 함수입니다. 이 함수는 첫 번째 줄을 만든 다음 유클리드 알고리즘의 다음 숫자 쌍을 사용하여 재귀 결과에 추가합니다. 두 번째 숫자가 0이면 다른 숫자의 문자열을 기본 사례로 사용하여 끝에 자체 줄에 인쇄됩니다.

형식화는 정수 나누기를 사용하여 곱셈을 얻는 문자열 대체를 통해 수행됩니다.

하나의 딸꾹질은 더 큰 숫자로 시작하여 작은 숫자로 시작해야합니다. 편리하게도 숫자의 순서가 잘못된 경우 유클리드 알고리즘의 첫 번째 단계에서 숫자가 반전됩니다. 이 단계가 표시되지 않도록하려면 첫 번째 숫자가 두 번째 숫자 이상인 경우에만 현재 행을 추가하십시오 (예 : 같음 f(9,9)).


5

awk, 78 77

x=$1{for(x<$2?x+=$2-(y=x):y=$2;t=y;x=t)print x"=("y"*"int(x/y)")+",y=x%y}$0=x

입력을 크기별로 정렬하려면 많은 바이트
가 필요합니다.

x=$1;
if(x<$2) x+=$2-(y=x); # add $2 subtract $1 and set y to $1
else y=$2;            # set y to $2

산출

650 1599 (입력)
1599 = (650 * 2) + 299
650 = (299 * 2) + 52
299 = (52 * 5) + 39
52 = (39 * 1) + 13
39 = (13 * 3) + 0
13

그것의 재미를 위해 나는 또한 제대로 간격을 둔 버전을 만들었고, 233 * 0.9 == 209.7 바이트의 점수를주었습니다.

업데이트 285 바이트에서 이것을 줄일 수 있었고 이제 -M옵션으로 gawk4를 호출하면 임의로 긴 숫자를 사용할 수 있습니다.

x=$1{x<$2?x+=$2-(y=x):y=$2;a=length(x);b=length(y);for(d=length(x%y);t=y;x=t){$++i=x;$++i=y;if(c<l=length($++i=int(x/y)))c=l;$++i=y=x%y}while(j<NF)printf "%"a"d = %"b-length($(j+2))"s(%d * %"c"d) + %"d"d\n",$++j,_,$++j,$++j,$++j}$0=x

그러나 나는 여전히 어딘가에 정신적 장애가 생겼다는 느낌을 받았다 ...

출력 (gawk4로 호출 awk -M -f code.awk)

6837125332653632513763 18237983363879361 (입력)
6837125332653632513763 = (18237983363879361 * 374883) + 15415252446024000
     18237983363879361 = (15415252446024000 * 1) + 2822730917855361
     15415252446024000 = (2822730917855361 * 5) + 1301597856747195
      2822730917855361 = (1301597856747195 * 2) + 219535204360971
      1301597856747195 = (219535204360971 * 5) + 203921834942340
       219535204360971 = (203921834942340 * 1) + 15613369418631
       203921834942340 = (15613369418631 * 13) + 948032500137
        15613369418631 = (948032500137 * 16) + 444849416439
          948032500137 = (444849416439 * 2) + 58333667259
          444849416439 = (58333667259 * 7) + 36513745626
           58333667259 = (36513745626 * 1) + 21819921633
           36513745626 = (21819921633 * 1) + 14693823993
           21819921633 = (14693823993 * 1) + 7126097640
           14693823993 = (7126097640 * 2) + 441628713
            7126097640 = (441628713 * 16) + 60038232
             441628713 = (60038232 * 7) + 21361089
              60038232 = (21361089 * 2) + 17316054
              21361089 = (17316054 * 1) + 4045035
              17316054 = (4045035 * 4) + 1135914
               4045035 = (1135914 * 3) + 637293
               1135914 = (637293 * 1) + 498621
                637293 = (498621 * 1) + 138672
                498621 = (138672 * 3) + 82605
                138672 = (82605 * 1) + 56067
                 82605 = (56067 * 1) + 26538
                 56067 = (26538 * 2) + 2991
                 26538 = (2991 * 8) + 2610
                  2991 = (2610 * 1) + 381
                  2610 = (381 * 6) + 324
                   381 = (324 * 1) + 57
                   324 = (57 * 5) + 39
                    57 = (39 * 1) + 18
                    39 = (18 * 2) + 3
                    18 = (3 * 6) + 0
삼

일부 줄 바꿈 및 탭 추가

x=$1{
    x<$2?x+=$2-(y=x):y=$2;
    a=length(x);
    b=length(y);
    for(d=length(x%y);t=y;x=t)
    {
        $++i=x;
        $++i=y;
        if(c<l=length($++i=int(x/y)))c=l;
        $++i=y=x%y
    }
    while(j<NF)
        printf "%"a"d = %"b-length($(j+2))"s(%d * %"c"d) + %"d"d\n",
                                               $++j,_,$++j,$++j,$++j
}$0=x

처음에는 x, y 및 x % y의 초기 값 길이를 저장할 수 있습니다. 각 단계마다 짧아 질 수 있기 때문입니다. 그러나 길이에 따라 길이가 다를 수 있기 때문에 인쇄하기 전에 최대 길이를 결정해야합니다. 내가 사용하는 $i그것이 [i]는 모든 시간을 사용하는 것에 비해 두 개의 문자를 저장하기 때문에, 여기에 배열한다.


4

C ++, GCC 컴파일러, 171 바이트 (-10 %, 154 바이트)

알았어 그래서 첫 시도 ..

#include<iostream>
using namespace std;
int main()
{
    int a,b,c;
    cin>>a>>b;
    if(a<b)
    swap(a,b);
    while(b>0)
    {
        c=a;
        cout<<a<<" = ("<<b<<" * "<<a/b<<") + "<<a%b<<endl;
        a=b;
        b=c%b;
    }
    cout<<a;
}

골프 코딩 팁.

추신 c ++을 사용하는 동안 표준 헤더 파일의 바이트와 int main을 계산해야합니까? 제외하면 50 바이트가 줄어 듭니다.


참고 : 코드를 예쁘게 만드는 데 사용 된 공백을 제외했습니다.
Devang Jayachandran

3

T-SQL (2012+), 268 바이트

재귀 CTE를 실행하는 인라인 테이블 함수로 구현되었습니다. 10 %의 보너스를 위해 포맷팅을 시도하는 것이 가치가있을 수 있지만, 기다려야합니다.

CREATE FUNCTION E(@ INT,@B INT)RETURNS TABLE RETURN WITH M AS(SELECT IIF(@<@B,@B,@)A,IIF(@>@B,@B,@)B),R AS(SELECT A,B,A/B D,A%B R FROM M UNION ALL SELECT B,R,B/R,B%R FROM R WHERE 0<>R)SELECT CONCAT(A,'=(',B,'*',D,')+',R)R FROM R UNION ALL SELECT STR(B)FROM R WHERE R=0

설명 및 사용법 :

--Create the function
CREATE FUNCTION E(@ INT,@B INT)RETURNS TABLE RETURN
WITH
    --Order the input correctly
    M AS (
          SELECT IIF(@<@B,@B,@)A,
                 IIF(@>@B,@B,@)B
          )
    --Recursive selection
    ,R AS (
          SELECT A,B,A/B D,A%B R FROM M -- Anchor query
          UNION ALL
          SELECT B,R,B/R,B%R FROM R     -- Recurse until R = 0
          WHERE 0<>R
          )
SELECT CONCAT(A,'=(',B,'*',D,')+',R)R   -- Concat results into output string
FROM R 
UNION ALL                               -- ALL required to maintain order
SELECT STR(B)                           -- Add final number
FROM R WHERE R=0

--Function Usage
SELECT * FROM E(447,501)

R
-----------------------------------------------------
501=(447*1)+54
447=(54*8)+15
54=(15*3)+9
15=(9*1)+6
9=(6*1)+3
6=(3*2)+0
3

2

개정 1 : Ruby, 86

Doorknob의 팁 덕분에 재귀 알고리즘.

f=->i,j{j>i&&(i,j=j,i)
0<j ?(print i," = (#{j} * #{i/j}) + #{i%j}
";f[j,i%j]):puts(i)}

개정 0 : 루비, 93

이것은 실제로 전혀 효과가 없었습니다. while루프는 특히에 너무 많은 문자를 차지합니다 end. 나는 그것을 피하는 방법을 볼 수 없습니다. 재귀에는 람다 대신 명명 된 함수가 필요하며 많은 문자를 소비합니다.

->i,j{j>i&&(i,j=j,i)
while j>0
print(i," = (#{j} * #{i/j}) + #{i%j}\n")
i,j=j,i%j
end
puts i}

다음과 같이 호출하십시오.

f=->i,j{j>i&&(i,j=j,i)
while j>0
print(i," = (#{j} * #{i/j}) + #{i%j}\n")
i,j=j,i%j
end
puts i}

I=gets.to_i
J=gets.to_i

f.call(I,J)

당신은 재귀 a=->i,j{...}와 전화 a를 통해 a[1,2]문자 를 사용할 수 있는지 확실하지 않습니다.
Doorknob

팁에 대한 @Doorknob 덕분에, 람다 함수를 호출하는 구문을 알지 못했습니다 (내 사용 참조 f.call) 실제로는 약간 짧지 만 여전히 먼 파이썬입니다.
Level River St

2

PowerShell, 84

변수에 저장된 재귀 코드 블록입니다. 다음과 같이 호출하십시오 & $e num1 num2.

$e={$s,$b=$args|Sort;if(!$s){$b}else{$r=$b%$s;"$b=($s*$(($b-$r)/$s))+$r";&$e $s $r}}

PS D:\> & $e 9894 2628
9894=(2628*3)+2010
2628=(2010*1)+618
2010=(618*3)+156
618=(156*3)+150
156=(150*1)+6
150=(6*25)+0
6

더 읽기 쉬운 형태로 다음을 수행합니다 (더 명확한 코드를 위해 전체 커맨드 릿 이름, 문자열에 더 많은 공백을 넣고 파이프 라인 출력 명령을 명시 적으로 만들었습니다).

function Euclid {
    $small, $big = $args|Sort-Object   #Sort argument list, assign to two vars.

    if (!$small) {                     #Recursion end, emit the last
        Write-Output $big              #number alone, for the last line.

    } else {                           #main recursive code

        $remainder = $big % $small
        Write-Output "$big = ( $small* $(($big-$remainder)/$small)) + $remainder"
        Euclid $small $remainder
    }
}

codegolf 관점에서 하나의 성가심; PoSh에는 정수 나누기가 없으며 10/3은 Double을 반환하지만 결과를 정수로 캐스팅하고 항상 반올림하지는 않습니다. N.5를 가장 가까운 짝수 -위 또는 아래로 반올림 합니다. 그래서 [int](99/2) == 50.

두 가지 어색한 선택이 남습니다.

$remainder = $x % $y
$quotient = [Math]::Floor($x/$y)

# or, worse

$remainder=$null
$quotient = [Math]::DivRem($x, $y, [ref]$remainder)

그렇기 때문에 몇 가지 캐릭터를 태워야합니다.

$remainder = $big % $small
($big - $remainder)/$small

그 외에도, 그것은의 수입니다

그리고 실제로 아파하는 삼항 연산자의 부족.

또한 84 버전의 반복 버전이 있습니다.

{$r=1;while($r){$s,$b=$args|Sort;$r=$b%$s;"$b=($s*$(($b-$r)/$s))+$r";$args=$s,$r}$s}

완전히 익명의 코드 블록이므로

& {*codeblock*} 1599 650



2

자바 스크립트 (ES6), 74 50 62 61 55 바이트

f=(x,y)=>y?y>x?y:x+`=(${y}*${x/y|0})+${x%=y}
`+f(y,x):x
  • 12 바이트를 희생하여 정수를 가장 큰 순서가 아닌 순서대로 전달할 수 있습니다.

시도 해봐

f=(x,y)=>y?y>x?y:x+`=(${y}*${x/y|0})+${x%=y}
`+f(y,x):x
o.innerText=f(i.value=683712533265363251376,j.value=18237983363879361)
i.oninput=j.oninput=_=>o.innerText=f(+i.value,+j.value)
<input id=i type=number><input id=j type=number><pre id=o>


설명

f=          :Assign the function to variable f ...
(x,y)=>     :And take the two integer inputs as arguments via parameters x and y.
y?          :If y is greater than 0 then
y>x?        :    If y is greater than x then
f(y,x)      :        Call f again, with the order of the integers reversed.
            :        (This can only happen the first time the function is called.)
:           :    Else
x           :        Start building the string, beginning with the value of x.
+`=(        :        Append "=(".
${y}        :          The value of y.
*           :          "*"
${x/y|0}    :          The floored value of x divided by y
)+          :          ")+"
${x%=y}     :          The remainder of x divided by y, which is assigned to x
            :          (x%=y is the same as x=x%y.)
\n          :          A newline (a literal newline is used in the solution).
`+f(y,x)    :        Append the value f returns when y and the new value of x
            :        are passed as arguments.
:           :Else
x           :    Return the current value of x,
            :    which will be the greatest common divisor of the original two integers.

1

JS, 151

a=prompt("g","");b=prompt("l","");c=0;l=[a,b];for(var i=0;i<=1;i++){t=c;o=c+1;r=c+2;n=l[t]%l[o];if(n!==0){l[r]=n;c=c+1;i=0;}else{p=l[o];alert(p);i=2;}}

1

C, 83 바이트

g(x,y,z){y&&(printf("%u=(%u*%u)+%u\n",x,y,x/y,z=x%y),z)?g(y,z,0):printf("%u\n",y);}

테스트 및 결과

int main()
{g(18,27,0);
 g(50,20,0);
 g(447,501,0);
 g(9894,2628,0);
}

18=(27*0)+18
27=(18*1)+9
18=(9*2)+0
9
50=(20*2)+10
20=(10*2)+0
10
447=(501*0)+447
501=(447*1)+54
447=(54*8)+15
54=(15*3)+9
15=(9*1)+6
9=(6*1)+3
6=(3*2)+0
3
9894=(2628*3)+2010
2628=(2010*1)+618
2010=(618*3)+156
618=(156*3)+150
156=(150*1)+6
150=(6*25)+0
6

0

자바 133

public void z(int i,int j){for(int d=1;d!=0;i=j,j=d){d=i%j;System.out.println(i+"=("+j+"*"+((i-d)/j)+")+"+d);}System.out.println(i);}

일반적인 유클리드 알고리즘은 수행하지 않습니다. 대신, 계수를 사용한 다음 인쇄 할 때 곱할 두 번째 숫자를 계산합니다. 람다 식으로 바꿔서 더 짧게 만들 수도 있지만 방법을 잘 모르겠습니다.

public void z(int i, int j)
{
    for(int d=1;d!=0;i=j,j=d)
    {
        d=i%j;
        System.out.println(i+"=("+j+"*"+((i-d)/j)+")+"+d);
    }
    System.out.println(i);
}

1.5 년이 지났다는 것을 알고 있지만를 제거 public 하고 초 printlnprint로 변경 d!=0하고d>0 있습니다. 또한 현재 첫 번째 행에 대해 잘못된 출력을 제공합니다. if(d!=i)앞에 추가하여 수정할 수 있습니다 System.out.println(i+"=("+j+"*"+((i-d)/j)+")+"+d);. : 그래서 총 void z(int i,int j){for(int d=1;d>0;i=j,j=d){d=i%j;if(d!=i)System.out.println(i+"=("+j+"*"+((i-d)/j)+")+"+d);}System.out.print(i);}( 131 바이트 및 버그 수정)
케빈 Cruijssen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.