ABAA / ABBB: Hasilkan pola 2D rekursif ini

30

Saya bermain-main dengan jaringan resistor tanpa batas (cerita panjang) ketika saya menemukan pola rekursif yang menarik berikut:

|-||
|---

Setiap instance dari pola ini dua kali lebih lebar dari tingginya. Untuk beralih dari satu level pola ke level berikutnya, Anda memecah persegi panjang ini menjadi dua sub-blok (masing-masing merupakan kotak NxN):

AB =
|-||
|---

so A = 
|-
|-

and B = 
||
--

Bagian ini kemudian digandakan dan disusun kembali sesuai dengan pola berikut:

ABAA
ABBB

giving

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

Tantangan

Tulis program / fungsi yang, diberi nomor N, menampilkan Niterasi desain rekursif ini. Ini golf.

Format I / O relatif ringan: Anda dapat mengembalikan string tunggal, daftar string, array karakter 2D, dll. Ruang spasi trailing sewenang-wenang diizinkan. Anda juga dapat menggunakan pengindeksan 0 atau 1.

Contohnya

Beberapa iterasi pertama dari pola adalah sebagai berikut:

N = 0
|-

N = 1
|-||
|---

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

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

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

Saya ingin tahu apakah ada beberapa cara aljabar singkat untuk menghitung struktur ini.

PhiNotPi
sumber
Apa yang Anda maksud dengan "aljabar"?
user202729
4
@ user202729 Seperti mungkin ada beberapa rumus matematika "sederhana" f(n,x,y)yang dapat secara langsung menghitung apakah koordinat yang diberikan harus berisi -atau |. Ini mungkin melibatkan operasi modulo atau operasi bitwise. Teknik yang saya lihat sejauh ini semuanya melibatkan cutting / join array seperti yang ditunjukkan dalam spesifikasi.
PhiNotPi
3
f(x,y)juga berfungsi, karena jika x,yvalid maka hasilnya tidak bergantung padan
amara
2
Bisakah output diindeks 1, yaitu input 1 memberi |-?
Zgarb
2
Apakah ini kerugian? 🤔
qwr

Jawaban:

13

APL (Dyalog Classic) , 29 25 byte

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

Cobalah online!

⍳2 adalah vektor 0 1

mengubahnya menjadi matriks 2x1

mentransposnya, sehingga menjadi 1x2

input yang dievaluasi

{ }⍣⎕ menerapkan fungsi yang berkali-kali

⍪⍨⍵ menggabungkan argumen di atas dirinya sendiri - matriks 2x2

a← ingat sebagai a

~ meniadakan

mengubah urutan

mundur secara horizontal

membalikkan secara vertikal

a,bergabung dengan adi sebelah kiri

'|-'[ ]gunakan matriks sebagai indeks dalam string '|-', yaitu mengubah 0 menjadi |dan 1 menjadi-

ngn
sumber
10

JavaScript (Node.js) , 130 ... 106 94 92 byte

Golf dari metode alternatif saya dan memperbaiki karakter, -14 byte Terima kasih @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="|-"

Cobalah online!

Pendekatan asli saya ( 106 102 bytes)

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 byte Terima kasih @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`
`:"|-"

Cobalah online!

Penjelasan & Tidak Digabungkan:

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

Metode alternatif asli saya, jika "|"->"2", "-"->"1"diizinkan, 105 104 byte:

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"

Cobalah online!

Baru saja menemukan beberapa metode aljabar untuk masalah ini.

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]

Cobalah online!

(akhirnya fungsi yang panjangnya sebanding dengan jawaban asli saya)

f(n, x, y)menghitung tipe blok pada (x, y) blok pada niterasi substitusi berikut:

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

dimana 0 = "|-", 1 = "||", 2 = "--", mulai dari f(0, 0, 0) = 0.

Kemudian, g(x)(y)hitung simbol pada (x, y) dari pola aslinya.

Shieru Asakoto
sumber
102 byte untuk solusi pertama Anda.
Shaggy
88 byte untuk yang kedua.
Shaggy
1
Dapatkan solusi kedua Anda bekerja dengan karakter yang benar untuk 95 byte
Shaggy
^ 94 byte
Shaggy
92 byte
Shaggy
9

Stax , 24 17 15 byte

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

Jalankan dan debug itu

Inilah representasi ascii dari program yang sama.

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

Ide dasarnya adalah mulai dengan kisi 0-generasi, dan kemudian ulangi blok yang memperluas kisi.

'|'-                    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
rekursif
sumber
8

Kanvas , 17 16 byte

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

Coba di sini!

Penjelasan, menunjukkan tumpukan untuk input 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       "|-||¶|---"

Diperbarui hingga 16 byte dengan memperbaiki bug di mana nilai yang ditetapkan untuk α/ ωuntuk bekerja tidak disalin dengan benar (Canvas seharusnya sepenuhnya tidak dapat diubah, tetapi, sayangnya, tidak).

dzaima
sumber
6

Python 2 , 88 77 byte

-11 byte thansk ke 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)]

Cobalah online!

tongkat
sumber
Anda dapat menggulung daftar-daftar pemahaman bersama untuk 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

Perl 5 , 72 byte

@1='|-';$l=@1,map{/.{$l}/;push@1,$_.$' x2;$_.=$&x2}@1for 1..<>;say for@1

Cobalah online!

Xcali
sumber
1
Dioptimalkan untuk 66: $.=map{s/.{$.}$/$&$$ /,push@1,$. $ & X3} @ 1untuk (@ 1 = "| -") x <>; ucapkan untuk @ 1`
Ton Hospel
4

Sekam , 17 byte

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

1-diindeks. Cobalah online!

Penjelasan

!¡§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.
Zgarb
sumber
3

Jelly , 21 19 byte

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

Cobalah online!


Penjelasan:

Awalnya, nilainya ⁾|-, yaitu ["|","-"].

Tautan terakhir ( Ç), diberikan [A, B], akan kembali

   AB     AA
[  AB  ,  BB  ]

. The ¡berulang kali menerapkan link terakhir (input) beberapa kali, dan ZYformat itu.

Penjelasan untuk tautan terakhir:

-----------------
;"/;`,Ẏ;`€$  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)
pengguna202729
sumber
2

Bersih , 121 106 byte

import StdEnv
$0=[['|-']]
$n#z=map(splitAt(2^n/2))($(n-1))
=[u++v++u++u\\(u,v)<-z]++[u++v++v++v\\(u,v)<-z]

Cobalah online!

Suram
sumber
2

Haskell , 86 byte

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

Cobalah online!

Cukup mudah. Output adalah daftar string. Kami mengambil versi sebelumnya dan membagi setiap baris menjadi dua lalu mengumpulkannya menjadi dua daftar baru menggunakan unzip. Maka itu hanya masalah menggabungkan array bersama dengan cara yang benar

pengguna1472751
sumber
1

J , 49 byte

f=.3 :'''|-''{~((,.[:|.[:|."1[:|:-.)@,~)^:y,:0 1'

Terjemahan canggung dari solusi APL ngn. Saya punya masalah membuatnya diam-diam - saya akan menghargai saran apa pun.

Cobalah online!

Galen Ivanov
sumber
1

Arang , 47 46 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

M²↖|-¶¶

Untuk mendapatkan posisi kursor yang konsisten untuk loop berikut, saya harus mencetak langkah 0 pada posisi (-2, -2) dan membiarkan kursor berada pada (-2, 0). (Ini mungkin karena bug di Arang.)

FENX²ι«

Ulangi Nkekuatan pertama 2.

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

Buat salinan dari output sebelumnya dengan berbagai offset yang menghasilkan kanvas yang berisi langkah berikutnya yang diinginkan dalam kotak di dalamnya.

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

Pindah ke posisi persegi panjang itu dan rapikan kanvas.

Solusi alternatif, juga 46 byte:

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

M²→|-

Langkah waktu 0 ini harus dicetak pada posisi (2, 0), tetapi setidaknya posisi kursor tidak masalah.

FENX²ι«

Ulangi Nkekuatan pertama 2.

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

Buat salinan dari output sebelumnya dengan berbagai offset yang menghasilkan kanvas yang berisi langkah berikutnya yang diinginkan dalam kotak di dalamnya.

≦⊗ιJ⊗ιιT⊗ιι

Pindah ke posisi persegi panjang itu dan rapikan kanvas.

Neil
sumber
1

R , 126 byte

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}

Cobalah online!

Pengembalian a matrix. Ada sedikit kode di tautan TIO untuk membuatnya mencetak dengan baik untuk kemudahan verifikasi.

Giuseppe
sumber
110
Robin Ryder