Dessinez la courbe de Hilbert à l'aide de barres obliques

30

La courbe de Hilbert est une fractale remplissant l'espace qui peut être représentée comme un système Lindenmayer avec des générations successives qui ressemblent à ceci:
Courbe de Hilbert
Merci à http://www.texample.net/tikz/examples/hilbert-curve/ pour l'image.

Objectif

Écrivez le programme le plus court possible (en octets) qui prend un entier positif n de stdin et dessine la courbe de Hilbert de nième ordre vers stdout en utilisant uniquement la barre oblique, la barre oblique inverse, l'espace et la nouvelle ligne.

Par exemple, si l'entrée est 1la sortie doit être

 \
\/

Si l'entrée est 2la sortie doit être

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

Si l'entrée est 3la sortie doit être

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

Etc. (Ils sont plus beaux si vous les collez dans quelque chose avec moins d'espacement de ligne.)

La sortie ne doit pas contenir de nouvelles lignes au-dessus ou au-dessous des extrémités de la courbe, ni aucun espace de fin sur aucune ligne.

Loisirs de Calvin
la source

Réponses:

10

Ruby, 247 230 205 caractères

r=?D
y=d=0
z=(1..2*x=2**gets.to_i.times{r.gsub!(/\w/){$&<?H?'-H~+D~D+~H-':'+D~-H~H-~D+'}}-1).map{' '*2*x}
r.bytes{|c|c>99?(z[y-=s=-~d/2%2][x-=1-d/2]='/\\'[d%2]
x+=d/2
y+=1-s):d-=c
d%=4}
puts z.map &:rstrip

Une approche ASCII-tortue utilisant la représentation Lindenmayer (essayez ici ).

Un grand merci à @Ventero pour un peu plus de golf.

Howard
la source
J'y ai joué un peu plus, j'espère que cela ne vous dérange pas: ideone.com/kvcPWT - le .map(&:rstrip)devait être ajouté pour répondre à l'exigence "sans espaces de fuite".
Ventero
@Ventero Merci. J'espère que cela ne vous dérange pas que j'ai pris votre solution - vous pouvez même supprimer les paranthèses autour de l'argument de la carte.
Howard
Ah, bien sûr! Je viens également de réaliser qu'il est possible d'inclure la définition de xet de raccourcir l'affectation à yet d, pour un total de 205 caractères (voir le même lien que précédemment).
Ventero
12

Python, 282

from numpy import*
def r(n):
 x=2**n-2;b=3*x/2+1;c=x/2+1;a=zeros((x*2+2,)*2,int);a[x+1,x+1]=1;a[b,x/2]=a[x/2,b]=-1
 if n>1:s=r(n-1);a[:x,c:b]=rot90(s,3)*-1;a[c:b,:x]|=rot90(s)*-1;a[c:b,x+2:]|=s;a[x+2:,c:b]|=s
 return a
for l in r(input()):print''.join(' /\\'[c] for c in l).rstrip()

Celui-ci utilise une approche récursive pour construire la courbe de Hilbert d'ordre n à partir de la courbe précédente. Les courbes sont représentées sous la forme d'un tableau numpy 2D pour un meilleur découpage et une meilleure manipulation.

Voici quelques exemples:

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/
grc
la source
5

Malsys - 234 221 caractères

Je sens quelques L-systèmes ici :) Malsys est un interpréteur de L-système en ligne. Ce n'est pas une entrée vraiment sérieuse, mais j'ai senti que cette solution était quelque peu intéressante.

La syntaxe de Malsys n'est pas vraiment bonne pour le golf car elle contient beaucoup de mots-clés longs mais néanmoins, elle est assez courte, lisible et expressive.

lsystem HilbertCurveAscii {
    set symbols axiom = R;
    set iterations = 5;
    set rightAngleSlashMode = true;
    interpret F as DrawLine;
    interpret + as TurnLeft;
    interpret - as TurnRight;
    rewrite L to + R F - L F L - F R +;
    rewrite R to - L F + R F R + F L -;
}
process all with HexAsciiRenderer;

http://malsys.cz/g/3DcVFMWn

Interprète: http://malsys.cz/Process

Version golfée:

lsystem H{set symbols axiom=R;set iterations=3;set
rightAngleSlashMode=1;interpret.as DrawLine;interpret+as
TurnLeft;interpret-as TurnRight;rewrite L to+R.-L.L-.R+;rewrite
R to-L.+R.R+.L-;}process H with HexAsciiRenderer;

Et que diriez-vous de la courbe de Gosper hexagonale Ascii? :)

      ____
 ____ \__ \
 \__ \__/ / __
 __/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
 \/ ____ \/ /
    \__ \__/
    __/

http://malsys.cz/g/ae5v5vGB

NightElfik
la source
2

JavaScript (ES6) 313 340

Modifier un caractère supprimé en utilisant vraiment mauvais pratiques - comme la variable globale w au lieu d'une valeur de retour de la fonction H

Convertir la position x, y en distance d (voir Wikipedia ) pour chaque x, y et vérifier si les positions les plus proches sont connectées,

Testez dans la console FireFox. Entrée via popup, sortie via console.log.

Il n'y a aucun espace de fin et aucun retour à la ligne au-dessus ou au-dessous de l'image. Mais chaque ligne se termine par une nouvelle ligne, je pense que c'est la bonne façon de créer une image d'art Ascii.

n=1<<prompt(),d=n-1
H=(s,x,y)=>{for(w=0;s>>=1;)p=x&s,q=y&s,w+=s*s*(3*!!p^!!q),q||(p&&(x=s-1-x,y=s-1-y),[x,y]=[y,x])}
for(r=t='';++r<d+n;t+='\n')for(r>d?(x=r-d,f=x-1):(f=d-r,x=0),t+=' '.repeat(f),z=r-x;x<=z;)
h=H(n,y=r-x,x)|w,H(n,y,x-1),x?t+=' \\'[h-w<2&w-h<2]:0,H(n,y-1,x++),y?t+=' /'[h-w<2&w-h<2]:0
console.log(t)
edc65
la source
Vous pouvez enregistrer certains caractères en utilisant alertau lieu de console.log. Vous disposez également d'un espace supplémentaire après le forsur la quatrième ligne, et vous devriez pouvoir vous débarrasser de ce dernier saut de ligne.
Bob
@Bob oui, en fait, je peux enregistrer 15 caractères de plus, j'ai renoncé à voir que je suis plus de 300 de toute façon. Je n'aime pas utiliser 'alerte' car l'image est complètement méconnaissable sans police à pas fixe
edc65
2

Perl, 270 caractères

Super golfé

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;eval's/A|B/$d{$&}/g;'x$n;s/A|B//g;map{if(/F/){if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}$s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]}else{($r+=2*/-/-1)%=4}}/./g;map{print map{$_||$"}@$_,$/}@s

Pas tellement joué au golf

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;
eval's/A|B/$d{$&}/g;'x$n;
s/A|B//g;
map{if(/F/){
    if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}
        $s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]
    }else{
        ($r+=2*/-/-1)%=4
    }
}/./g;
map{print map{$_||$"}@$_,$/}@s

Je pourrais probablement le jouer davantage si je comprenais mieux Perl. Utilise une approche système Lindenmayer utilisant des règles de production définies à la ligne 1.

killmous
la source
2

APL (Dyalog Unicode) , 90 octets SBCS

⎕∘←¨' +$'r''¨↓1↓∘⍉∘⌽⍣4' /\'[{3|(⊢+⍉)2@(¯1 0+3 1×s÷2)s⊢(¯.5×≢⍵)⊖(2×s←⍴⍵)↑⍵,⍨-⊖⍵}⍣⎕⊢2 2⍴0]

Essayez-le en ligne!

2 2⍴0 une matrice 2x2 de zéros

{ }⍣⎕ saisir N ​​et appliquer une fonction N fois

⍵,⍨-⊖⍵ concaténer à gauche de la matrice une copie de lui-même inversée et inversée verticalement

(2×s←⍴⍵)↑ tampon avec des zéros de sorte que les dimensions (rappelées comme s ) soient deux fois plus

¯.5×≢⍵ tourner vers le bas pour le centrer verticalement, pris en sandwich entre les zéros de remplissage

2@(¯1 0+3 1×s÷2) mettre 2 s à des emplacements spécifiques - ce sont les barres obliques de liaison entre les petites instances de la fractale

(⊢+⍉) ajouter la matrice avec son auto transposé

3|modulo 3; nous avons utilisé la négation, veuillez donc noter que -1≡2 (mod 3) et -2≡1 (mod 3)

' /\'[ ] utiliser les éléments de la matrice comme indices dans la chaîne ' /\'

1↓∘⍉∘⌽⍣4 couper la marge vide à 1 élément de tous les côtés

divisé en lignes

' +$'⎕r''¨ supprimer les espaces de fuite de chacun (ce défi l'exige)

⎕∘←¨ sortie chacun

ngn
la source