ABAA / ABBB:生成此递归2D模式


30

当我遇到以下有趣的递归模式时,我正在搞无限电阻网络(长话不说):

|-||
|---

该图案的每个实例的宽度是其高度的两倍。要从图案的一个层次转到下一个层次,请将该矩形分成两个子块(每个子块为NxN正方形):

AB =
|-||
|---

so A = 
|-
|-

and B = 
||
--

然后根据以下模式复制和重新排列这些半部分:

ABAA
ABBB

giving

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

挑战

编写一个程序/函数,给定一个数字N,输出N该递归设计的第th次迭代。这是高尔夫。

I / O格式相对宽松:您可以返回单个字符串,字符串列表,二维字符数组等。允许使用任意尾随空格。您也可以使用0或1索引。

例子

模式的前几次迭代如下:

N = 0
|-

N = 1
|-||
|---

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

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

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

我想知道是否有一些简短的代数方法来计算这种结构。


“代数”是什么意思?
user202729 '18

4
@ user202729也许有一些“简单”的数学公式f(n,x,y)可以直接计算给定坐标应包含-还是|。它可能涉及模运算或按位运算。到目前为止,我所见过的技术都涉及剪切/连接数组,如规范所示。
PhiNotPi

3
f(x,y)也有效,因为如果x,y有效,则结果不依赖n
amara

2
输出可以是1索引的,即输入1是否给出|-
Zgarb

2
这是损失吗?🤔–
qwr

Answers:


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="|-"

在线尝试!

我的原始方法(106102字节)

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在以下替换的第x 次迭代中计算(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个字节
毛茸茸的

88字节为您的第二个。
毛茸茸的

1
得到了第二个解决方案,使用95个字节
-Shaggy



9

Stax24 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

画布17 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是完全不变的,但是事实并非如此)。


6

Python 2中88 77个字节

-11字节thansk至Lynn

f=lambda x:x<1and['|-']or[n+2*n[i:i+2**x/2]for i in(0,2**x/2)for n in f(x-1)]

在线尝试!


您可以将这些列表理解汇总为77:f=lambda x:x<1and['|-']or[n+2*n[i:i+2**x/2]for i in(0,2**x/2)for n in f(x-1)]
Lynn


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

在线尝试!

很简单 输出是字符串列表。我们采用以前的版本,将每一行分成两半,然后使用将它们收集到两个新列表中unzip。然后,只需将阵列正确组合即可



1

木炭47 46字节

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

在线尝试!链接是详细版本的代码。说明:

M²↖|-¶¶

为了在下一个循环中获得一致的光标位置,我必须在位置(-2,-2)打印步骤0,并将光标保留在(-2,0)。(这可能是由于木炭中的错误所致。)

FENX²ι«

循环N使用2 的第一个幂。

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

制作具有各种偏移量的上一个输出的副本,从而生成一个画布,其中的矩形中包含所需的下一步。

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

移动到该矩形的位置并修剪画布。

替代解决方案,也是46个字节:

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

在线尝试!链接是详细版本的代码。说明:

M²→|-

该时间步0必须打印在位置(2,0),但至少光标位置无关紧要。

FENX²ι«

循环N使用2 的第一个幂。

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

制作具有各种偏移量的上一个输出的副本,从而生成一个画布,其中的矩形中包含所需的下一步。

≦⊗ιJ⊗ιιT⊗ιι

移动到该矩形的位置并修剪画布。


1

R,126个字节

function(n,k=cbind){o=matrix(c("|","-"),1,2)
if(n>0)for(i in 1:n)o=rbind(k(a<-o[,x<-1:(2^(i-1))],b<-o[,-x],a,a),k(a,b,b,b))
o}

在线尝试!

返回matrix。TIO链接中有一些代码可以很好地打印以简化验证。




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.