アスキー水道


19

イントロ

次のf A\/ような文字のグリッドを考えます

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

ここで:

  • f 水の流れを下に注ぐ蛇口を表します
  • A 上の水の流れを分岐させて、ちょうど半分が左に、半分が右に行くようにします
  • \ 上の水の流れを1単位だけ右にシフトします
  • / 上の水の流れを左に1単位シフトします
  • 組み合わせ\/は、その上の水流を収集する無限の容量を持つトラフを作成します
  • [space] 水が通過できるよりも空きスペースです

これから、水(*)が蛇口から出て、トラフまたはグリッド領域のいずれかに落ちるときに通る経路を想像できます。

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つの蛇口が同じ量の水を一度に1つずつ出力すると仮定すると、

  • 最初の蛇口の水はすべて下のトラフに流れます。
  • 2番目の蛇口の水の半分は下部トラフに流れ、残りの半分は下部トラフとグリッドからの落下に分けられます。
  • 3番目の蛇口の水の4分の1が下部トラフに流れ、1/4がグリッドの底から流れ落ち、4分の1が上部トラフに流れ込み、1/4がグリッドの右に流れ落ちます。

このことから(1 + 3/4 + 1/4 + 1/4) / 3 = 75%、水がトラフに捕捉され(1/4 + 1/4 + 1/4) / 3 = 25%、グリッドから落ちることがわかります。

課題

このASCII水流設定に関連するこれらの課題のいずれかまたはすべてを完了することができます。それらはすべてコードゴルフであり、各チャレンジの最短回答が勝者です。受け入れられる答えは、最も長いチャレンジを完了した人であり、コードの合計長はタイブレーカーです。

課題1
特定のグリッドの谷に流入する水の割合を出力するプログラムを作成します。上記の例の出力は、単にになります0.75

課題2
グリッドを指定して、*上記のように水が流​​れる場所にを描画するプログラムを作成します。スペース文字以外は上書きしないでください。グリッドのサイズを変更しないでください。のようなもの

 f
/A

Aの両側に水が流れますが、水を除去せずに左に引く/ことはできず、2×2グリッドを大きくせずに右に引くことはできないため、何もする必要はありません。

課題3(更新済み)
2つの非負整数、合計TおよびKを保持する量(T> = K)を取り込むプログラムを作成します。f蛇口がT単位の水を注ぐと、正確にKがトラフに流れるように、グリッドを1つだけ生成して描画します。特定の(T、K)ペアの有限グリッドでこれを行うことが不可能な場合、「不可能」を出力します。

明確化(すべての課題に適用)

  • 入力は、stdin、ファイル、またはグリッドの文字列表現での関数呼び出しを介して行うことができます。異なる入力の実行方法を明確にするだけです。
  • 出力はstdoutに送信する必要があります。
  • \AそしてA/AAあなたが期待するようにまた谷です。
  • w x hグリッドは、常に改行をカウントしないw * h文字の適切にフォーマットされた長方形になります。末尾のスペースが欠落したり、が出現したりすることはありません*
  • グリッドの寸法は、1×1程度の小ささで、任意に大きくすることができます。(理由の範囲内で任意に大きく、int.maxValueなどは許容範囲です。TおよびKについても同様です。)
  • 上のストリームは、その中をf流れます。
  • 蛇口は、上の列だけでなく、どこにでも配置できます。
  • A 常に注ぐ水の量を正確に半分に分けます。

注:のようなもの/Aとは//完全に有効です。キャラクター間で水自由に流れます(ただし、チャレンジ2の場合、水を引くのに十分なスペースがありません)。

だから、セットアップで

ff

/A

左のfストリームが流れ落ち、ヒットし/、左にシフトします。右側のfストリームが降り注ぎ、をヒットしA、半分が右に進み、半分がの間で左に移動A/ます。

例えば

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

3
+1ナイスチャレンジ。それは3持っているので、挑戦3については、一番上のグリッドは、有効な回答ではありませんfS
edc65

@ edc65ああ、いいキャッチ!
カルビンの趣味14


2
2番目の課題では、/A水がに落ちる場合のように入力を処理する方法を指定する必要がありますA。すべての課題について\A、トラフであるかどうかを明確にするとよいでしょう。3番目の課題では、3つのユニットAが分割されると想定される1.5 / 1.5ので(入力は実際には単一の有理数になります)2 / 12それともどちらの側が受信しますか?
ピーターテイラー14

1
@PeterTaylorありがとう。これらの点を明確にしました。TとKは浮動小数点数になる可能性があると思いますが、簡単にするために整数のままにします。(ただし、T = 3がヒットしたA場合、両側は1.5になります。フロートの精度が問題にならないことを確認するのはコーダー次第です。)
カルビンの趣味14

回答:


3

すべてのチャレンジC#690bytes(416bytes + 274bytes)

Challenges 1&2 C#579 446 416bytes

これは、チャレンジ1および2を実行する完全なプログラムです。空行を受け取るまで、stdinから入力行を読み取ります。チャレンジ2の結果を出力し、次にチャレンジ1の結果を出力します。

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

少ないゴルフ:

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

テスト実行(末尾にスペースがないことを約束します):

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

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

チャレンジ3 C#274bytes

これは、チャレンジ3を完了する必要のある完全なプログラムです。私は、Splita ReadLineを使用して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"));}}

少ないゴルフ:

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

テスト実行(ここでも、末尾にスペースがないことを約束します):

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

3

まず、チャレンジについて質問があります。私は質問にコメントするのに十分な評判がないので、ここに書いています:

  • 行動は何ですか/A(Aに流れる水)、 //(水が右側に流れる)と、この原則のバリエーションは?水は側面の最初の「自由な場所」に流れますか、それとも隣の「下」に流れますか?

単純に試してみると、単純化できます(この投稿を編集して後で行います)。

編集: 2番目のバージョン、少し小さい。私は別のアプローチを試みました。上部と側面から来るものをチェックするために各セルを探すのではなく、蛇口から始めて再帰で下に「流れ」ます。

Javascript、226バイト(チャレンジ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バイト(チャレンジ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バイト(チャレンジ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)};

使い方

マップの2次元表現を提供します。質問で提供されている例は次のとおりです。

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

出力

課題1:結果を含むダイアログボックス(アラート)を作成します(上記の例では0.75)。

課題2:マップを直接変更します。 印刷する必要がありますか?その場合、console.logは受け入れられますか?有効な出力として?

課題1 + 2:上記の両方を組み合わせて、明らかに ...


キャラクターの間に水が流れ続け、まるでそれがAスラッシュやスラッシュのラインを抱いているようになります。質問でそれを明確にした。
カルバンの趣味

質問の状態Output must go to stdout.
user80551

入力形式として、行ごとに1文字の文字列の配列を指定するように指定しましたが、文字列にインデックスstr[0]を付けることができることに留意してください。これは、文字の配列の配列ではなく、文字列の配列になります。
tomsmeding

1
user80551おかげで、なぜそれが私の頭から抜け落ちたのかわかりません。できるだけ早くコードを更新します。@tomsmedingはい、チャレンジ1の私の答えには機能します。しかし、チャレンジ2の場合、入力を直接変更しているため、str [i]を使用して文字列の文字を変更できません。
refreshfr

2

Python 3、186バイト(チャレンジ3)

VisualMelonの答えからグリッドのアイデアを取りました。関数は、可能であれば(有限サイズのグリッド)、任意の大きなTとKの有効なグリッドを標準出力に出力する必要があります。

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)

使い方

c引数として保持する合計量と量で関数を呼び出します。

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

>>> c(6, 2)
Impossible
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.