Öklid algoritmasını görselleştirin


17

Öklid algoritması, iki pozitif tam sayının en büyük ortak bölenini (GCD) hesaplamak için yaygın olarak bilinen bir algoritmadır.

Algoritma

Bu zorluğun amacı için, algoritma aşağıdaki gibi açıklanmaktadır:

  1. Belirli bir karakter bitişik çizgileri, iki giriş görüntü
    bir girişi, örneğin 3,4komşu hatlar ile temsil edilebilir 000ve0000

  2. İlk çevirin length(short_line)başka karakterin içine uzun satırındaki işareti, demek -
    benzediğini şimdi 000ve---0

  3. length(short_line)Uzun satırdaki ilk karakterleri kaldırın .
    şimdi 000,0

  4. İkiye kadar tekrarlayın Adım 2 ve 3, her yineleme sonrası daha kısa ve daha uzun hatları kullanarak, aynı uzunluğa sahip, örneğin
    000, 0
    -00, 0
    00, 0
    -0, 0
    0,0

  5. Burada durmayı veya yinelemeye devam etmeyi ve satırlardan birini boş bir satıra dönüştürmeyi seçebilirsiniz.

Bu adımların her biri 0.3 ile 1.5 saniye arasında bir aralık ile ayrılmalıdır.

Meydan okuma

Girdi olarak iki doğal sayı verilen, yukarıdaki algoritmanın çıktısıyla tam olarak aynı görünen bir çıktı oluşturan bir program yazın. Boşluk olmayan diğer yazdırılabilir ASCII karakterlerini 0ve dışında -kullanabilirsiniz, ancak tutarlı olun ve yalnızca iki karakter kullanın. Çıktı, zamanlama da dahil olmak üzere, yukarıdaki algoritma tarafından üretilecekle tamamen aynı olduğu sürece alternatif algoritmalar da kullanabilirsiniz.

Örnekler

Bu, 24,35GCD'leri 1 olan kopyalar olan girdi içeren bir örnektir .

resim açıklamasını buraya girin

Bu, 16,42GCD 2'ye sahip girişli bir örnektir .

resim açıklamasını buraya girin

kurallar


Açıklamalar

  • Sayıları temsil eden satırların orijinal sıralarında kalmaları gerekir, yani ilk görüntülenen "kare" nin ilk ve ikinci satırlarının sonraki tüm karelerde sırasıyla birinci ve ikinci satır olması gerekir.
  • Algoritma sona erdikten sonra, görünür hiçbir ek varlık görünmemelidir. Bununla birlikte, son "kare" nin, boşluk bırakmadan önce diğer tüm karelerle en az aynı süre boyunca görüntülendiğinden emin olursanız, satırları boşaltmanın da uygun olduğu anlamına gelir.

@WheatWizard harika öneri, üstünde
busukxuan

Çizgiler aynı göreceli sırada mı kalmalıdır? Veya yinelemeler arasında yeniden sıralanabilirler mi? (İkinci dilin çoğu dilde çok daha kısa olması muhtemel olup olmadığını kontrol ediyorum ve bu nedenle sepciti ihlal ettiği için bu optimizasyonu kullanmalı mıyım yoksa görmezden mi gelmem gerektiğini bilmeliyim.)

@ ais523 Evet yapıyorlar:-)
busukxuan

@ ais523 Evet, boşaltmak uygun değil, ancak son kareye diğer karelerle aynı görüntüleme süresi verildiğinden emin olun
busukxuan

1
@busukxuan Şahsen ben sondaki boşluklara izin vereceğimi düşünüyorum, ama belki de "anlamlı" karakterlerden biri olarak yer değil
Luis Mendo

Yanıtlar:


3

Jöle , 29 bayt

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

Çevrimiçi deneyin!

Bu, bir işlevi tanımlar 2Ŀ(tam bir program değil; TIO bağlantısı, işlevi iki öğenin listesini girdi olarak alan ve çıktıyı ekranda (yasal G / Ç yöntemlerimizden biri) görüntüleyen bir altbilgi içerir. ve bu meydan okuma için gerekli olan bir şeydir, çünkü ekrandaki görünümden bahseder). Bu, programın ANSI standardıyla uyumlu bir terminalde çalıştırıldığını (kullandığım gnome-terminalancak çoğu çalışacağım) ve terminalin başlangıçta boş olduğunu (en mantıklı varsayılan gibi görünüyor); çevrimiçi deneyin unutmayın! does not bu varsayımlara uygun ve böylece çıkış orada bozulur (Ben beklendiği gibi animasyon doğrulamak için lokal programı koştu). Kullandığım nerede soru kullanımları ve yerine .102-

açıklama

Yardımcı işlevi 1Ŀ (iki basamaklı listenin bir listesi verildiğinde, bunları ekranın ilk ve ikinci satırlarına çıkarır, sonra 0,5 saniye bekler; girişini döndürür)

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

ANSI uyumlu bir terminale gönderildiğinde "\ x1bc" dizesi, terminali sıfırlamak için bir kontrol kodu olarak yorumlanır; bu ekranı temizler ve imleci sol üst köşeye taşır (böylece terminali bir sonraki çıkış için hazır hale getirir).

Yardımcı işlev adlandırılır 1Ŀ(Jelly, işlevler için bu formun adlarını otomatik olarak oluşturur ve aslında bunları adlandırmanın başka bir yolu yoktur), ancak yalnızca Çana programdan olduğu gibi ifade edilebilir (çünkü dil, yakındaki sayılara sahip işlevler için kısayol içerir) ).

Ana işlev 2Ŀ (soruda istenen görevi yerine getirir)

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

JavaScript (ES6), 128 124 bayt

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>


3

Python 2 , 152146 bayt

import time
s,o='-0'
a,b=input()
while a*b:
 d,e=o*a,o*b
 if a>b:a=a-b;d=s*b+o*a
 elif b>a:b=b-a;e=s*a+o*b
 else:a=0
 print d+'\n'+e;time.sleep(1)

Çevrimiçi deneyin!


Girdi olarak virgülle ayrılmış iki tam sayı alır


Güzel bir cevap.
ElPedro

2

JavaScript (ES6), 215 194 ... 135 129 127 bayt

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)

kullanım

Bu, köri üzerinde bir varyasyon alır. Kullanmak için, işlevi bir değişkene (örneğin G) fist atayın , ardından şu şekilde çağırın:

G(5)(6)()

açıklama

Algoritma bitmediği sürece 1 saniye sonra kendini çağıran biraz özyinelemeli işlev. Bu üçüncü bir değişken izler cbelirler olmadığını ave bdeğiştirilmesi gerektiğini (eğer colduğunu 1değişim için, 's zamanı).

İlk olarak, fonksiyon konsola bir şey yazar. Öyleyse c, 0aralarında yeni satır bulunan iki sıfır dizesi yazar. Yana chiç bir sıfırlanır 0, bu yararlanmak ve küresel değişkenler ayarlayabilirsiniz fve gbenzeri (genellikle ihtiyacımız bazı dizeleri tutmak olduğunu 0verepeat ).

Aksi takdirde, sıfır ve eksileri olan bir dize oluşturur. Tüm bu dizeler iki bölümden oluşur: önce bazıları (bu miktarı çağır A) eksi, sonra bazıları (bu miktarı çağır B) sıfır, sonra bir satırsonu, sonra bazıları (bu miktarı çağır D) eksi ve son olarak bazı (bu miktarı çağır E) sıfırlar.

İlk giriş ikinci girişten küçükse, ikinci girişteki sıfırları kaldırmamız gerekir, yani Asıfırdır, Bilk girişe Deşittir, ilk girişe Eeşittir ve ikinci giriş eksi ilk girişe eşittir. İlk giriş ikinci girişten daha küçük değilse, tersi geçerlidir ( Aikinci giriş, Bilk giriş eksi ikinci giriş vb.).

Giriş ve anahtarlamalı bir değişken için bu yeni değerlerle c, işlevin 1e3milisaniye cinsinden yeniden çağrılması planlanır , bu da bir saniyeye eşittir.

notlar

  • alertÇıktı için kullanır
  • Kullanımlarda 0ve -tıpkı örneklerde olduğu gibi
  • Adımlar arasındaki gecikme 1000 ms'dir (1 saniye)
  • İlk adımdan sonra, işlev (JavaScript'in doğası gereği) göz ardı edilecek bir sayı döndürür
  • TIO'daki sürüm her şeyi bir kerede çıkarır, kodu tarayıcı konsoluna yapıştırmak gecikmeleri düzgün bir şekilde dikkate alır

Çevrimiçi deneyin

Burada deneyin!


2

Python 2 , 208 204 194 bayt

-4 ile sinsi hüner için math_junkie teşekkürler time.sleep

-10 "net ekran" kuralını açıklamak için @busukxuan sayesinde.

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)

Çevrimiçi deneyin!

Bu daha golf olabilir eminim. Bu çoğaltmak bana acı printveforDuraklama oluşturmak için döngüyü ama şu anda bunun için bir yol bulamıyorum.

notlar

  • Duraklama artık @math_junkie tarafından bir ipucu kullanıyor
  • Çıktıyı depoladığı ve program bittiğinde çıkardığı için TIO üzerinde tam olarak çalışmaz. Konsolda iyi çalışıyor.

1
Sen kullanarak bazı bayt kaydetmek gerekir import time, s=time.sleepve s(1)bunun yerine gecikme için bir döngü
matematik bağımlısı

Teşekkürler @math_junkie - Çoğu kombinasyonu kullanarak denedim time.sleepama bunu kaçırdım. Bir şans vereceğim.
ElPedro

@math_junkie - benim için 215'e geliyor. Belki aptalca bir şeyi özlüyorum. Çevrimiçi Deneyin'e bir örnek gönderebilir misiniz ?
ElPedro


1

perl, 161149 bayt

... girintiler ve yeni satırlar olmadan:

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

Bir dosyaya gcd.pl koyun ve şu şekilde çalıştırın:

perl -M5.010 gcd.pl 16 42

1
-M5.010Eğer kullanarak birkaç byte kaydedebilirsiniz böylece Perl için bayrak, serbesttir sayüzerinde print…\n. Buna ek olarak, anonim altyordamınıza bir değişkende saklamak yerine bir ad vermenin ters olduğuna eminim.

12 bayt tıraş ipuçları için ax523 için teşekkürler
Kjetil S.

1

GNU Sed ( exec uzantılı), 88

Puan -zrfseçenekleri için +3 içerir 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

Girdi, büyük harfleri Orakam olarak kullanarak iki satır başı ayrılmış tekli tamsayı olarak verilir .

Örneğin, 16, 42 örneği şu şekilde çalıştırılabilir:

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

En son yorumlara göre, iterasyonlar arasındaki ekranı temizlemiyorum.


0

V , 47 44 bayt

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

Çevrimiçi deneyin!

TIO'daki üstbilgi ve altbilgi gs, geçerli iki satırı ekranın altına kopyalamak için değiştirilir ve sonunda ilk ikisini siler. Bu, TIO için işlemi görselleştirir, ancak V'de (üstbilgi ve altbilgi olmadan) çalıştırırsanız, her işlem arasında bir saniye beklenir.

Àé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

Sonuna gerçekten ihtiyacın var òmı?
Kritixi Lithos

Onsuz asılı, neden emin değilim. Herhangi bir hata ayıklamak için üzerinde V olan bir bilgisayar olana kadar bekleyecek
nmjcman101
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.