วาดเส้นโค้ง Hilbert โดยใช้เครื่องหมายทับ


30

โค้ง Hilbertเป็นเศษส่วนพื้นที่บรรจุที่สามารถแสดงเป็นระบบ Lindenmayerกับรุ่นหลังที่มีลักษณะเช่นนี้
โค้งของฮิลแบร์ต
ขอขอบคุณที่http://www.texample.net/tikz/examples/hilbert-curve/สำหรับภาพ

เป้าหมาย

เขียนโปรแกรมที่สั้นที่สุดเท่าที่จะเป็นไปได้ (เป็นไบต์) ที่รับค่าจำนวนเต็มบวก n จาก stdin และดึงเส้นโค้ง Hilbert ลำดับที่ n มาที่ stdout โดยใช้เฉพาะเครื่องหมายทับด้านหน้า, สแลชย้อนหลัง, ช่องว่างและบรรทัดใหม่

ตัวอย่างเช่นถ้าอินพุตเป็น1เอาต์พุตต้องเป็น

 \
\/

หากอินพุตเป็น2เอาต์พุตจะต้องเป็น

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

หากอินพุตเป็น3เอาต์พุตจะต้องเป็น

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

และอื่น ๆ (พวกเขาดูดีกว่าถ้าคุณวางลงในบางสิ่งที่มีระยะห่างบรรทัดน้อยกว่า)

เอาต์พุตไม่ควรมีการขึ้นบรรทัดใหม่ด้านบนหรือด้านล่างสุดของเส้นโค้งหรือเว้นวรรคที่ต่อท้ายบนบรรทัดใด ๆ

คำตอบ:


10

Ruby, 247 230 205 ตัวอักษร

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

วิธี ASCII-turtle โดยใช้ตัวแทน Lindenmayer (ลองที่นี่ )

ใหญ่ขอบคุณ@Venteroสำหรับการเล่นกอล์ฟเพิ่มเติม


คาดหวังสิ่งนี้เพิ่มขึ้นอีกเล็กน้อยหวังว่าคุณจะไม่สนใจ: ideone.com/kvcPWT - .map(&:rstrip)ต้องมีการเพิ่มเพื่อตอบสนองความต้องการ "ไม่มีช่องว่างต่อท้าย"
Ventero

@Ventero ขอบคุณ หวังว่าคุณจะไม่รังเกียจที่ฉันใช้ทางออกของคุณ - คุณอาจละทิ้ง parantheses รอบ ๆ อาร์กิวเมนต์แผนที่
Howard

แน่นอน! ฉันเพิ่งตระหนักว่ามันเป็นไปได้ที่จะอินไลน์นิยามxและย่อการมอบหมายให้yและdรวม 205 ตัวอักษร (ดูลิงค์เดียวกันเหมือนก่อน)
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()

วิธีนี้ใช้วิธีเรียกซ้ำเพื่อสร้างเส้นโค้งลำดับที่สามของ Hilbert จากเส้นโค้งก่อนหน้า เส้นโค้งถูกแสดงเป็นอาร์เรย์ numpy 2d เพื่อการแบ่งส่วนและการจัดการที่ดีขึ้น

นี่คือตัวอย่างบางส่วน:

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

5

Malsys - 234 221 ตัวอักษร

ฉันได้กลิ่น L-systems ที่นี่ :) Malsys เป็นล่าม L-system ออนไลน์ นี่ไม่ใช่รายการที่ร้ายแรงจริงๆ แต่ฉันรู้สึกว่าโซลูชันนี้ค่อนข้างน่าสนใจ

ไวยากรณ์ของ Malsys นั้นไม่ค่อยดีสำหรับการเล่นกอล์ฟเนื่องจากมีคำหลักที่ยาวมาก แต่ก็ยังค่อนข้างสั้นอ่านและแสดงออกได้

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

ล่าม: http://malsys.cz/Process

รุ่น Golfed:

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;

แล้วเส้นโค้งโกสเปอร์แบบ Ascii หกเหลี่ยมล่ะ? :)

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

http://malsys.cz/g/ae5v5vGB


2

JavaScript (ES6) 313 340

แก้ไข ตัวละครบางตัวถูกลบโดยใช้ไม่ดีจริงๆวิธีปฏิบัติที่เช่นตัวแปรทั่วโลก w แทนค่าส่งคืนจากฟังก์ชัน H

การแปลงตำแหน่ง x, y เป็นระยะทาง d (ดูWikipedia ) สำหรับแต่ละ x, y และตรวจสอบว่าตำแหน่งที่ใกล้ที่สุดเชื่อมต่อกันหรือไม่

ทดสอบในคอนโซล FireFox อินพุตผ่านป๊อปอัพเอาต์พุตผ่าน console.log

ไม่มีช่องว่างต่อท้ายและไม่มีการขึ้นบรรทัดใหม่ด้านบนหรือด้านล่างของภาพ แต่แต่ละบรรทัดถูกยกเลิกด้วยบรรทัดใหม่ฉันคิดว่ามันเป็นวิธีที่ถูกต้องในการสร้างภาพศิลปะ 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)

คุณสามารถบันทึกตัวละครบางตัวโดยใช้ alertconsole.logแทน นอกจากนี้คุณยังมีพื้นที่พิเศษหลังจากforบรรทัดที่สี่และคุณควรจะสามารถกำจัดตัวแบ่งบรรทัดสุดท้าย
Bob

@ บ๊อบใช่จริง ๆ แล้วฉันสามารถบันทึกตัวละครได้อีก 15 ตัวฉันยอมแพ้เมื่อเห็นว่าฉันมีมากกว่า 300 ตัว ฉันไม่ชอบการใช้ 'การแจ้งเตือน' เนื่องจากภาพไม่สามารถจดจำได้อย่างสมบูรณ์โดยไม่มีแบบ
อักษรพิชช์

2

Perl, 270 ตัวอักษร

ซูเปอร์ golfed

$_=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

ไม่ค่อยเล่นกอล์ฟมากนัก

$_=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

อาจตีกอล์ฟลงได้มากกว่านี้หากฉันเข้าใจภาษา Perl ได้ดีขึ้น ใช้แนวทางของระบบ Lindenmayer โดยใช้กฎการผลิตที่กำหนดไว้ในบรรทัดที่ 1


2

APL (Dyalog Unicode) , 90 ไบต์SBCS

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

ลองออนไลน์!

2 2⍴0 เมทริกซ์ 2x2 ของศูนย์

{ }⍣⎕ อินพุต N และใช้ฟังก์ชัน N ครั้ง

⍵,⍨-⊖⍵ ต่อกันทางด้านซ้ายของเมทริกซ์สำเนาของตัวเองในแนวตั้งและกลับด้าน

(2×s←⍴⍵)↑แผ่นที่มีศูนย์เพื่อให้ขนาด (จำได้ว่าเป็นs) เป็นสองเท่าของการโต้แย้ง

¯.5×≢⍵ หมุนลงเพื่อจัดกึ่งกลางในแนวตั้งคั่นกลางระหว่างศูนย์

2@(¯1 0+3 1×s÷2) ใส่ 2-s ในตำแหน่งเฉพาะ - สิ่งเหล่านี้คือเครื่องหมายสแลชลิงก์ระหว่างอินสแตนซ์ขนาดเล็กของเศษส่วน

(⊢+⍉) เพิ่มเมทริกซ์ด้วยตนเองที่ถูกย้าย

3|โมดูโล 3; เราใช้การปฏิเสธดังนั้นโปรดทราบว่า-1≡2 (mod 3) และ-2≡1 (mod 3)

' /\'[ ] ใช้องค์ประกอบเมทริกซ์เป็นดัชนีในสตริง ' /\'

1↓∘⍉∘⌽⍣4 ตัดขอบว่างเปล่าแบบกว้าง 1 องค์ประกอบจากทุกด้าน

แบ่งออกเป็นเส้น

' +$'⎕r''¨ ลบช่องว่างต่อท้ายออกจากแต่ละ (ความท้าทายนี้ต้องใช้)

⎕∘←¨ ส่งออกแต่ละ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.