Vẽ đường cong Hilbert bằng dấu gạch chéo


30

Các đường cong Hilbert là một không gian đầy fractal có thể được biểu diễn dưới dạng một hệ thống Lindenmayer với các thế hệ kế tiếp mà nhìn như thế này:
Đường cong Hilbert
Nhờ http://www.texample.net/tikz/examples/hilbert-curve/ cho hình ảnh.

Mục tiêu

Viết chương trình ngắn nhất có thể (tính bằng byte) lấy số nguyên dương n từ stdin và vẽ đường cong Hilbert bậc n đến stdout bằng cách chỉ sử dụng dấu gạch chéo, dấu gạch chéo ngược, dấu cách và dòng mới.

Ví dụ, nếu đầu vào là 1đầu ra phải

 \
\/

Nếu đầu vào là 2đầu ra phải

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

Nếu đầu vào là 3đầu ra phải

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

Và như vậy. (Chúng trông đẹp hơn nếu bạn dán chúng vào một cái gì đó với khoảng cách dòng ít hơn.)

Đầu ra không được chứa các dòng mới bên trên hoặc bên dưới các điểm cực trị của đường cong, cũng như không có bất kỳ dấu cách nào trên bất kỳ dòng nào.

Câu trả lời:


10

Ruby, 247 230 205 ký tự

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

Cách tiếp cận rùa ASCII sử dụng đại diện Lindenmayer (thử tại đây ).

Xin chân thành cảm ơn @Ventero vì đã chơi golf nhiều hơn.


Chơi gôn này nhiều hơn một chút, hy vọng bạn không phiền: ideone.com/kvcPWT - .map(&:rstrip)phải được thêm vào để đáp ứng yêu cầu "không có dấu cách".
Ventero

@Ventero Cảm ơn bạn. Hy vọng bạn không bận tâm rằng tôi đã lấy giải pháp của bạn - thậm chí bạn có thể loại bỏ các thông số xung quanh đối số bản đồ.
Howard

À, tất nhiên rồi! Tôi cũng chỉ nhận ra rằng có thể nội tuyến hóa định nghĩa xvà rút ngắn việc gán cho yd, với tổng số 205 ký tự (xem cùng một liên kết như trước).
Ventero

12

Con tră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()

Điều này sử dụng một cách tiếp cận đệ quy để xây dựng đường cong Hilbert bậc n ra khỏi đường cong trước đó. Các đường cong được biểu diễn dưới dạng một mảng numpy 2d để cắt và thao tác tốt hơn.

Dưới đây là một số ví dụ:

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/

5

Malsys - 234 221 ký tự

Tôi ngửi thấy một số hệ thống L ở đây :) Malsys là trình thông dịch hệ thống L trực tuyến. Đây không phải là mục thực sự nghiêm trọng nhưng tôi cảm thấy giải pháp này có phần thú vị.

Cú pháp của Malsys không thực sự tốt cho việc chơi golf vì nó chứa rất nhiều từ khóa dài nhưng vẫn khá ngắn, dễ đọc và diễn cảm.

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

Thông dịch viên: http://malsys.cz/Process

Phiên bản chơi gôn:

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;

Và làm thế nào về đường cong hình lục giác của Ascii? :)

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

http://malsys.cz/g/ae5v5vGB


2

JavaScript (ES6) 313 340

Chỉnh sửa một số ký tự bị xóa bằng cách sử dụng thực sự xấu tiễn - như biến toàn cục w thay vì giá trị trả về từ hàm H

Chuyển đổi vị trí x, y thành khoảng cách d (xem Wikipedia ) cho từng x, y và xác minh nếu các vị trí gần nhất được kết nối,

Thử nghiệm trong bảng điều khiển FireFox. Nhập qua popup, đầu ra qua console.log.

Không có dấu cách và không có dòng mới bên trên hoặc bên dưới hình ảnh. Nhưng mỗi dòng được kết thúc bằng một dòng mới, tôi nghĩ đó là cách chính xác để tạo ra một hình ảnh nghệ thuật của người Maya.

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)

Bạn có thể lưu một số ký tự bằng cách sử dụng alertthay vì console.log. Bạn cũng có thêm một khoảng trống sau fordòng thứ tư, và bạn sẽ có thể thoát khỏi dòng ngắt cuối cùng đó.
Bob

@Bob vâng, thực tế tôi có thể lưu thêm 15 ký tự nữa, tôi đã từ bỏ khi thấy tôi hơn 300. Tôi không thích sử dụng 'cảnh báo' vì hình ảnh hoàn toàn không thể nhận ra nếu không có phông chữ cố định
edc65

2

Perl, 270 ký tự

Siêu 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

Không có nhiều 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

Có lẽ có thể đánh gôn xuống nhiều hơn nếu tôi hiểu rõ hơn về Perl. Sử dụng phương pháp tiếp cận hệ thống Lindenmayer bằng cách sử dụng các quy tắc sản xuất được xác định trong dòng 1.


2

APL (Dyalog Unicode) , 90 byte SBCS

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

Hãy thử trực tuyến!

2 2⍴0 một ma trận 2x2 của số không

{ }⍣⎕ nhập N và áp dụng hàm N lần

⍵,⍨-⊖⍵ nối bên trái của ma trận một bản sao được đảo ngược và phủ định theo chiều dọc của chính nó

(2×s←⍴⍵)↑pad với các số 0 sao cho kích thước (được nhớ là s) gấp đôi đối số

¯.5×≢⍵ xoay xuống để căn giữa nó theo chiều dọc, kẹp giữa các số 0 đệm

2@(¯1 0+3 1×s÷2) đặt 2 giây tại các vị trí cụ thể - đây là các dấu gạch chéo liên kết giữa các trường hợp nhỏ hơn của fractal

(⊢+⍉) thêm ma trận với tự chuyển

3|modulo 3; chúng tôi đã sử dụng phủ định, vì vậy xin lưu ý rằng -1≡2 (mod 3) và -2≡1 (mod 3)

' /\'[ ] sử dụng các phần tử ma trận như các chỉ mục trong chuỗi ' /\'

1↓∘⍉∘⌽⍣4 cắt lề trống rộng 1 phần tử từ mọi phía

chia thành các dòng

' +$'⎕r''¨ xóa dấu cách từ mỗi dấu (thử thách này yêu cầu nó)

⎕∘←¨ đầu ra mỗi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.