ASCII Su İşleri


19

giriş

f A\/Gibi karakterlerin bir ızgarasını düşünün

f  f  f  
      A  
   A / \ 
\ /     A
    A \/ 
   /     
 \/         

nerede:

  • f bir su akışını aşağıya akan bir musluğu temsil eder
  • A su akışını iki katına çıkarır, böylece yarısı tam sola ve yarısı sağa gider
  • \ su akışını bir birim sağa kaydırır
  • / su akışını bir birim sola kaydırır
  • kombinasyonlar \/, üstündeki su akışlarını toplayan sonsuz kapasiteye sahip bir çukur yaratır
  • [space] suyun hareket edebileceğinden daha fazla boş alan

Buradan, suyun ( *) musluklardan çıktığı ve oluklara veya ızgara alanının dışına düştüğü sırada izleyeceği yolu hayal edebiliriz :

f  f  f    <-- first second and third faucets
*  * *A* 
* *A*/ \*
\*/ *  *A  <-- a '*' is not drawn to the right of this A because it would be out of the 9×7 bounds
 * *A*\/   <-- upper trough
 **/ *   
 \/  *     <-- lower trough

3 armatürün her seferinde aynı miktarda su verdiğini varsayarsak,

  • İlk musluğun suyu alt oluğa gider.
  • İkinci musluğun suyunun yarısı alt oluğa giderken, diğer yarısı alt oluk ve ızgaradan düşüyor.
  • Üçüncü musluğun suyunun dörtte biri alt oluğa gider, dörtte biri ızgaranın dibinden düşer, dörtte biri üst oluğa düşer ve dörtte biri sağdaki ızgaradan düşer.

Buradan (1 + 3/4 + 1/4 + 1/4) / 3 = 75%suyun oluklara yakalandığını (1/4 + 1/4 + 1/4) / 3 = 25%ve şebekeden düştüğünü söyleyebiliriz .

Zorluklar

Bu ASCII su akışı kurulumuyla ilgili bu zorlukların herhangi birini veya tümünü tamamlayabilirsiniz. Hepsi kod golf, her meydan okuma için en kısa cevap kazanır. Kabul edilen cevap, toplam kod uzunluğu kravat kırıcı olarak en fazla zorluğu tamamlayan kişi olacaktır.

Zorluk 1
Belirli bir ızgara için oluklara akan suyun fraksiyonunu veren bir program yazın. Yukarıdaki örneğin çıktısı basitçe olacaktır 0.75.

Zorluk 2
Bir ızgara verildiğinde, *yukarıda yaptığım gibi suyun aktığı yerlere çeken bir program yazın . Boşluk karakterlerinin yanı sıra hiçbir şeyin üzerine yazmamalısınız ve ızgara boyutunu değiştirmemelidir. Yani böyle bir şey için

 f
/A

Su A'nın her iki tarafından akmasına rağmen, çıkarılmadan sola /çekilemez ve 2 × 2 ızgarayı büyütmeden sağa çizilemez.

Zorluk 3 (Güncelleme)
Toplam T ve K tutacak miktar olmak üzere iki negatif olmayan tamsayı alan bir program yazın (T> = K). Tam olarak bir tane ile bir ızgara oluşturun ve çizin f, böylece musluk T ünite su döktüğünde, tam olarak K oluklara akacaktır. Bunu belirli bir (T, K) çifti için sonlu bir ızgarada yapmak mümkün değilse 'İmkansız' çıktısını alın.

Açıklamalar (tüm zorluklar için geçerlidir)

  • Giriş stdin veya bir dosya veya hatta ızgaranın dize gösterimi üzerindeki bir işlev çağrısı yoluyla olabilir. Farklı girişlerin nasıl çalıştırılacağını açıkça belirtmeniz yeterlidir.
  • Çıktı stdout'a gitmelidir.
  • \Ave A/ve AAbeklediğiniz gibi de çukurlarının vardır.
  • Bir g x h ızgarası her zaman yeni satırları saymayan w * h karakterlerinin iyi biçimlendirilmiş bir dikdörtgeni olacaktır. Sondaki boşluklar eksik olmayacak *.
  • Izgara boyutları 1 × 1 kadar küçük ve keyfi olarak büyük olabilir. (Makul değer dahilinde keyfi olarak büyük, int.maxDeğer veya benzeri kabul edilebilir bir sınırdır. T ve K için de geçerlidir.)
  • Üstünden bir dere fakar.
  • Musluklar sadece üst sırada değil, herhangi bir yerde olabilir.
  • A üzerine dökülen su miktarını daima ikiye böler.

Not: gibi /Ave //tamamen geçerlidir. Su yok (meydan okuma 2 için çizmek için yeterli yer olmasa da) serbestçe karakterler arasında akar.

Yani, kurulumda

ff

/A

Sol fakış aşağı akar, vurur /ve sola kayar. Doğru fakım, aşağıya dökülüyor vurur A, yarım doğru gider ve yarım arasında kalan gider Ave /.

Örneğin

 ff
 **
*/A*
** *
** *

3
+1 Güzel bir meydan okuma. O 3'ün çünkü meydan 3 gelince, üstündeki ızgara geçerli bir cevap olmaz fler
edc65

@ edc65 Ah, iyi yakala!
Calvin'in Hobileri


2
İkinci zorluk için, /Asuyun üzerine düşüyormuş gibi girişi nasıl ele alacağınızı belirtmeniz gerekir A. Tüm zorluklar için \A, bir oluk olup olmadığını açıklığa kavuşturmak iyi olur . Üçüncü meydan okuma için, düşen 3 ünitenin Abölüneceği varsayılacaktır 1.5 / 1.5(bu nedenle girdi gerçekten tek bir rasyonel sayıdır) mı yoksa 2 / 1bu durumda hangi tarafın 2?
Peter Taylor

1
@PeterTaylor Teşekkürler. Bu noktaları netleştirdim. Sanırım T ve K yüzen olabilir ama basitlik için tamsayı tutuyorum. (Ama T = 3 vurursa, Aher iki taraf da 1.5 kazanır. Şamandıra hassasiyetinin bir sorun olmadığından emin olmak kodlayıcıya bağlıdır.)
Calvin'in Hobileri

Yanıtlar:


3

Tüm Zorluklar C # 690bayt (416bayt + 274bayt)

1 & 2 C # Güçlükler 579 446 416bytes

Bu meydan okuma 1 ve 2, hemen hemen yapması gereken tam bir programdır. Boş bir satır alana kadar stdin'den girdi satırlarını okur. Challenge 2 sonucunu ve sonra Challenge 1 sonucunu yazdırır. Umarım yuvarlama hatalarından kaçınmak için .NET ondalık sınıfını kullanır.

using C=System.Console;class P{static void Main(){decimal u,t=0,f=0;string c,z="";for(decimal[]n=null,o;(c=C.ReadLine())!="";z+='\n'){int s=c.Length,i=s,e;o=n;n=new decimal[s];for(o=o??n;i-->0;n[i]+=(e&2)*u/2){e=c[i]%13;u=o[i]/(e<1?2:1);if(e%8<1)if(i>0)if(c[i-1]%7<3)t+=u;else n[i-1]+=u;if(e<2)if(i<s-1)if(c[i+1]%2>0)t+=u;else n[i+1]+=u;if(e>9){u++;f++;}}for(;++i<s;)z+=c[i]<33&n[i]>0?'*':c[i];}C.WriteLine(z+t/f);}}

Daha az golf:

using C=System.Console;
class P
{
    static void Main()
    {
        decimal u,t=0,f=0;
        string c,z="";

        for(decimal[]n=null,o;(c=C.ReadLine())!="";z+='\n')
        {
            int s=c.Length,i=s,e;
            o=n;
            n=new decimal[s];
            for(o=o??n;i-->0;n[i]+=(e&2)*u/2)
            {
                e=c[i]%13;
                u=o[i]/(e<1?2:1);

                if(e%8<1)
                    if(i>0)
                        if(c[i-1]%7<3)t+=u;
                        else n[i-1]+=u;
                if(e<2)
                    if(i<s-1)
                        if(c[i+1]%2>0)t+=u;
                        else n[i+1]+=u;
                if(e>9)
                {
                    u++;
                    f++;
                }
            }
            for(;++i<s;)
                z+=c[i]<33&n[i]>0?'*':c[i];
        }

        C.WriteLine(z+t/f);
    }
}

Test çalıştırması (söz verdiğim sondaki boşlukların olmaması ile):

f  f  f
      A
   A / \
\ /     A
    A \/
   /
 \/

f  f  f
*  * *A*
* *A*/ \*
\*/ *  *A
 * *A*\/
 **/ *
 \/  *
0.75

Görev 3 C # 274bytes

Bu bir girişi okumak için kendi tamsayı ayrıştırıcı yazma ziyade tarafından 6bytes kurtarmayı başardı 3. Meydan tamamlamalıdır komple programdır Splitbir ing ReadLineve kullanma long.Parse;

using C=System.Console;class P{static void Main(){long t=-1,f=t,k;for(;f<0;)for(f=t,t=0;(k=C.Read())>47;)t=t*10+k-48;var r="Impossible\n";for(k=t;k<t*f;)k*=2;if(f<1||(k/f)*f==k)for(r=" f \n";t>0&t<f;t-=(t/f)*f)r+=((t*=2)<f?" ":"A")+"A \n/ /\n";C.Write(r+(t<f?"":"AAA\n"));}}

Daha az golf:

using C=System.Console;
class P
{
    static void Main()
    {
        long t=-1,f=t,k;
        for(;f<0;)
            for(f=t,t=0;(k=C.Read())>47;)
                t=t*10+k-48;

        var r="Impossible\n";
        for(k=t;k<t*f;)
            k*=2;
        if(f<1||(k/f)*f==k)
            for(r=" f \n";t>0&t<f;t-=(t/f)*f)
                r+=((t*=2)<f?" ":"A")+"A \n/ /\n";
        C.Write(r+(t<f?"":"AAA\n"));
    }
}

Test çalıştırması (yine söz verdiğim sondaki boşlukların eksikliği ile):

32 17
 f
AA
/ /
 A
/ /
 A
/ /
 A
/ /
AA
/ /

3

Her şeyden önce, meydan okuma ile ilgili bir sorum var. Soru hakkında yorum yapmak için yeterli üne sahip olmadığım için buraya yazıyorum:

  • Davranışı nedir /A, (su A akan) //bu ilkenin (su sağ tarafında akan) ve varyasyonları? Su, yandaki ilk "serbest noktaya" akıyor mu yoksa komşusunun "altında" mı akıyor?

Sadece basit bir deneme, waaaaay basitleştirilmiş olabilir (ki bu yazıyı düzenleyerek daha sonra yapacağım).

Düzenleme: İkinci sürüm, biraz daha küçük. Farklı bir yaklaşım için gittim: her hücreyi üstten ve yandan gelenleri kontrol etmek yerine, musluklardan başlayıp özyineleme ile aşağıya "akıyorum".

Javascript, 226 bayt (1. Zorluk)

function f(c){function h(b,a,d,e){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"==e||"A"==e?g+=d:h(b,a+1,d,"\\"):"/"==c[b][a]?"\\"==e||"A"==e?g+=d:h(b,a-1,d,"/"):"A"==c[b][a]?"A"==e||"\\"==e||"/"==e?g+=d:(h(b,a-1,d/2,"A"),h(b,a+1,d/2,"A")):h(b+1,a,d,c[b][a]))}for(var g=0,m=0,k=0;k<c.length;k++)for(var l=0;l<c[k].length;l++)"f"==c[k][l]&&(h(k+1,l,1),m++);alert(g/m)};

Javascript, 204 bayt (2. Zorluk)

function f(c){function e(b,a,d){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"!=d&&"A"!=d&&e(b,a+1,"\\"):"/"==c[b][a]?"\\"!=d&&"A"!=d&&e(b,a-1,"/"):"A"==c[b][a]?"A"!=d&&"\\"!=d&&"/"!=d&&(e(b,a-1,"A"),e(b,a+1,"A")):(" "==c[b][a]&&(c[b][a]="*"),e(b+1,a,c[b][a])))}for(var g=0;g<c.length;g++)for(var h=0;h<c[g].length;h++)"f"==c[g][h]&&e(g+1,h)};

Javascript, 238 bayt (Zorluk 1 + 2)

function f(c){function h(b,a,d,e){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"==e||"A"==e?g+=d:h(b,a+1,d,"\\"):"/"==c[b][a]?"\\"==e||"A"==e?g+=d:h(b,a-1,d,"/"):"A"==c[b][a]?"A"==e||"\\"==e||"/"==e?g+=d:(h(b,a-1,d/2,"A"),h(b,a+1,d/2,"A")):(" "==c[b][a]&&(c[b][a]="*"),h(b+1,a,d,c[b][a])))}for(var g=0,m=0,k=0;k<c.length;k++)for(var l=0;l<c[k].length;l++)"f"==c[k][l]&&(h(k+1,l,1),m++);alert(g/m)};

Nasıl kullanılır

Haritanın iki boyutlu bir temsilini sağlayın. Soruda verilen örnek şöyledir:

var input = [["f"," "," ","f"," "," ","f"," "," "],[" "," "," "," "," "," ","A"," "," "],[" "," "," ","A"," ","/"," ","\\"," "],["\\"," ","/"," "," "," "," "," ","A"],[" "," "," "," ","A"," ","\\","/"," "],[" "," "," ","/"," "," "," "," "," "],[" ","\\","/"," "," "," "," "," "," "]];
f(input);

Çıktı

Zorluk 1: Sonuçla birlikte bir iletişim kutusu (uyarı) oluşturacaktır (yukarıdaki örnek için 0,75).

Zorluk 2: Haritayı doğrudan değiştirecektir. Yazdırmalı mıyım? Öyleyse, console.log kabul edilir mi? geçerli bir çıktı olarak?

Zorluk 1 + 2: Yukarıdakilerin her ikisi de bir araya geldi, belli ki ...


Su, karakterler Aveya eğik çizgilerin çizgilerini sarıyormuş gibi karakterler arasında akmaya devam ediyor . Bunu soruda açıklığa kavuştum.
Calvin'in Hobileri

Soru devletleriOutput must go to stdout.
user80551

Her satıra bir karakter dizisi dizisi vereceğiniz giriş biçimi olarak belirlediniz, ancak str[0]dizelere dizin oluşturabileceğinizi unutmayın . Bu, bir dizi karakter dizisi yerine bir dize dizisi olurdu.
tomsmeding

1
user80551 Teşekkürler, neden aklımdan çıktığını bilmiyorum. Kodumu en kısa zamanda güncelleyeceğim. @tomsmeding Evet, meydan okuma 1'e verdiğim yanıt için çalışıyor.
refreshfr

2

Python 3, 186 bayt (Challenge 3)

Izgara fikrini VisualMelon'un cevabından aldım . Tabii ki (sonlu boyutlu ızgara) olması koşuluyla, işlev keyfi olarak büyük T ve K için stdout'a geçerli bir ızgara yazdırmalıdır.

from fractions import*
def c(T,K):
 p=print;g=gcd(T,K);K//=g;T//=g
 if T&(T-1):p('Impossible')
 else:
  p(' f ')
  while T-1:
   T//=2;p('A/'[K<T]+'A \n///')
   if K>=T:K-=T
  p('AAA'*K)

Nasıl kullanılır

cİşlevi bağımsız değişken olarak tutacak toplam tutar ve tutarla çağırın .

>>> c(24, 9)
 f 
/A 
///
AA 
///
AA 
///

>>> c(6, 2)
Impossible
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.