ABAA / ABBB: genera questo modello 2D ricorsivo


30

Stavo scherzando con infinite reti di resistori (lunga storia) quando mi sono imbattuto nel seguente schema ricorsivo interessante:

|-||
|---

Ogni istanza di questo modello è doppia rispetto a quella alta. Per passare da un livello del modello a quello successivo, suddividi questo rettangolo in due blocchi secondari (ognuno dei quali è un quadrato NxN):

AB =
|-||
|---

so A = 
|-
|-

and B = 
||
--

Queste metà vengono quindi duplicate e riorganizzate secondo il modello seguente:

ABAA
ABBB

giving

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

Sfida

Scrivi un programma / funzione che, dato un numero N, genera l' Niterazione di questo disegno ricorsivo. Questo è il golf.

Il formato I / O è relativamente clemente: è possibile restituire una singola stringa, un elenco di stringhe, una matrice 2D di caratteri, ecc. È consentito uno spazio bianco finale arbitrario. Puoi anche utilizzare l'indicizzazione 0 o 1.

Esempi

Le prime diverse iterazioni del modello sono le seguenti:

N = 0
|-

N = 1
|-||
|---

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

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

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

Mi chiedo se esiste un modo algebrico breve per calcolare questa struttura.


Cosa intendi con "algebrico"?
user202729

4
@ user202729 Come forse c'è una formula matematica "semplice" f(n,x,y)che può calcolare direttamente se una data coordinata deve contenere -o |. Potrebbe comportare operazioni modulo o operazioni bit a bit. Le tecniche che ho visto finora riguardano il taglio / l'unione di array come mostrato nelle specifiche.
PhiNotPi

3
f(x,y)funziona anche, poiché se x,yè valido, il risultato non dipende dan
amara,

2
L'output può essere 1 indicizzato, ovvero input 1 che dà |-?
Zgarb,

2
Questa perdita è? 🤔
qwr

Risposte:


13

APL (Dyalog Classic) , 29 25 byte

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

Provalo online!

⍳2 è il vettore 0 1

lo trasforma in una matrice 2x1

lo traspone, quindi diventa 1x2

input valutato

{ }⍣⎕ applicare una funzione che più volte

⍪⍨⍵ concatena l'argomento sopra se stesso: una matrice 2x2

a← ricorda come a

~ negare

trasporre

retromarcia in senso orizzontale

inverti verticalmente

a,concatenarsi con aa sinistra

'|-'[ ]usa la matrice come indice nella stringa '|-', ovvero trasforma 0 in |e 1 in-


10

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

Giocato a golf dal mio metodo alternativo e riparando i caratteri, -14 byte Grazie @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="|-"

Provalo online!

Il mio approccio originale ( 106 102 byte)

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 Grazie @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`
`:"|-"

Provalo online!

Spiegazione e Ungolfed:

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

Il mio metodo alternativo originale, se "|"->"2", "-"->"1"consentito, 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"

Provalo online!

Ho appena scoperto un metodo algebrico per risolvere questo problema.

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]

Provalo online!

(finalmente una funzione di lunghezza paragonabile alla mia risposta originale)

f(n, x, y)calcola il tipo di blocco nel blocco (x, y) nall'iterazione della seguente sostituzione:

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

dove 0 = "|-", 1 = "||", 2 = "--", a partire da f(0, 0, 0) = 0.

Quindi, g(x)(y)calcola il simbolo in (x, y) del modello originale.


102 byte per la tua prima soluzione.
Shaggy,

88 byte per il tuo secondo.
Shaggy,

1
La tua seconda soluzione funziona con i caratteri corretti per 95 byte
Shaggy,



9

Stax , 24 17 15 byte

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

Esegui ed esegui il debug

Ecco la rappresentazione ASCII dello stesso programma.

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

L'idea di base è iniziare con la griglia di generazione 0, quindi ripetere un blocco che espande la griglia.

'|'-                    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

Tela , 17 16 byte

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

Provalo qui!

Spiegazione, che mostra lo stack per l'ingresso di 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       "|-||¶|---"

Aggiornato a 16 byte correggendo un bug in cui i valori impostati per α/ ωper il funzionamento non venivano copiati correttamente (Canvas dovrebbe essere completamente immutabile, ma, ahimè, non lo era).


6

Python 2 , 88 77 byte

-11 byte grazie a 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)]

Provalo online!


Puoi raggruppare queste comprensioni dell'elenco insieme per 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

Provalo online!


1
Ottimizzato per 66: $.=map{s/.{$.}$/$&$$ /,push@1,$. $ & X3} @ 1for (@ 1 = "| -") x <>; dì per @ 1`
Ton Hospel

4

Buccia , 17 byte

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

1-indicizzati. Provalo online!

Spiegazione

!¡§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

Gelatina , 21 19 byte

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

Provalo online!


Spiegazione:

Inizialmente, il valore è ⁾|-, cioè["|","-"] .

L'ultimo link ( Ç), dato [A, B], tornerà

   AB     AA
[  AB  ,  BB  ]

. Il ¡più volte applicare l'ultimo numero di collegamento (ingresso) di volte, e ZYformatta.

Spiegazione per l'ultimo collegamento:

-----------------
;"/;`,Ẏ;`€$  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 byte

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

Provalo online!

Abbastanza semplice. L'output è un elenco di stringhe. Prendiamo la versione precedente e dividiamo ogni riga a metà, quindi raccogliamo quelli in due nuovi elenchi usando unzip. Quindi si tratta semplicemente di combinare gli array nel modo giusto


1

J , 49 byte

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

Una traduzione maldestra della soluzione APL di ngn. Ho avuto problemi a renderlo tacito - apprezzerò qualsiasi consiglio.

Provalo online!


1

Carbone , 47 46 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

M²↖|-¶¶

Per ottenere una posizione del cursore coerente per il ciclo seguente, devo stampare il passaggio 0 nella posizione (-2, -2) e lasciare il cursore su (-2, 0). (Ciò potrebbe essere dovuto a un bug in Carbone.)

FENX²ι«

Passa sopra i primi Npoteri di 2.

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

Crea copie dell'output precedente con vari offset risultanti in un'area di disegno che contiene il passaggio successivo desiderato in un rettangolo al suo interno.

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

Spostati nella posizione di quel rettangolo e ritaglia la tela.

Soluzione alternativa, anche 46 byte:

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

M²→|-

Questa volta il passaggio 0 deve essere stampato nella posizione (2, 0), ma almeno la posizione del cursore non ha importanza.

FENX²ι«

Passa sopra i primi Npoteri di 2.

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

Crea copie dell'output precedente con vari offset risultanti in un'area di disegno che contiene il passaggio successivo desiderato in un rettangolo al suo interno.

≦⊗ιJ⊗ιιT⊗ιι

Spostati nella posizione di quel rettangolo e ritaglia la tela.


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}

Provalo online!

Restituisce a matrix. C'è un po 'di codice nel link TIO per farlo stampare bene per una facile verifica.




Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.