유클리드 알고리즘 시각화


17

유클리드 알고리즘은 두 양의 정수의 최대 공약수 (GCD)를 계산하기 위해 널리 알려진 알고리즘입니다.

알고리즘

이 과제를 위해 알고리즘은 다음과 같이 설명됩니다.

  1. 특정 문자의 인접 라인으로 두 개의 입력 디스플레이
    의 입력 예 3,4인접하는 선에 의해 표현 될 수 0000000

  2. 첫 돌려 length(short_line)다른 문자로 긴 줄에 문자를 말하는 -
    그 모습 지금 000---0

  3. length(short_line)긴 줄에서 첫 문자를 제거하십시오 .
    지금 000,0

  4. 두 단계를 반복하여도 2 및도 3은 각각의 반복 후에는 짧고 긴 선을 이용하여, 동일한 길이를 갖도록, 예를 들어
    000, 0
    -00, 0
    00, 0
    -0, 0
    0,0

  5. 여기서 중지 할 것인지 반복을 계속할 것인지를 선택하고 한 줄을 빈 줄로 바꿀 수 있습니다.

이러한 각 단계는 0.3과 1.5 사이의 간격으로 분리해야합니다.

도전

두 개의 자연수를 입력으로하여 위 알고리즘의 출력과 정확히 동일한 출력을 생성하는 프로그램을 작성하십시오. 공백 이외의 인쇄 할 수없는 ASCII 문자는 0및 이외의 문자를 사용할 수 -있지만 일관되며 두 문자 만 사용할 수 있습니다. 타이밍을 포함하여 출력이 위 알고리즘에서 생성 된 것과 정확히 동일하다면 대체 알고리즘을 사용할 수도 있습니다.

이것은 input을 가진 예제이며 24,35, coprimes이므로 GCD는 1입니다.

여기에 이미지 설명을 입력하십시오

이것은 input과 함께 16,42GCD 2를 가진 예제입니다 .

여기에 이미지 설명을 입력하십시오

규칙


설명

  • 숫자를 나타내는 선은 원래 순서대로 유지되어야합니다. 즉, 첫 번째로 표시되는 "프레임"의 첫 번째와 두 번째 줄은 이후의 모든 프레임에서 첫 번째와 두 번째 줄이어야합니다.
  • 알고리즘이 종료 된 후에는 추가로 보이는 엔티티가 나타나지 않습니다. 그러나 이는 마지막 "프레임"이 블랭킹하기 전에 다른 모든 프레임과 동일한 시간 동안 표시되도록하는 경우에는 라인을 비워도됩니다.

@ @WheatWizard 그것에 큰 제안
busukxuan

라인이 동일한 상대 순서로 유지되어야합니까? 아니면 반복 사이에 순서를 바꿀 수 있습니까? (대부분의 언어에서 후자가 훨씬 간결하기 때문에 확인하기 때문에 최적화를 사용해야하는지 또는 sepc를 위반하여 무시해야하는지 알아야합니다.)

@ ais523 네, 그렇습니다 :-)
busukxuan

@ ais523 네, 비워도 무방하지만 마지막 프레임은 다른 프레임과 같은 표시 시간을
갖도록하십시오

1
@busukxuan 개인적으로 나는 후행 공백을 허용하지만 아마도 "의미있는"문자 중 하나는 공백이 아니라고 생각합니다.
Luis Mendo

답변:


3

젤리 , 29 바이트

VY“ñc‘ỌœS.⁸
1ẋǵ+M¦ṚÇt€2ǵ⁻/¿

온라인으로 사용해보십시오!

이것은 함수 2Ŀ(전체 프로그램이 아님; TIO 링크에는 함수를 프로그램으로 변환하는 바닥 글 포함)를 정의하여 두 요소의 목록을 입력으로 취하고 화면에 출력을 표시합니다 (법적 I / O 방법 중 하나). , 화면의 모양에 대해 이야기하기 때문에이 도전에 필요한 것). 이것은 프로그램이 ANSI 표준을 준수하는 터미널에서 실행되고 (내가 사용 gnome-terminal했지만 대부분 작동 할 것임) 터미널이 비어있는 것으로 가정합니다 (가장 합리적인 기본값처럼 보입니다). 온라인으로 사용해보십시오! 않습니다 하지 이러한 가정을 준수하고, 따라서 출력이 왜곡 (I는이 같은 예상 애니메이션화 있는지 확인하기 위해 로컬 프로그램을 실행). 내가 사용하는 대신에 .1질문에서 사용 곳을 사용 0하고2-

설명

도우미 기능 1Ŀ (두 자릿수 목록을 제공하여 화면의 첫 번째와 두 번째 줄에 출력 한 다음 0.5 초 기다립니다. 입력을 반환합니다)

VY“ñc‘ỌœS.⁸
V                   Convert each list of digits to an integer
 Y                  Separate these integers by newlines
  “ñc‘              {Output that; then restart with} the list [27, 99]
      Ọ             Convert codepoints to characters (i.e. "\x1bc"
       œS.          Wait (œS) 0.5 (.) seconds
          ⁸         {Output that; then return} the initial argument

문자열 "\ x1bc"는 ANSI 호환 터미널로 전송 될 때 터미널을 재설정하는 제어 코드로 해석됩니다. 화면을 지우고 커서를 왼쪽 상단으로 이동합니다 (따라서 다음 출력을 위해 터미널을 재설정합니다).

도우미 함수의 이름은 1Ŀ(Jelly 는 함수 에 대해이 양식의 이름을 자동으로 생성하며 실제로 다른 이름을 지정할 수있는 방법은 없습니다), Ç주 프로그램에서 간단히 참조 할 수 있습니다 (언어에 숫자가있는 함수의 약어가 있기 때문에) ).

주요 기능 2Ŀ (질문에서 요청한 작업을 구현)

1ẋǵ+M¦ṚÇt€2ǵ⁻/¿
1ẋ                  Convert input to unary
  Ç                 Call helper function (producing one animation frame)
   µ         µ  ¿   While
              ⁻/      the elements differ:
     M¦               Change the largest element
    +  Ṛ                by adding corresponding elements of the other element
        Ç             Call helper function (producing one animation frame)
         t€2          Delete all 2s from each side of each element
            Ç         Call helper function (producing one animation frame)

6

자바 스크립트 (ES6) 128 124 바이트

t=0
f=
(a,b,o,c,d)=>setInterval(e=>{e=[b,d,a,c];o.data=`-0
-0`.replace(/./g,c=>c.repeat(e.pop()));c|d?c=d=0:a>b?a-=c=b:b-=d=a},1e3)
<form><input id=a><input id=b><button onclick=clearTimeout(t),t=f(+a.value,+b.value,o.firstChild)>Go!</button><pre id=o>



2

자바 (ES6) 215 194 ... 135 129 127 바이트

a=>b=>F=(c=0)=>alert('-'[d='repeat'](e=c&a>b&&b)+'0'[d](a-=e)+`
`+'-'[d](f=c&a<b&&a)+'0'[d](b-=f))|a-b|c&&setTimeout(F,1e3,1-c)

용법

이것은 카레의 변형을 입력합니다. 이를 사용하려면 fist 함수를 변수에 할당 G한 다음 (예 :) 다음과 같이 호출하십시오.

G(5)(6)()

설명

알고리즘이 완료되지 않는 한 1 초 후에 자체 호출하는 재귀 함수입니다. 이 제 3 변수의 트랙을 유지 c여부를 결정 a하고 b변경한다 (경우 c1변화, 그것의 시간).

먼저, 함수는 콘솔에 무언가를 씁니다. cis 0인 경우 개행 문자를 포함하여 두 개의 문자열로 0을 씁니다. 이후 c에 초기화되어 0, 우리는이를 활용, 글로벌 변수를 설정할 수 있습니다 fg 종종 우리가 필요로하는 일부 문자열을 개최하는 (같은 0repeat).

그렇지 않으면 0과 마이너스로 문자열을 작성합니다. 이러한 모든 문자열은 두 부분으로 구성됩니다. 먼저 일부 (이 금액 호출 A) 마이너스, 일부 (이 수량 호출 B) 0, 개행, 일부 (이 금액 호출)D ) 마이너스 및 마지막으로 (이 금액 호출 E) 0입니다.

첫 번째 입력이 두 번째 입력보다 작 으면 두 번째 입력에서 0을 제거해야하므로 A0 이므로 B첫 번째 입력과 D같고 첫 번째 입력과 같습니다.E 두 번째 입력을 뺀 첫 번째 입력 같습니다. 첫 번째 입력이 두 번째 입력보다 작지 않으면 반대가 적용됩니다 ( A두 번째 입력, B첫 번째 입력에서 두 번째 입력을 뺀 값 등).

입력 및 전환 된 변수에 대한 이러한 새 값을 사용하면 c함수는 1e31 초와 같은 밀리 초 단위로 다시 호출되도록 예약됩니다 .

노트

  • 용도 alert 출력
  • 사용 0-예제와 마찬가지로
  • 단계 간 지연은 1000ms (1 초)입니다.
  • 첫 번째 단계 후에 함수는 (JavaScript의 특성으로 인해) 무시해야 할 숫자를 반환합니다.
  • TIO의 버전은 모든 것을 한 번에 출력하며 브라우저 콘솔에 코드를 붙여 넣으면 지연이 올바르게 고려됩니다.

온라인으로 사용해보십시오

여기 사용해보십시오!


2

파이썬 (2) , 208 (204) 194 바이트

비열한 속임수에 대한 @math_junkie 덕분에 -4 time.sleep

"투명한 화면"규칙을 명확히 해준 @busukxuan에게 감사의 말을 전한다.

def z(a,b,y='-',w=1):
 import time;c,d,n,s='0'*a,'0'*b,'\n',time.sleep
 if w:print c+n+d;s(1)
 if b>a:d=y*a+d[a:]
 else:c=y*b+c[b:]
 print c+n+d;s(1)
 if c!=d:z(len(c),len(d),('','-')[y!='-'],0)

온라인으로 사용해보십시오!

이것이 더 골프 될 수 있다고 확신하십시오. 그것은 복제 나에게 고통 print과를for일시 중지를 만들기 루프 스럽지만 현재로서는 그 방법을 찾을 수 없습니다.

노트

  • 일시 중지는 이제 @math_junkie의 힌트를 사용합니다.
  • 출력을 저장하고 프로그램이 끝나면 출력을 덤프하므로 TIO에서 완전히 작동하지 않습니다. 콘솔에서 잘 작동합니다.

1
당신은 사용하여 일부 바이트를 저장할 수 있어야합니다 import time, s=time.sleep그리고 s(1)대신 지연 루프
수학 마약 중독자

감사합니다 @math_junkie-나는 대부분의 조합을 사용 time.sleep했지만 그중 하나를 놓쳤습니다. 갈 것이다.
ElPedro

@math_junkie-나를 위해 215에 온다. 어쩌면 나는 바보 같은 것을 놓치고 있습니다. Try it Online 에 예제를 게시 할 수 있습니까 ?
ElPedro


1

161 149 바이트

... 들여 쓰기와 줄 바꿈없이 :

($a,$b)=map 0 x$_,@ARGV;
sub p{say"\n$a\n$b";sleep 1}p;
while($a ne$b){
  ($A,$B)=$b lt$a?(\$a,\$b):(\$b,\$a);
  map$$A=~s/0/-/,1..length$$B;
  p;
  $$A=~s/-//g;
  p
}

파일 gcd.pl에 넣고 다음과 같이 실행하십시오.

perl -M5.010 gcd.pl 16 42

1
-M5.010perl에 대한 플래그는 비어 있으므로 sayover 를 사용하여 몇 바이트를 절약 할 수 있습니다 print…\n. 또한 익명의 서브 루틴에 변수를 저장하지 않고 이름을 지정하는 것이 더 확실합니다.

12 바이트를 줄여주는 팁은 ais523입니다.
Kjetil S.

1

GNU Sed ( e확장자 xec), 88

점수는 +3 -zrf 옵션에 합니다 sed.

p
:
x
esleep 1
g
ta
:a
s/o+//p
t
s/^((O+)(O+)\n\2\b|(O+)\n\4\B)/\L\2\U\3\4\n\2\L\4\U/p
t

입력은 대문자를 사용하여 두 개의 줄 바꿈으로 구분 된 단항 정수로 제공됩니다. O 를 숫자로 로 제공됩니다.

예를 들어, 16, 42 예제는 다음과 같이 실행될 수 있습니다.

printf "%0*d\n%0*d\n" 16 0 42 0 | tr 0 O | sed -znrf euclidvis.sed

최신 의견에 따르면 반복 사이의 화면을 지우지 않습니다.


0

V , 47 44 바이트

Àé0á
Àé0Hqwmmjlhmmkl@wqòHî@w
gs`mlhv0r-gsÓ-ò

온라인으로 사용해보십시오!

TIO의 머리글과 바닥 글 gs은 현재 두 줄을 화면 하단에 복사하도록 수정 한 다음 마지막 두 줄을 삭제합니다. 이렇게하면 TIO에 대한 작업이 시각화되지만 V에서 (헤더 및 바닥 글없이) 실행 한 경우 각 작업간에 1 초 정도 기다립니다.

Àé0                     " Print (Arg1) zeroes
   á                    " Newline
Àé0                     " Print (Arg2) zeroes
   H                    " Go home
    qwmmjlhmmkl@wq      " Store a recursive macro in w that finds the shorter line
                  ò     " recursively
                   Hî@w " find the longest line
gs                      " wait a second
  `mlhv0r-              " replace the zeroes of the long line with -
          gs            " wait a second
            Ó-          " delete all -
              ò         " end recursion

정말로 결말이 필요 ò합니까?
Kritixi Lithos

이유없이 확실하지 않습니다. 나는 V와 컴퓨터가 때까지 모든 디버깅을 기다릴 것
nmjcman101
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.