Pengairan ASCII

19

Intro

Pertimbangkan kisi-kisi karakter f A\/seperti

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

dimana:

  • f mewakili faucet yang menuangkan aliran air ke bawah
  • A membagi dua aliran air di atas sehingga tepat setengah ke kiri dan tepat setengah ke kanan
  • \ menggeser aliran air di atas ke kanan dengan satu unit
  • / menggeser aliran air di atas ke kiri oleh satu unit
  • kombinasi \/menciptakan palung dengan kapasitas tak terbatas yang mengumpulkan aliran air di atasnya
  • [space] adalah ruang kosong yang bisa dilewati air

Dari sini kita dapat membayangkan jalan yang *akan diambil oleh air ( ) yang keluar dari faucet dan jatuh ke dalam bak atau keluar dari area grid:

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

Dengan asumsi 3 faucet menghasilkan jumlah air yang sama satu per satu kita bisa melihatnya

  • Semua air keran pertama mengalir ke bak bawah.
  • Setengah dari air keran kedua mengalir ke palung yang lebih rendah dan separuh lainnya terbelah antara palung yang lebih rendah dan jatuh dari kisi.
  • Seperempat air keran ketiga mengalir ke palung yang lebih rendah, seperempat jatuh dari dasar grid, seperempat masuk ke palung atas, dan seperempat jatuh dari grid ke kanan.

Dari sini kita dapat mengatakan bahwa (1 + 3/4 + 1/4 + 1/4) / 3 = 75%air ditangkap oleh bak dan (1/4 + 1/4 + 1/4) / 3 = 25%jatuh dari grid.

Tantangan

Anda dapat menyelesaikan salah satu atau semua tantangan ini terkait dengan pengaturan aliran air ASCII ini. Semuanya adalah kode-golf, jawaban terpendek untuk setiap tantangan adalah pemenangnya. Jawaban yang diterima adalah orang yang paling menyelesaikan tantangan, dengan panjang kode total sebagai tie-breaker.

Tantangan 1
Tulis program yang menampilkan sebagian kecil air yang mengalir ke palung untuk kisi-kisi yang diberikan. Keluaran dari contoh di atas adalah sederhana 0.75.

Tantangan 2
Tulis sebuah program yang, dengan grid, menggambar *'s di tempat-tempat air mengalir seperti yang saya lakukan di atas. Anda tidak boleh menimpa apa pun selain karakter spasi dan kisi tidak boleh mengubah ukuran. Jadi untuk sesuatu seperti

 f
/A

tidak ada yang perlu dilakukan karena, meskipun air mengalir di kedua sisi A, itu tidak dapat ditarik ke kiri tanpa melepas /dan tidak dapat ditarik ke kanan tanpa membuat grid 2 × 2 lebih besar.

Tantangan 3 (Diperbarui)
Tulis program yang menggunakan dua bilangan bulat non-negatif, total T dan jumlah untuk menjaga K (T> = K). Hasilkan dan gambarkan kisi-kisi dengan tepat fsehingga ketika faucet itu mencurahkan T unit air, tepatnya K akan mengalir ke bak. Jika tidak mungkin untuk melakukan ini dalam grid terbatas untuk pasangan (T, K) tertentu, maka output 'Mustahil'.

Klarifikasi (berlaku untuk semua tantangan)

  • Input dapat melalui stdin, atau file, atau bahkan panggilan fungsi pada representasi string dari grid. Cukup jelaskan bagaimana menjalankan input yang berbeda.
  • Output harus menuju stdout.
  • \Adan A/dan AAjuga palung seperti yang Anda harapkan.
  • Grid w oleh h akan selalu berupa persegi panjang yang diformat dengan karakter w * h tanpa menghitung baris baru. Tidak akan ada spasi tambahan dan tidak ada kejadian *.
  • Dimensi grid bisa sekecil 1 × 1 dan besar sewenang-wenang. (Cukup besar untuk alasan, int.maxValue atau sejenisnya adalah batas yang dapat diterima. Hal yang sama berlaku untuk T dan K.)
  • Aliran di atas fmengalir tepat melaluinya.
  • Keran bisa di mana saja, tidak hanya di baris atas.
  • A selalu membagi jumlah air yang dituangkan tepat di setengahnya.

Catatan: Hal-hal seperti /Adan //sangat valid. Air tidak bebas mengalir antara karakter (meskipun untuk tantangan 2 tidak ada cukup ruang untuk menggambar).

Jadi, dalam pengaturan

ff

/A

Aliran kiri fmengalir turun, mengenai /dan bergeser ke kiri. Aliran kanan fmengalir ke bawah, mengenai A, setengah ke kanan dan setengah ke kiri antara Adan /.

misalnya

 ff
 **
*/A*
** *
** *
Hobi Calvin
sumber
3
+1 Tantangan bagus. Sedangkan untuk tantangan 3, kisi di atas tidak akan menjadi jawaban yang valid karena memiliki 3 fs
edc65
@ edc65 Ah, tangkapan bagus!
Hobi Calvin
2
Sangat sangat mirip: codegolf.stackexchange.com/questions/26059/…
Howard
2
Untuk tantangan kedua, Anda perlu menentukan cara menangani input seperti /Ajika air jatuh ke atas A. Untuk semua tantangan, akan baik untuk mengklarifikasi apakah \Apalung. Untuk tantangan ketiga, haruskah 3 unit jatuh pada Adiasumsikan terbelah 1.5 / 1.5(jadi input benar-benar bilangan rasional tunggal) atau itu 2 / 1, dalam hal mana pihak yang menerima 2?
Peter Taylor
1
@PeterTaylor Terima kasih. Saya sudah mengklarifikasi poin-poin itu. Saya kira T dan K bisa jadi mengapung tapi saya menjaga mereka bilangan bulat untuk kesederhanaan. (Tetapi jika T = 3 tidak mengenai satu Amaka kedua belah pihak mendapatkan 1,5. Terserah koder untuk memastikan presisi float tidak menjadi masalah.)
Calvin Hobbies

Jawaban:

3

Semua Tantangan C # 690bytes (416bytes + 274bytes)

Tantangan 1 & 2 C # 579 446 416 byte

Ini adalah program lengkap yang harus mengerjakan Tantangan 1 & 2, hanya tentang. Bunyinya baris input dari stdin sampai menerima baris kosong. Mencetak hasil untuk Tantangan 2, dan kemudian hasil untuk Tantangan 1. Menggunakan kelas desimal .NET untuk menghindari kesalahan pembulatan.

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

Kurang bermain 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);
    }
}

Uji coba (dengan kurangnya ruang tambahan yang saya janjikan ada di sana):

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

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

Tantang 3 C # 274bytes

Ini adalah program lengkap yang harus menyelesaikan Tantangan 3. Saya seorang berhasil menyelamatkan 6bytes dengan menulis parser bilangan bulat saya sendiri untuk membaca masukan daripada Spliting ReadLinedan menggunakan 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"));}}

Kurang bermain 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"));
    }
}

Uji coba (lagi-lagi dengan kurangnya ruang tambahan yang saya janjikan ada di sana):

32 17
 f
AA
/ /
 A
/ /
 A
/ /
 A
/ /
AA
/ /
VisualMelon
sumber
3

Pertama-tama, saya punya pertanyaan tentang tantangan. Karena saya tidak memiliki reputasi yang cukup untuk mengomentari pertanyaan itu, saya menulisnya di sini:

  • Apa perilaku /A(air yang mengalir di A), //(air yang mengalir di sisi kanan) dan variasi prinsip ini? Apakah air mengalir ke "tempat bebas" pertama di samping atau apakah mengalir "di bawah" tetangganya?

Hanya dengan mencoba yang sederhana, ini dapat disederhanakan waaaaay (yang akan saya lakukan nanti dengan mengedit posting ini).

Sunting: Versi kedua, sedikit lebih kecil. Saya melakukan pendekatan yang berbeda: alih-alih mencari setiap sel untuk memeriksa apa yang datang dari atas dan samping, saya mulai dari keran dan "mengalir" ke bawah dengan rekursi.

Javascript, 226 byte (Tantangan 1)

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 byte (Tantangan 2)

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 byte (Tantangan 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)};

Cara Penggunaan

Berikan representasi dua dimensi dari peta. Berikut adalah contoh yang diberikan dalam pertanyaan:

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

Keluaran

Tantangan 1: Ini hanya akan membuat kotak dialog (peringatan) dengan hasilnya (0,75 untuk contoh di atas).

Tantangan 2: Ini akan langsung mengubah peta. Haruskah saya mencetaknya? Jika demikian, apakah console.log diterima? sebagai output yang valid?

Tantangan 1 + 2: Keduanya digabungkan, jelas ...

refreshfr
sumber
Air terus mengalir di antara karakter seolah-olah memeluk garis Aatau garis miring. Saya sudah mengklarifikasi itu dalam pertanyaan.
Hobi Calvin
Pertanyaannya menyatakanOutput must go to stdout.
user80551
Anda ditentukan sebagai format input yang harus Anda berikan array string satu karakter per baris, tetapi ingatlah Anda dapat mengindeks str[0]ke string. Itu akan menjadi array string, bukan array array karakter.
tommeding
1
user80551 Terima kasih, saya tidak tahu mengapa itu keluar dari pikiran saya. Saya akan memperbarui kode saya sesegera mungkin. @tommeding Ya, itu berfungsi untuk jawaban saya atas tantangan 1. Tapi untuk tantangan 2 Saya langsung memodifikasi input dan Anda tidak dapat mengubah karakter dalam string menggunakan str [i], maka penggunaan array array.
refreshfr
2

Python 3, 186 byte (Tantangan 3)

Saya mengambil ide untuk grid dari jawaban VisualMelon . Fungsi harus mencetak kisi yang valid ke stdout untuk T dan K besar yang sewenang-wenang, asalkan dimungkinkan (kisi ukuran terbatas) tentu saja.

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)

Cara Penggunaan

Panggil cfungsi dengan jumlah dan jumlah total untuk disimpan sebagai argumen.

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

>>> c(6, 2)
Impossible
Sianogenoid
sumber