Dibuja la curva de Hilbert con barras

30

La curva de Hilbert es un fractal que llena espacios y se puede representar como un sistema Lindenmayer con generaciones sucesivas que se ven así:
Curva de Hilbert
Gracias a http://www.texample.net/tikz/examples/hilbert-curve/ por la imagen.

Gol

Escriba el programa más corto posible (en bytes) que tome un entero positivo n de stdin y dibuje la curva de Hilbert de enésimo orden en stdout usando solo barra diagonal, barra diagonal inversa, espacio y nueva línea.

Por ejemplo, si la entrada es 1la salida debe ser

 \
\/

Si la entrada es 2la salida debe ser

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

Si la entrada es 3la salida debe ser

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

Y así. (Se ven mejor si los pega en algo con menos espacio entre líneas).

La salida no debe contener nuevas líneas por encima o por debajo de las extremidades de la curva, ni espacios finales en ninguna línea.

Pasatiempos de Calvin
fuente

Respuestas:

10

Rubí, 247 230 205 caracteres

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

Un enfoque de tortuga ASCII utilizando la representación de Lindenmayer (intente aquí ).

Muchas gracias a @Ventero por un poco más de golf.

Howard
fuente
Golfed esto un poco más, espero que no te importe : ideone.com/kvcPWT : se .map(&:rstrip)tuvo que agregar para cumplir con el requisito de "no espacios finales".
Ventero
@Ventero Gracias. Espero que no te importe que haya tomado tu solución, incluso puedes descartar las paréntesis alrededor del argumento del mapa.
Howard
Ah, por supuesto! También me di cuenta de que es posible alinear la definición xy acortar la asignación a yy d, para un total de 205 caracteres (ver el mismo enlace que antes).
Ventero
12

Pitón, 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()

Esto utiliza un enfoque recursivo para construir la curva de Hilbert de enésimo orden a partir de la curva anterior. Las curvas se representan como una matriz numpy en 2d para un mejor corte y manipulación.

Aquí hay unos ejemplos:

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

Malsys - 234 221 caracteres

Huelo algunos sistemas L aquí :) Malsys es un intérprete en línea del sistema L. Esta no es una entrada realmente seria, pero sentí que esta solución es algo interesante.

La sintaxis de Malsys no es realmente buena para el golf, ya que contiene muchas palabras clave largas, pero aún así, es bastante corta, legible y expresiva.

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

Intérprete: http://malsys.cz/Process

Versión de golf:

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;

¿Y qué hay de la curva Ascii hexagonal Gosper? :)

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

http://malsys.cz/g/ae5v5vGB

NightElfik
fuente
2

JavaScript (ES6) 313 340

Editar Se eliminan algunos caracteres usando prácticas realmente malas , como la variable global w en lugar de un valor de retorno de la función H

Convirtiendo la posición x, y a la distancia d (ver Wikipedia ) para cada x, y verificando si las posiciones más cercanas están conectadas,

Prueba en la consola FireFox. Entrada a través de ventana emergente, salida a través de console.log.

No hay espacios finales ni líneas nuevas encima o debajo de la imagen. Pero cada línea termina con una nueva línea, creo que es la forma correcta de hacer una imagen de arte 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
fuente
Puede guardar algunos caracteres usando en alertlugar de console.log. También tiene un espacio extra después forde la cuarta línea, y debería poder deshacerse de ese último salto de línea.
Bob
@Bob sí, de hecho, puedo guardar unos 15 caracteres más, de todos modos dejé de ver que tengo más de 300. No me gusta usar 'alert' porque la imagen es completamente irreconocible sin una fuente de tono fijo
edc65
2

Perl, 270 caracteres

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

No tanto 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

Probablemente podría jugar más golf si entendiera mejor a Perl. Utiliza un enfoque de sistema Lindenmayer utilizando reglas de producción definidas en la línea 1.

killmous
fuente
2

APL (Dyalog Unicode) , SBCS de 90 bytes

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

Pruébalo en línea!

2 2⍴0 una matriz de ceros 2x2

{ }⍣⎕ ingrese N y aplique una función N veces

⍵,⍨-⊖⍵ concatenar a la izquierda de la matriz una copia verticalmente invertida y negada de sí mismo

(2×s←⍴⍵)↑pad con ceros para que las dimensiones (recordadas como s) sean dos veces las del argumento

¯.5×≢⍵ girar hacia abajo para centrarlo verticalmente, intercalado entre los ceros de relleno

2@(¯1 0+3 1×s÷2) pon 2-s en ubicaciones específicas: estas son las barras diagonales entre instancias más pequeñas del fractal

(⊢+⍉) agregue la matriz con su yo transpuesto

3|módulo 3; utilizamos negación, así que tenga en cuenta que -1≡2 (mod 3) y -2≡1 (mod 3)

' /\'[ ] usar los elementos de la matriz como índices en la cadena ' /\'

1↓∘⍉∘⌽⍣4 recorte el margen vacío de 1 elemento de ancho desde todos los lados

dividido en líneas

' +$'⎕r''¨ eliminar espacios finales de cada uno (este desafío lo requiere)

⎕∘←¨ salida cada

ngn
fuente