CJam,148个 116 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}/
在这里测试。
斐波那契式的示例:
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
指最里面的六角形还是最外面的六角形?