Befunge, 444 368 323 bytes
&1>\1-:v
0v^*2\<_$00p>
_>:10p\:20pv^_@#-*2g00:+1,+55$
^!-<v*2g000<>$#<0>>-\:v
g2*^>>10g20g+v \ ^*84g_$:88+g,89+g,\1+:00
v#*!-1g02!g01_4^2_
>::00g2*-!\1-:10g-\20g-++>v
87+#^\#p01#<<v!`g01/2\+76:_
vv1-^#1-g01:\_$:2/20g`!
_ 2/^>:10g#vv#`g02/4*3:\+77
v>0p^^/2:/2_
<^2-1-g02</2`#*3:
0g+10p2*:^*3_1
! "#%$
%$"#!
!!##%
|||_
_ __
ลองออนไลน์!
วิธีการทั่วไปในการวาด Hilbert Curve คือการทำตามเส้นทางเป็นชุดของสโตรกและเทิร์นการเรนเดอร์ผลลัพธ์ลงในบิตแมปหรือพื้นที่หน่วยความจำบางส่วนแล้วเขียนเรนเดอร์นั้นเมื่อเส้นทางเสร็จสมบูรณ์ นี่เป็นไปไม่ได้ใน Befunge เมื่อเรามีหน่วยความจำ 2,000 ไบต์เท่านั้นที่ใช้งานได้และนั่นรวมถึงแหล่งที่มาของโปรแกรมด้วย
ดังนั้นวิธีที่เราทำในที่นี้คือสูตรที่บอกเราว่าตัวอักษรที่จะส่งออกสำหรับพิกัด x, y ที่กำหนด เพื่อให้เข้าใจถึงวิธีการทำงานนี้ก็ง่ายที่สุดที่จะไม่สนใจการแสดงผล ASCII ที่จะเริ่มต้นด้วยและเพียงแค่คิดว่าของเส้นโค้งเป็นที่สร้างขึ้นจากตัวละครกล่อง: ┌
, ┐
, └
, ┘
, และ│
─
เมื่อเราดูเส้นโค้งแบบนั้นเราจะเห็นได้ทันทีว่าด้านขวามือเป็นกระจกที่แน่นอนของด้านซ้ายมือ ตัวละครทางด้านขวาสามารถกำหนดได้โดยการมองหาคู่ของพวกเขาทางด้านซ้ายและสะท้อนให้เห็นในแนวนอน (เช่นเกิดขึ้นของ┌
และ┐
มีการสลับเช่นเดียวกับ└
และ┘
)
จากนั้นดูที่มุมล่างซ้ายอีกครั้งเราจะเห็นได้ว่าครึ่งล่างเป็นภาพสะท้อนของครึ่งบน ดังนั้นตัวละครที่อยู่ด้านล่างจะถูกกำหนดโดยเพียงแค่มองหาคู่ของพวกเขาด้านบนและสะท้อนให้เห็นในแนวตั้ง (เช่นเกิดขึ้น┌
และ└
มีการแลกเปลี่ยนเป็น┐
และ┘
)
ครึ่งที่เหลือของมุมนี้ไม่ค่อยชัดเจนนัก บล็อกด้านขวาสามารถได้มาจากการสะท้อนแนวตั้งของบล็อกที่อยู่ติดกันในแนวทแยงมุม
และบล็อกมือซ้ายสามารถได้มาจากการสะท้อนแนวตั้งของบล็อกในมุมบนซ้ายของเส้นโค้งเต็ม
ณ จุดนี้สิ่งที่เราเหลือไว้คือมุมบนซ้ายซึ่งเป็นอีกมุมหนึ่งของฮิลแบร์ตเคอร์ที่ต่ำลงหนึ่งรอบ ในทางทฤษฎีตอนนี้เราควรจะต้องทำซ้ำขั้นตอนอีกครั้ง แต่มีการจับ - ในระดับนี้ครึ่งซ้ายและขวาของบล็อกไม่ได้สะท้อนแน่นอนของกันและกัน
ดังนั้นในสิ่งอื่นที่ไม่ใช่ระดับบนสุดที่ตัวละครที่มุมด้านล่างต้องมีการจัดการเป็นกรณีพิเศษที่┌
ตัวละครจะสะท้อนให้เห็นเป็น─
และตัวละครที่สะท้อนให้เห็นเป็น│
└
แต่นอกเหนือจากนั้นเราสามารถทำซ้ำกระบวนการนี้ซ้ำ ๆ ได้ ในระดับสุดท้ายที่เรา hardcode ด้านบนซ้ายเป็นตัวและตัวอักษรด้านล่างเป็น┌
│
ตอนนี้เรามีวิธีกำหนดรูปร่างของเส้นโค้งที่พิกัด x, y เฉพาะแล้วเราจะแปลสิ่งนั้นเป็นการเรนเดอร์ ASCII ได้อย่างไร? จริงๆแล้วมันเป็นเพียงการทำแผนที่อย่างง่าย ๆ ที่แปลไทล์แต่ละอันที่เป็นไปได้ให้เป็นอักขระ ASCII สองตัว
┌
กลายเป็น _
(ช่องว่างบวกขีดล่าง)
┐
กลายเป็น
(สองช่องว่าง)
└
กลายเป็น|_
(แถบแนวตั้งบวกขีดล่าง)
┘
กลายเป็น|
(แถบแนวตั้งบวกพื้นที่)
│
จะกลายเป็น|
(อีกครั้งแถบแนวตั้งพร้อมพื้นที่)
─
กลายเป็น__
(ขีดล่างสองอัน)
การทำแผนที่นี้ไม่ง่ายในตอนแรก แต่คุณสามารถดูวิธีการทำงานเมื่อดูการเรนเดอร์ที่เกี่ยวข้องกันสองแบบ
และนั่นคือทั้งหมดที่มีให้ การใช้อัลกอริทึมนี้ใน Befunge จริง ๆ แล้วเป็นปัญหาอีกอย่างหนึ่งโดยสิ้นเชิง แต่ฉันจะทิ้งคำอธิบายไว้อีกครั้ง