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.


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-


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.


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



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

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).


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!


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

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.

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)


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


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!


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.


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.




En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.