Générer une séquence de cure-dents

10

Qu'est-ce que la séquence de cure-dents?

Selon Wikipedia

En géométrie, la séquence de cure-dents est une séquence de motifs bidimensionnels qui peuvent être formés en ajoutant à plusieurs reprises des segments de ligne ("cure-dents") au motif précédent de la séquence.

La première étape de la conception est un seul "cure-dent" ou segment de ligne. Chaque étape après la première est formée en prenant le modèle précédent et, pour chaque extrémité de cure-dent exposée, en plaçant un autre cure-dent centré à angle droit sur cette extrémité.

Ce processus se traduit par un schéma de croissance dans lequel le nombre de segments au stade n oscille avec un schéma fractal compris entre 0,45n2 et 0,67n2. Si T (n) désigne le nombre de segments à l'étape n, alors les valeurs de n pour lesquelles T (n) / n2 est proche de son maximum se produisent lorsque n est proche d'une puissance de deux, tandis que les valeurs pour lesquelles il est proche de son minimum se produisent près de nombres qui sont environ 1,43 fois une puissance de deux. La structure des étapes de la séquence du cure-dent ressemble souvent à la fractale du carré en T, ou à la disposition des cellules dans l'automate cellulaire Ulam – Warburton.

Toutes les régions délimitées entourées de cure-dents dans le motif, mais pas elles-mêmes traversées par des cure-dents, doivent être des carrés ou des rectangles. Il a été conjecturé que chaque rectangle ouvert dans le modèle de cure-dent (c'est-à-dire un rectangle qui est complètement entouré de cure-dents, mais sans cure-dent traversant son intérieur) a des longueurs latérales et des zones qui sont des puissances de deux, avec l'une des longueurs latérales étant au plus deux.

Tâche

Vous devez créer un programme ou une fonction qui prend en entrée STDIN, l'argument de fonction ou l'argument de ligne de commande et créer une fractale tootpick à ce stade. Les sauts de ligne de début et de fin sont interdits sauf si cela est inévitable. La zone de délimitation doit être au minimum, y compris l'espace de début et de fin. Pour la ligne initiale, nous faisons deux \diagonales dans l'espace. L'entrée est garantie à moins de deux mille. Au moins une ligne a un caractère non-espace. L'espace de fuite est autorisé.

Cas de test

1
\ 
 \     

5
    \     
    /\    
   /\     
  / /\   
\/\/\ \ \ 
 \ \ \/\/\
    \/ /  
     \/   
    \/    
     \    
Akangka
la source

Réponses:

6

CJam, 99 93 octets

Cela est devenu assez long ...

"\ "_W%]{{Sf+W%z}4*2ew{2fewz{_sa"\//\\"4S**4/^_,3={:.e>W%2/\}&;}%z{\)[email protected]>+}:Ff*}%{F}*}q~(*N*

Testez-le ici. Si vous voulez tester des entrées plus grandes, comme le 89 sur Wikipédia, TryItOnline de Dennis utilise l'interpréteur Java beaucoup plus rapide sous le capot et peut gérer des entrées comme ça en quelques secondes.

Je suis sûr qu'il y a beaucoup de place à l'amélioration, et j'ajouterai une explication une fois que je serai plus satisfait du score ...

Voici la sortie pour N = 13:

            \             
            /\            
           /\             
          / /\            
        \/\/\ \ \         
         \ \/\/\/\        
           /\/\/          
          / /\ \          
    \    /\/\ \     \     
    /\  /  \/\/\    /\    
   /\  /\  /\/  \ \/\     
  / /\/ /\/ /\  /\ \/\    
\/\/\/\/\/\/\ \/\ \/\ \ \ 
 \ \ \/\ \/\ \/\/\/\/\/\/\
    \/\ \/  \/ /\/ /\/ /  
     \/\ \  /\/  \/  \/   
    \/    \/\/\  /  \/    
     \     \ \/\/    \    
          \ \/ /          
          /\/\/           
        \/\/\/\ \         
         \ \ \/\/\        
            \/ /          
             \/           
            \/            
             \            

Pour ma propre référence en jouant plus loin, quelques autres idées:

"\ "_W%]{{Sf+W%z}4*2few2ew::.{+_a"\//\\"4S**4/^_,3={:.e>W%\}&;2/}:z{\)[email protected]>+}ff*{\)[email protected]>+}*}ri(*N*
"\ "_W%]{{Sf+W%z}4*2ew{2fewz{_sa"\//\\"4S**4/^_,3={:.e>W%2/\}&;}%{.{\)[email protected]>+}}*}%{\)[email protected]>+}*}q~(*N*
Martin Ender
la source
1

JavaScript (ES6), 263 octets

n=>(o=(o=[..." ".repeat(n*2)]).map(_=>o.map(_=>s=c=" ")),(g=a=>s++<n&&g(q=[],a.map(p=>o[p[4]][p[3]]==c&&(o[y=p[1]][x=p[0]]=o[y-1][(b=+p[2])?x-1:x+1]="/\\"[b],q.push([x,++y,!b,b?x+1:x-1,y],[b?x-=2:x+=2,y-2,!b,x,y-3])))))([[n,n,1,n,n]]),o.map(r=>r.join``).join`
`)

Explication

n=>(                           // n = desired stage

  o=                           // o = output grid
                               //     [ [ "\\", " " ], [ " ", "\\" ], etc... ]
    (o=[..." ".repeat(n*2)])   // create an array the size of the grid
    .map(_=>o.map(_=>          // loop over it and return the output grid
      s=                       // s = current stage (" " acts the same as 0)
        c=                     // c = blank character
          " "                  // initialise each element to " "
    )),

  (g=                          // g = compute stage function
    a=>                        // a = positions to place toothpicks
                               //     [ x, y, isBackslash, checkX, checkY ]
      s++<n&&                  // do nothing if we have reached the desired stage
      g(q=[],                  // q = positions for the next stage's toothpicks
        a.map(p=>              // p = current potential toothpick position
          o[p[4]][p[3]]==c&&(  // check the position to make sure it is clear

            o[y=p[1]][x=p[0]]= // place bottom toothpick, x/y = position x/y
            o[y-1][            // place top toothpick
              (b=+p[2])        // b = isBackslash
              ?x-1:x+1         // top toothpick x depends on direction
            ]="/\\"[b],        // set the location to the appropriate character

            // Add the next toothpick positions
            q.push([x,++y,!b,b?x+1:x-1,y],
              [b?x-=2:x+=2,y-2,!b,x,y-3])
          )
        )
      )
  )([[n,n,1,n,n]]),            // place the initial toothpicks
  o.map(r=>r.join``).join`
` // return the grid converted to a string
)

Tester

Stages: <input type="number" oninput='result.innerHTML=(

n=>(o=(o=[..." ".repeat(n*2)]).map(_=>o.map(_=>s=c=" ")),(g=a=>s++<n&&g(q=[],a.map(p=>o[p[4]][p[3]]==c&&(o[y=p[1]][x=p[0]]=o[y-1][(b=+p[2])?x-1:x+1]="/\\"[b],q.push([x,++y,!b,b?x+1:x-1,y],[b?x-=2:x+=2,y-2,!b,x,y-3])))))([[n,n,1,n,n]]),o.map(r=>r.join``).join`
`)

)(+this.value)' /><pre id="result"></pre>

user81655
la source
1

Rubis, 151 octets

La version golfée utilise une seule boucle j, avec iet kcalculée à la volée.

->n{m=n*2
s=(' '*m+$/)*m
l=m*m+m
s[l/2+n]=s[l/2-n-2]=?\\
(n*l-l).times{|j|(s[i=j%l]+s[i-m-2+2*k=j/l%2]).sum==124-k*45&&s[i-m-1]=s[i-1+2*k]="/\\"[k]}
s}

Non testé dans le programme de test

Cette version utilise 2 boucles imbriquées.

Une fonction intégrée rarement utilisée est celle sumqui renvoie une somme de contrôle brute en ajoutant tous les octets d'une chaîne ascii.

f=->n{
  m=n*2                                       #calculate grid height / width            
  s=(' '*m+$/)*m                              #fill grid with spaces, separated by newlines
  l=m*m+m                                     #calculate length of string s
  s[l/2+n]=s[l/2-n-2]=?\\                     #draw the first toothpick
  (n-1).times{|j|                             #iterate n-1 times
    l.times{|i|                               #for each character in the string
      (s[i]+s[i-m-2+2*k=j%2]).sum==124-k*45&& #if checksum of current character + character diagonally above indicates the end of a toothpick
         s[i-m-1]=s[i-1+2*k]="/\\"[k]         #draw another toothpick at the end
    }                                         
  }
s}                                            #return value = s


puts f[gets.to_i]
Level River St
la source