CJam, 148 116 109 109 ไบต์
สิ่งนี้ใช้เวลานานกว่าที่ฉันคาดไว้มาก เดิมทีฉันต้องการสร้างจตุภาคซ้ายบนซ้ำแล้วซ้ำอีกเหมือนในความท้าทายของเพชรและจากนั้นให้เหลือจากการสะท้อน แต่ฉันไม่ได้สังเกตว่าขีดเส้นใต้ไม่เชื่อฟังกระจกสมมาตรระหว่างครึ่งบนและล่าง ดังนั้นฉันต้องทำซ้ำส่วนใหญ่เพื่อสร้างครึ่งทางที่ถูกต้องซ้ำแล้วสะท้อนเพียงครั้งเดียว (ทางซ้าย)
S]2[l~]:(f#:+2bW%{_,2/~:T;{IT):T1<'\'/?S?S++}%__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+}fI{)T)2*2$,-*1$W%"\/"_W%er@N}/
ทดสอบที่นี่
ตัวอย่าง Fibonacci-esque:
8 3 1 5 2
________________
/ \
/ \
/ __________ \
/ / \ \
/ / ______ \ \
/ / / ____ \ \ \
/ / / / __ \ \ \ \
/ / / / / \ \ \ \ \
\ \ \ \ \__/ / / / /
\ \ \ \____/ / / /
\ \ \______/ / /
\ \ / /
\ \__________/ /
\ /
\ /
\________________/
คำอธิบาย:
ตามที่ระบุไว้ด้านบนฉันเริ่มต้นด้วยการสร้างครึ่งทางขวาซ้ำ ๆ นั่นคือตอนแรกฉันมีเพียงช่องว่างเดียวในกริดและจากนั้นสำหรับวงแหวนที่เป็นไปได้แต่ละอันฉันจะล้อมรอบกริดที่มีอยู่ในช่องว่างหรือกึ่งหกเหลี่ยมใหม่
เมื่อทำเสร็จแล้วฉันจะสะท้อนแต่ละบรรทัดไปทางซ้ายและวางด้วยช่องว่างนำหน้าเพื่อจัดแนวที่ถูกต้อง นี่คือรายละเอียดของรหัส:
"Prepare the input and the grid:";
S]2[l~]:(f#:+2bW%
S] "Push string with a space and wrap it in an array. This is the grid.";
2 "Push a 2 for future use.";
[l~] "Read and evaluate the input, wrap it in an array.";
:( "Decrement each number by 1.";
f# "Map each number i to 2^i.";
:+ "Sum them all up.";
2b "Get the base two representation.";
W% "Reverse the array.":
"At this point, the stack has the proto-grid at the bottom, and an array of 1s and
0s on top, which indicates for each hexagon if it's present or not.";
"Next is a for loop, which runs the block for each of those 0s and 1s, storing the
actual value in I. This block adds the next semi-hexagon or spaces.";
{ ... }fI
"First, append two characters to all existing lines:";
_,2/~:T;{IT):T1<'\'/?S?S++}%
_ "Duplicate the previous grid.";
,2/ "Get its length, integer-divide by 2.";
~:T; "Get the bitwise complement and store it in T. Discard it.";
{ }% "Map this block onto each line of the grid.";
I "Push the current hexagon flag for future use.";
T):T "Push T, increment, store the new value.";
1<'\'/? "If T is less than 1, push \, else push /.";
S? "If the current flag is 0, replace by a space.";
S++ "Append a space and add it to the current line.";
"So for hexagons this appends '\ ' to the top half and '/ ' to the bottom half.
For empty rings, it appends ' ' to all lines.";
"Now add a new line to the top and the bottom:"
__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+
__ "Get two copies of the grid.";
,2/ "Get its length, integer-divide by 2.";
= "Get that line - this is always the middle line.";
,2/ "Get ITS length, integer'divide by 2.";
I'_S?* "Get a string of that many _ or spaces depending on the
current flag.";
_S+ "Duplicate and a space.";
a@+ "Wrap in an array, pull up the grid, and prepend the line.";
\ "Swap with the other copy.";
I'/S? "Choose between / and a space depending on the flag.";
S++ "Append a space, and add both characters to the line.";
a+ "Wrap in an array, and append line to the grid.";
"This is all. Rinse and repeat for all rings. The result will look something like this:
_____
\
___ \
__ \ \
_ \ \ \
\ \ \ \
_/ / / /
__/ / /
___/ /
/
_____/
Note that there are still trailing spaces.";
"Finish up all lines. These will not be joined together any more, but simply left
on the stack in pieces to printed out back-to-back at the end of the program.
The following runs the given block for each line:";
{ ... } /
"This generates the necessary indentation, then mirrors the lines and puts them
in the right order:"
)T)2*2$,-*\_W%"\/"_W%er\N
) "Slice off that trailing space, but leave it on the stack.";
T "Remember T? That still has something like the the size of
the grid from the last iteration. In fact it's N-1, where
N is the largest visible hexagon. We can use that to figure
out how many spaces we need.";
)2* "Increment and double.";
2$ "Copy the current line.";
,- "Subtract its length from 2*N.";
* "Repeat the space that often. This is our indentation.";
\_ "Swap with the line and duplicate.";
W% "Reverse the line.";
"\/"_W%er "Replace slashes with backslashes and vice versa.";
\ "Swap with the original line.";
N "Push a line break.";
1
อ้างถึงรูปหกเหลี่ยมด้านในสุดหรือด้านนอกสุด?