ABAA / ABBB:この再帰的な2Dパターンを生成


30

次の興味深い再帰パターンに出くわしたとき、無限抵抗ネットワーク(長い話)をいじっていました。

|-||
|---

このパターンの各インスタンスは、高さの2倍の幅です。パターンのあるレベルから次のレベルに進むには、この長方形を2つのサブブロックに分割します(それぞれがNxNの正方形です)。

AB =
|-||
|---

so A = 
|-
|-

and B = 
||
--

これらの半分は、次のパターンに従って複製および再配置されます。

ABAA
ABBB

giving

|-|||-|-
|---|-|-
|-||||||
|-------

チャレンジ

数値を指定して、この再帰的設計のth番目の反復をN出力するプログラム/関数を作成しNます。これはゴルフです。

I / O形式は比較的緩やかです。単一の文字列、文字列のリスト、文字の2D配列などを返すことができます。任意の末尾の空白を使用できます。0または1のインデックスを使用することもできます。

パターンの最初のいくつかの反復は次のとおりです。

N = 0
|-

N = 1
|-||
|---

N = 2
|-|||-|-
|---|-|-
|-||||||
|-------

N = 3
|-|||-|-|-|||-||
|---|-|-|---|---
|-|||||||-|||-||
|-------|---|---
|-|||-|-|-|-|-|-
|---|-|-|-|-|-|-
|-||||||||||||||
|---------------

N = 4
|-|||-|-|-|||-|||-|||-|-|-|||-|-
|---|-|-|---|---|---|-|-|---|-|-
|-|||||||-|||-|||-|||||||-||||||
|-------|---|---|-------|-------
|-|||-|-|-|-|-|-|-|||-|-|-|||-|-
|---|-|-|-|-|-|-|---|-|-|---|-|-
|-|||||||||||||||-|||||||-||||||
|---------------|-------|-------
|-|||-|-|-|||-|||-|||-|||-|||-||
|---|-|-|---|---|---|---|---|---
|-|||||||-|||-|||-|||-|||-|||-||
|-------|---|---|---|---|---|---
|-|||-|-|-|-|-|-|-|-|-|-|-|-|-|-
|---|-|-|-|-|-|-|-|-|-|-|-|-|-|-
|-||||||||||||||||||||||||||||||
|-------------------------------

この構造を計算するための短い代数的方法があるのだろうか。


「代数的」とはどういう意味ですか?
user202729

4
@ user202729同様にf(n,x,y)、特定の座標に-またはを含める必要があるかどうかを直接計算できる「単純な」数学式があります|。モジュロ演算またはビット演算が含まれる場合があります。私がこれまでに見てきた技術はすべて、仕様に示されているように、配列の切断/結合を伴います。
PhiNotPi

3
f(x,y)場合以降も、作品x,y有効で、結果は依存しませんn
アマラ

2
出力に1のインデックスを付ける、つまり入力1を与えることはでき|-ますか?
ズガルブ

2
これは損失ですか?🤔
QWR

回答:


13

APL(Dyalog Classic)29 25バイト

'|-'[{a,⊖⌽⍉~a←⍪⍨⍵}⍣⎕⍉⍪⍳2]

オンラインでお試しください!

⍳2 ベクトルです 0 1

2x1行列に変換します

転置するため、1x2になります

評価された入力

{ }⍣⎕ 関数を何度も適用する

⍪⍨⍵ 引数をそれ自体の上に連結します-2x2行列

a← 覚えている a

~ 否定する

転置

水平に反転

垂直に反転

a,a左側で連結

'|-'[ ]行列を文字列のインデックスとして使用します'|-'。つまり、0を|1に変換します-


10

JavaScript(Node.js)130 ... 106 94 92バイト

私の代替方法でゴルフをし、文字を修正しました、-14バイトありがとう@Shaggy

f=n=>n?f(n-1).replace(/.+/g,x=>(g=i=>x.replace(/./g,p=>p<i?s[i]+s[i]:s))`0`+`
`+g`1`):s="|-"

オンラインでお試しください!

私の元のアプローチ(106 102バイト)

f=n=>n?[0,1].map(j=>f(n-1).split`
`.map(x=>x+x.substr((i=x.length/2)*j,i).repeat(2)).join`
`).join`
`:"|-"

-4バイトありがとう@Shaggy

f=n=>n?[0,1].map(j=>f(n-1).split`
`.map(x=>x+(y=x.substr((i=x.length/2)*j,i))+y).join`
`).join`
`:"|-"

オンラインでお試しください!

説明とゴルフなし:

function f(n) {                     // Main Function
 if (n != 0) {                      //  If n != 0: (i.e. not the base case)
  return [0, 1].map(                //   Separate the pattern into 2 parts
  function(j) {                     //   For each part:
   return f(n - 1).split("\n")      //    Split the next depth into lines
    .map(function(x) {              //    For each line in the result:
    return x                        //     The common part: "AB"
     + x.substr(
      (i = x.length / 2) * j        //     Take A if j == 0, B if j == 1
      , i                           //     Take half the original length
     ).repeat(2);                   //     Double this part
   }).join("\n");                   //    Join all lines together
  }).join("\n");                    //   Join the two parts together
 }
 else return "|-";                  //  If not (base case): return "|-";
}

私の元の代替方法"|"->"2", "-"->"1"が許可されている場合、105 104バイト:

f=n=>n?f(n-1).replace(/[12]+/g,x=>(g=(y,i)=>y.replace(/1|2/g,p=>[,i?11:22,21][p]))(x,0)+`
`+g(x,1)):"21"

オンラインでお試しください!

この問題に対する代数的方法を考え出しただけです。

x=>y=>"|-||--"[(f=(x,y,t=0,m=2**30,i=!(y&m)*2+!(x&m)<<1)=>m?f(x^m,y^m,([18,0,90][t]&3<<i)>>i,m>>1):t)(x>>1,y)*2+x%2]

オンラインでお試しください!

(最終的には元の答えに匹敵する長さの関数)

f(n, x, y)n次の置換のth回目の反復で(x、y)ブロックのブロックタイプを計算します。

0 => 0 1      1 => 0 0      2 => 1 1
     0 2           0 0           2 2

ここで0 = "|-", 1 = "||", 2 = "--"、から始まりf(0, 0, 0) = 0ます。

次に、g(x)(y)元のパターンの(x、y)でシンボルを計算します。


最初のソリューションでは102バイト
シャギー

1秒で88バイト
シャギー




9

スタックス24 17 15 バイト

╛ä├¼àz[{╧↑;ε╖>╠

実行してデバッグする

同じプログラムのascii表現を次に示します。

'|'-{b\2*aa+c\}N\m

基本的な考え方は、0世代グリッドから始めて、グリッドを拡張するブロックを繰り返すことです。

'|'-                    Push "|" and "-"
     {         }N       Get input and repeat block that many times.
      b                 Copy two top stack values
       \2*              Zip two parts, and double the height
          aa            Roll the top of the stack down to 3rd position.
            +           Concatenate two grids vertically
             c\         Copy result and zip horizontally
                  \     Zip the two parts horizontally
                   m    Output each row

8

Canvas17 16 バイト

|∙-╶[∔αω+:∔;:+}+

ここで試してみてください!

1の入力のスタックを示す説明。

|∙-               push "|" and "-" - the initial halves  "|", "-"
   ╶[         }   repeat input times                     
     ∔              add the two parts vertically         "|¶-"
      αω            get the original arguments to that   "|¶-", "|", "-"
        +           and add those horizontally           "|¶-", "|-"
         :∔         and add to itself vertically         "|¶-", "|-¶|-"
           ;        get the vertically added parts       "|-¶|-", "|¶-"
            :+      and add to itself horizontally       "|-¶|-", "||¶--"
               +  finally, add the halves together       "|-||¶|---"

α/ ωに設定された値が正しくコピーされなかったバグを修正することにより、16バイトに更新されました(Canvasは完全に不変であるはずですが、残念ながらそうではありませんでした)。




4

、17バイト

!¡§z+DȯṁmDTm½;"|-

1インデックス付き。 オンラインでお試しください!

説明

!¡§z+DȯṁmDTm½;"|-  Implicit input: a number n.
              "|-  The string "|-".
             ;     Wrap in a list: ["|-"]
 ¡                 Iterate this function on it:
                    Argument is a list of lines, e.g. L = ["|-||","|---"]
           m½       Break each line into two: [["|-","||"],["|-","--"]]
          T         Transpose: [["|-","|-"],["||","--"]]
      ȯṁ            Map and concatenate:
        mD           Map self-concatenation.
                    Result: ["|-|-","|-|-","||||","----"]
   z+               Zip using concatenation
  §  D              with L concatenated to itself: ["|-|||-|-","|---|-|-","|-||||||","|-------"]
                   Result is the infinite list [["|-"],["|-||","|---"],["|-|||-|-","|---|-|-","|-||||||","|-------"],...
!                  Take n'th element, implicitly display separated by newlines.

3

ゼリー21 19バイト

;"/;`,Ẏ;`€$
⁾|-Ç¡ZY

オンラインでお試しください!


説明:

最初は、値は⁾|-、つまり["|","-"]

指定された最後のリンク(Ç[A, B]が返されます

   AB     AA
[  AB  ,  BB  ]

¡繰り返し回数の最後のリンク(入力)数を適用し、ZYの形式に。

最後のリンクの説明:

-----------------
;"/;`,Ẏ;`€$  Monadic link. Value = [A, B]
;"/          Accumulate vectorized concatenate. Calculates (A ;" B).
             Represented as a matrix, it's |AB| (concatenated horizontally)
   ;`        Concatenate with self.      |AB|
                                Value =  |AB|  (concatenate vertically)
     ,    $  Pair with ...
      Ẏ        Tighten.  |A|    (concatenate vertically)
                 Value = |B|
       ;`€     Concatenate each with self.    |AA|
                                      Value = |BB|  (duplicate horizontally)


2

Haskell、86バイト

(%)=zipWith(++)
f 0=["|-"]
f n|(a,b)<-unzip$splitAt(2^(n-1))<$>f(n-1)=a%b%a%a++a%b%b%b

オンラインでお試しください!

ものすごく単純。出力は文字列のリストです。以前のバージョンを使用して、各行を半分に分割し、を使用してそれらを2つの新しいリストに収集しますunzip。それは単に配列を正しい方法で組み合わせるだけの問題です



1

47 46バイト

M²↖|-¶¶FENX²ι«F²C±ι⁰C⁰ιC⊗ι±ιC׳ι±ι≦⊗ιM±ι±ιT⊗ιι

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

M²↖|-¶¶

次のループで一貫したカーソル位置を取得するために、位置(-2、-2)でステップ0を印刷し、カーソルを(-2、0)のままにしておく必要があります。(これは、炭のバグが原因である可能性があります。)

FENX²ι«

N2 の最初の累乗でループします。

F²C±ι⁰C⁰ιC⊗ι±ιC׳ι±ι

さまざまなオフセットを使用して前の出力のコピーを作成し、その中の長方形に目的の次のステップを含むキャンバスを作成します。

≦⊗ιM±ι±ιT⊗ιι

その長方形の位置に移動して、キャンバスをトリミングします。

代替ソリューション、同じく46バイト:

M²→|-FENX²ι«F432C×Iκι׳ιF245C×Iκι⊗ι≦⊗ιJ⊗ιιT⊗ιι

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

M²→|-

今回はステップ0を位置(2、0)に印刷する必要がありますが、少なくともカーソル位置は重要ではありません。

FENX²ι«

N2 の最初の累乗でループします。

F432C×Iκι׳ιF245C×Iκι⊗ι

さまざまなオフセットを使用して前の出力のコピーを作成し、その中の長方形に目的の次のステップを含むキャンバスを作成します。

≦⊗ιJ⊗ιιT⊗ιι

その長方形の位置に移動して、キャンバスをトリミングします。




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