ABAA / ABBB: générer ce motif 2D récursif

30

Je jouais avec des réseaux de résistances infinies (longue histoire) quand je suis tombé sur le motif récursif intéressant suivant:

|-||
|---

Chaque instance de ce modèle est deux fois plus large que haute. Pour passer d'un niveau du motif au suivant, vous divisez ce rectangle en deux sous-blocs (chacun étant un carré NxN):

AB =
|-||
|---

so A = 
|-
|-

and B = 
||
--

Ces moitiés sont ensuite dupliquées et réorganisées selon le modèle suivant:

ABAA
ABBB

giving

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

Défi

Écrivez un programme / fonction qui, étant donné un nombre N, produit la Nième itération de cette conception récursive. C'est le golf.

Le format d'E / S est relativement indulgent: vous pouvez renvoyer une seule chaîne, une liste de chaînes, un tableau 2D de caractères, etc. Un espace de fin arbitraire est autorisé. Vous pouvez également utiliser l'indexation 0 ou 1.

Exemples

Les premières itérations du modèle sont les suivantes:

N = 0
|-

N = 1
|-||
|---

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

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

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

Je me demande s'il existe une méthode algébrique courte pour calculer cette structure.

PhiNotPi
la source
Qu'entendez-vous par «algébrique»?
user202729
4
@ user202729 Comme peut-être il y a une formule mathématique "simple" f(n,x,y)qui peut calculer directement si une coordonnée donnée doit contenir -ou |. Il peut s'agir d'opérations modulo ou d'opérations au niveau du bit. Les techniques que j'ai vues jusqu'à présent impliquent toutes de couper / joindre des tableaux comme indiqué dans la spécification.
PhiNotPi
3
f(x,y)fonctionne également, car si x,yest valide, le résultat ne dépend pas den
amara
2
La sortie peut-elle être indexée 1, c'est-à-dire que l'entrée 1 donne |-?
Zgarb
2
Est-ce une perte? 🤔
qwr

Réponses:

13

APL (Dyalog Classic) , 29 25 octets

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

Essayez-le en ligne!

⍳2 est le vecteur 0 1

le transforme en matrice 2x1

le transpose, il devient donc 1x2

entrée évaluée

{ }⍣⎕ appliquer une fonction plusieurs fois

⍪⍨⍵ concaténer l'argument au-dessus de lui-même - une matrice 2x2

a← rappelez-vous a

~ nier

transposer

inverser horizontalement

inverser verticalement

a,concaténer avec aà gauche

'|-'[ ]utiliser la matrice comme indices dans la chaîne '|-', c'est-à-dire transformer 0 en |et 1 en-

ngn
la source
10

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

Golfé à partir de ma méthode alternative et fixant les caractères, -14 octets Merci @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="|-"

Essayez-le en ligne!

Mon approche originale ( 106 102 octets)

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

Essayez-le en ligne!

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

Ma méthode alternative d'origine, si elle "|"->"2", "-"->"1"est autorisée, 105 104 octets:

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"

Essayez-le en ligne!

Je viens de découvrir une méthode algébrique pour résoudre ce problème.

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]

Essayez-le en ligne!

(enfin une fonction dont la longueur est comparable à ma réponse d'origine)

f(n, x, y)calcule le type de bloc au bloc (x, y) à l' nitération de la substitution suivante:

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

d'où 0 = "|-", 1 = "||", 2 = "--", à partir de f(0, 0, 0) = 0.

Ensuite, g(x)(y)calcule le symbole en (x, y) du motif d'origine.

Shieru Asakoto
la source
102 octets pour votre première solution.
Shaggy
88 octets pour votre deuxième.
Shaggy
1
Vous avez votre deuxième solution fonctionnant avec les bons caractères pour 95 octets
Shaggy
^ 94 octets
Shaggy
92 octets
Shaggy
9

Stax , 24 17 15 octets

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

Exécuter et déboguer

Voici la représentation ascii du même programme.

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

L'idée de base est de commencer par la grille de génération 0, puis de répéter un bloc qui étend la grille.

'|'-                    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
récursif
la source
8

Toile , 17 16 octets

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

Essayez-le ici!

Explication, montrant la pile pour l'entrée de 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       "|-||¶|---"

Mis à jour à 16 octets en corrigeant un bogue où les valeurs définies pour α/ ωpour travailler n'étaient pas copiées correctement (Canvas est censé être entièrement immuable, mais, hélas, ce n'était pas le cas).

dzaima
la source
6

Python 2 , 88 77 octets

-11 octets merci à 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)]

Essayez-le en ligne!

Barre
la source
Vous pouvez rouler ces listes de compréhension ensemble pour 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 octets

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

Essayez-le en ligne!

Xcali
la source
1
Optimisé pour 66: $.=map{s/.{$.}$/$&$$ /,push@1,$. $ & X3} @ 1pour (@ 1 = "| -") x <>; dire pour @ 1`
Ton Hospel
4

Husk , 17 octets

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

1 indexé. Essayez-le en ligne!

Explication

!¡§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
la source
3

Gelée , 21 19 octets

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

Essayez-le en ligne!


Explication:

Initialement, la valeur est ⁾|-, c'est-à-dire ["|","-"].

Le dernier lien ( Ç), donné [A, B], renverra

   AB     AA
[  AB  ,  BB  ]

. Ils ¡appliquent le dernier lien (entrée) à plusieurs reprises et le ZYformate.

Explication du dernier lien:

-----------------
;"/;`,Ẏ;`€$  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)
user202729
la source
2

Haskell , 86 octets

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

Essayez-le en ligne!

Assez simple. La sortie est une liste de chaînes. Nous prenons la version précédente et divisons chaque ligne en deux, puis les collectons en deux nouvelles listes à l'aide unzip. Ensuite, il s'agit simplement de combiner les tableaux de la bonne façon

user1472751
la source
1

J , 49 octets

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

Une traduction maladroite de la solution APL de ngn. J'ai eu du mal à le faire tacite - je vous remercie de tout conseil.

Essayez-le en ligne!

Galen Ivanov
la source
1

Fusain , 47 46 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

M²↖|-¶¶

Afin d'obtenir une position de curseur cohérente pour la boucle suivante, je dois imprimer l'étape 0 à la position (-2, -2) et laisser le curseur à (-2, 0). (Cela peut être dû à un bug dans Charcoal.)

FENX²ι«

Boucle sur les premiers Npouvoirs de 2.

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

Faites des copies de la sortie précédente avec divers décalages, ce qui donne un canevas contenant l'étape suivante souhaitée dans un rectangle.

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

Déplacez-vous à la position de ce rectangle et découpez la toile.

Solution alternative, également 46 octets:

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

M²→|-

Ce pas de temps 0 doit être imprimé à la position (2, 0), mais au moins la position du curseur n'a pas d'importance.

FENX²ι«

Boucle sur les premiers Npouvoirs de 2.

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

Faites des copies de la sortie précédente avec divers décalages, ce qui donne un canevas contenant l'étape suivante souhaitée dans un rectangle.

≦⊗ιJ⊗ιιT⊗ιι

Déplacez-vous à la position de ce rectangle et découpez la toile.

Neil
la source
1

R , 126 octets

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}

Essayez-le en ligne!

Renvoie a matrix. Il y a un peu de code dans le lien TIO pour qu'il s'imprime bien pour faciliter la vérification.

Giuseppe
la source
110
Robin Ryder