Disegna la curva di Hilbert


12

Una curva di Hilbert è un tipo di curva di riempimento dello spazio e fondamentalmente mappa una linea su un piano. Ogni punto nella linea corrisponde a un solo punto nel piano e ogni punto nel piano corrisponde a un solo punto sulla linea. Sono mostrate le iterazioni da 0 a 4 della curva di Hilbert:

Iterazioni da 0 a 4:

L'obiettivo di questo compito: scrivere il codice che disegna la quarta iterazione della curva di Hilbert, come definito sopra. Il tuo codice dovrebbe essere completo - in altre parole, se crei una funzione per disegnare la curva di Hilbert, il tuo codice deve chiamare quella funzione. L'output può essere visualizzato direttamente sullo schermo oppure è possibile scrivere l'output in un file di immagine. La curva può essere ruotata o capovolta, ma le linee devono intersecarsi ad angolo retto e l'output non può essere allungato. L'arte ASCII è apprezzata ma non sarà accettata. Vince il codice più corto in byte!


Il numero di volte è un input? O possiamo scegliere un valore di almeno 4?
Luis Mendo,

L'arte ASCII è considerata grafica?
Gabriel Benamy,

No; scusate, allora sarebbe un duplicato di un'altra domanda
J. Antonio Perez,

@JorgePerez La curva può avere un orientamento diverso? Come una versione ruotata verticalmente o ruotata di 90 gradi dei tuoi esempi
Luis Mendo,

Sì! Anche se la forma complessiva deve essere ancora quadrata
J. Antonio Perez,

Risposte:


7

R, 90 byte

n=scan();a=1+1i;b=1-1i;z=0;for(k in 1:n)z=c((w<-1i*Conj(z))-a,z-b,z+a,b-w)/2;plot(z,t="s")

Sha -eless R-port dell'algoritmo utilizzato nel collegamento pubblicato da @Luis Mendo.

Perché n=5otteniamo:

inserisci qui la descrizione dell'immagine


7

MATL , 39 38 byte

O5:"tZjJ*JQ-wJq+t2+&y2j+_v2/]XG25Y01ZG

Questo prende il numero di iterazioni come input. Se si desidera codificarlo, sostituirlo icon il numero.

Il programma è una porta del codice Matlab di Jonas Lundgren mostrato qui .

Il risultato è mostrato sotto. Puoi anche provarlo su MATL Online! Ci vogliono un paio di secondi per produrre l'output. Questo compilatore è sperimentale; potrebbe essere necessario aggiornare la pagina e premere nuovamente "Esegui" se inizialmente non funziona.

inserisci qui la descrizione dell'immagine

Spiegazione

O          % Push 0. This is the initial value of "z" in the original code
5:"        % Do 5 times
  t        %   Duplicate
  Zj       %   Complex conjugate
  J*       %   Multiply by 1j (imaginary unit). This is "w" in the original code
  JQ-      %   Subtract 1+1j
  w        %   Swap: brings copy of "z" to top
  Jq+      %   Add 1-1j
  t        %   Duplicate
  2+       %   Add 2
  &y       %   Duplicate the third element from top
  2j+_     %   Add 2j and negate
  v        %   Concatenate the three matrices vertically
  2/       %   Divide by 2
]          % End
XG         % Plot (in complex plane). The numbers are joined by straight lines
25Y0       % Push string 'square'
1ZG        % Make axis square

Potresti spiegare come funziona il tuo codice?
J. Antonio Perez,

L'algoritmo è esattamente come nel collegamento. Ma aggiungerò una spiegazione
Luis Mendo il

@Jorge Explanation ha aggiunto
Luis Mendo il

omg, quello su cui hai basato il tuo è molto più facile del mio = /
flawr

@flawr Tutto il merito a Jonas Lundgren :-)
Luis Mendo il

6

MATLAB, 264 262 161 byte

Funziona ancora più o meno allo stesso modo, tranne per il fatto che in sostanza calcoliamo la "derivata" della curva di Hilbert, che poi "integriamo" tramite `cumsum``. Ciò riduce la dimensione del codice di un bel po 'di byte.

function c;plot(cumsum([0,h(1,1+i,4)]));axis equal;end function v=h(f,d,l);v=d*[i*f,1,-i*f];if l;l=l-1;D=i*d*f;w=h(f,d,l);x=h(-f,D,l);v=[x,D,w,d,w,-D,-x];end;end

Vecchia versione

Questo è solo un semplice approccio ricorsivo. Ho usato numeri complessi per memorizzare informazioni vettoriali per semplicità. È possibile modificare la curva nella parte h(0,1,1+i,4). Il primo argomento p=0è la posizione iniziale, il secondo argomento fè una bandiera per l'orientamento ( +1o -1), il terzo argomento dè la direzione / rotazione in cui deve essere disegnata la curva e il quarto lè la profondità di ricorsione.

function c;hold on;h(0,1,1+i,4);axis equal;end function p=h(p,f,d,l);q=@plot;if l;l=l-1;d=i*d*f;p=h(p,-f,d,l);q(p+[0,d]);p=p+d;d=-i*d*f;p=h(p,f,d,l);q(p+[0,d]);p=p+d;p=h(p,f,d,l);d=-i*d*f;q(p+[0,d]);p=p+d;p=h(p,-f,d,l);else;q(p + d*[0,i*f,1+i*f,1]);p=p+d;end;end

Ecco come appare nelle versioni precedenti:

Ecco come appare nel 2015b:

->

1
In Matlab R2015b trama a colori <3
Luis Mendo il

Haha così bello :)
flawr

@LuisMendo Ora sono stato in grado di giocarci un po 'con l' cumsumidea che è semplicemente geniale!
Flawr

3

MATLAB / Octave, 202 byte

Ho notato che la versione @LuisMendo legati a dire era il modo più breve rispetto alle precedenti soluzioni "fatto a mano" , ma utilizza un approccio completamente diverso. Sto postando qui una versione golfata come CW:

Questa versione si basa sull'approccio del sistema Lindenmayer:

A=zeros(0,2);B=A;C=A;D=A;n=[0,1];e=[1,0];for k=1:4;a=[B;n;A;e;A;-n;C];b=[A;e;B;n;B;-e;D];c=[D;-e;C;-n;C;e;A];D=[C;-n;D;-e;D;n;B];A=a;B=b;C=c;end;A=[0,0;cumsum(A)];plot(A(:,1),A(:,2));axis off;axis equal

inserisci qui la descrizione dell'immagine


3

JavaScript (ES6), 266 ... 233 232 byte

Un rendering in formato SVG della curva di Hilbert.

document.write('<svg><path fill=none stroke=red d="M8 8'+(f=(i,s='2',d=x=y=8)=>i?f(i-1,s.replace(/./g,c=>[32410401423,,10432423401][+c]||c)):s.replace(/./g,c=>c-4?(d+=c&1&&c-2,''):`L${x+=4-'4840'[d&=3]} ${y+=4-'0484'[d]}`))(5)+'">')

Salvato 1 byte grazie a Neil


1
Provafill=none
Neil

2

Python 3, 177 175 171 byte

Una semplice implementazione del sistema Lindenmayer per la curva di Hilbert. Suggerimenti di golf benvenuti!

Modifica: -2 byte grazie a Kade. -3 byte dalla ristrutturazione della costruzione della curva di Hilbert. -1 byte con grazie a ETHproductions.

from turtle import*;s="a";exec('t=""\nfor c in s:t+=c>"F"and"+-abFF-+baFFba-+FFab+-"[c<"b"::2]or c\ns=t;'*5)
for c in s:
 if"-">c:rt(90)
 elif"F">c:lt(90)
 elif"a">c:fd(9)

inserisci qui la descrizione dell'immagine

Ungolfing

import turtle

hilbert_seq = "a"

for _ in range(5):
    new_seq = ""
    for char in hilbert_seq:
        if char == "a":
            new_seq += "-bF+aFa+Fb-"
        elif char == "b":
            new_seq += "+aF-bFb-Fa+"
        else:
            new_seq += char
    hilbert_seq = new_seq

for char in hilbert_seq:
    if char == "F":
        turtle.forward(9)
    elif char == "+":
        turtle.right(90)
    elif char == "-":
        turtle.left(90)

Cambiare il modo si forma tpuò salvare due byte: t+=[[c,"+AF-BFB-FA+"][c=="B"],"-BF+AFA+FB-"][c=="A"]. Dato che lo schema è quasi lo stesso per loro due, mi chiedo se c'è un modo per usarlo ..
Kade,

Forse passare if c>"E":a if"E"<c:per salvare un byte?
ETHproductions

1

MSWLogo (Versione 6.5b), 136 byte

Basato sul programma finale della curva di Hilbert qui .

to h :n :a :l
if :n=0[stop]
rt :a
h :n-1(-:a):l
fd :l
lt :a
h :n-1 :a :l
fd :l
h :n-1 :a :l
lt :a
fd :l
h :n-1(-:a):l
rt :a
end
h 5 90 9

Viene hdefinita una funzione , che richiede il numero di iterazioni :n(basate su 1), angolo :a, lunghezza :l. È ricorsivo, chiamando un'iterazione inferiore di se stesso con l'angolo :anegato in due casi per ottenere l'orientamento corretto.

  • rt :a, lt :aruota la tartaruga (triangolo del cui percorso è tracciato) a destra, a sinistra di :agradi.
  • fd :lsposta la tartaruga in avanti per :lpassi.

Infine, la funzione viene chiamata: h 5 90 9. La tartaruga può essere nascosto per un extra di 2 byte, ht.

(5-1) -th iteration


Cosa sta succedendo nell'angolo in alto a sinistra?
flawr

@flawr Questa è la tartaruga. Può essere nascosto aggiungendo ht.
per Monica,

1

Mathematica 128 byte

Graphics[Line@AnglePath[Total/@Split[Cases[Nest[#/.{-2->(s=##&@@#&)[l={-1,2,0,1,-2,0,-2,1,0,2,-1}],2->s@-l}&,{-2},4],-1|1|0],#!=0&][[;;-2,;;-2]]*Pi/2]]

Sostituisci il 4 sopra con un numero diverso di iterazioni, se lo desideri.

Fatto come un sistema Lindenmayer con sequenze di numeri interi anziché sequenze di stringhe, quindi la seconda regola di produzione è solo il negativo della prima regola. Questa versione è di 151 byte.

Il porto del codice MATLAB di Jonas Lundgren è di soli 128 byte.

z=0;Graphics[Line[{Re[#],Im[#]}&/@Flatten[Table[w=I*Conjugate[z];z={w-(a=1+I),z-(b=1-I),z+a,b-w}/2,{k,5}][[5]]]],AspectRatio->1]

Vedo che in una versione futura di Mathematica, questo potrebbe diventare davvero breve, qualcosa del tipo:

Graphics@HilbertCurve[n]

http://mathworld.wolfram.com/HilbertCurve.html


1

LindenMASM , 63 byte

Un'altra domanda con una risposta LindenMASM? Eccezionale!

STT
AXI A
INC 5
SET F 0
RPL A -BF+AFA+FB-
RPL B +AF-BFB-FA+
END

Ancora una volta, a causa di alcuni bug di disegno con Python turtle, a volte quando lo esegui l'intero disegno non è lì. Tuttavia puoi vedere che funziona davvero:

4a iterazione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.