展开六角形源代码


52

介绍

如果您不熟悉Hexagony,那是MartinBüttner创建的一种深奥的语言。问题是该语言接受程序的多种形式。以下程序都是等效的:

abcdefg

 a b
c d e
 f g

因此,基本上,代码已汇总为规则的六边形。但是请注意,在代码中添加新命令abcdefgh将导致以下程序:

  a b c
 d e f g
h . . . .
 . . . .
  . . .

如您所见,第一步是将代码汇总成一个六边形,然后在六边形中用no-ops(.)填充到下一个居中的六边形数字

您的任务很简单,当给定字符串(源代码)时,输出完整的六角形源代码。

规则

  • 您可以提供程序或功能。
  • 允许前导空格,但仅当六角形不变形时才允许
  • 允许尾随空格。
  • 请注意,程序中的空格将被忽略。所以a b c等于abc
  • 仅使用可打印的ASCII字符(32 - 126),因此仅常规Space字符被忽略。
  • 假设字符串的长度大于0。
  • 这是,因此以最少的字节提交为准!

测试用例

Input: ?({{&2'2':{):!/)'*/

Output:
  ? ( {
 { & 2 '
2 ' : { )
 : ! / )
  ' * /


Input: H;e;l;d;*;r;o;Wl;;o;*433;@.>;23<\4;*/

Output:
   H ; e ;
  l ; d ; *
 ; r ; o ; W
l ; ; o ; * 4
 3 3 ; @ . >
  ; 2 3 < \
   4 ; * /


Input: .?'.) .@@/'/ .!.>   +=(<.!)}    (  $>( <%

Output:
   . ? ' .
  ) . @ @ /
 ' / . ! . >
+ = ( < . ! )
 } ( $ > ( <
  % . . . .
   . . . .

6
另外,我不确定您是否想成为那种挑剔的人,但是在确定代码宽度的过程中,反引号会被忽略,因为它们会注释下一个字符。所以abc`defg实际上会变成pastebin.com/ZrdJmHiR
Martin Ender

2
@MartinBüttner哦,我不知道那是:)。对于这个挑战,反引号将不会被忽略。
阿德南(Adnan)2015年

18
我真的很想在Hexagony中看到这个问题的答案。
Arcturus

2
@Adnan可能会有一个更好的响应:“您可以假定输入不包含调试标志(`字符)。”
Riking

4
@Ampora询问,您将收到。
马丁·恩德

Answers:


13

Pyth,57 54 50 49 48 46

V+UJfgh*6sUTlK-zd1_UtJ+*d-JNjd:.[K\.^TJZ=+Z+JN

测试套件

在每行上打印一个前导空格。

此版本需要证明所有n> = 1的10 ^ n> = 3n(n-1)+ 1。感谢ANerdIErickWong提供的证明。

遵循以下不等式:10 ^ n>(1 + 3)^ n = 1 + 3n + 9n(n-1)+ ...> 3n(n-1)+ 1人们可以很容易地看出这对于n>是正确的= 2。检查n = 1的情况相当琐碎,给出10> 1

替代地,对这些方程式的导数取两次表明,对于所有n> = 1,10 ^ n具有更大的二阶导数,然后可以将其级联为一阶导数,最后级联为原始方程式。

说明

              ##  Implicit: z=input(); Z=0
Jf...1        ##  Save to J the side length of the hexagon the code fills up
              ##  by finding the first number such that:
gh*6sUT       ##  the the T'th hexagonal number is greater than...
              ##  Computes 6 * T'th triangular number (by using sum 1..T-1) + 1
    lK-zd     ##  ...the length of the code without spaces (also save the string value to K)
V+UJ_UtJ      ##  For loop over N = [0, 1, ..., J-1, ..., 0]:
+*d-JN        ##  append J - N spaces to the front of the line
jd            ##  riffle the result of the next operation with spaces
:.[K\.yJ      ##  slice the string given by K padded to be the length of the Jth hexagon
              ##  number with noops
Z=+Z+JN       ##  from Z to Z + J + N, then set Z to be Z + J + N

2
首先,您需要证明n> = 1的ln(10)* 10 ^ n> 6n-3(导数)。这很容易,因为这些表达式的导数分别为ln(10)^ 2 10 ^ n和6。由于10 ^ n单调递增并且10 ^ 1> 6 * 1,所以10 ^ n都大于6n-3 n> = 1。您可以使用相同的逻辑来完成10 ^ n和3n(n-1)+1的证明。
Arcturus

@Ampora谢谢,我曾考虑过使用派生工具,但似乎不干净。我找不到更好的方法,非常感谢!
FryAmTheEggman 2015年

乐意效劳。Calc有时会变得非常丑陋。
Arcturus

在上面的链接pyth.herokuapp.com/?code=etc中,我发现编译器未运行...
RosLuP

1
@FryAmTheEggman有一个非常简单的方法来显示n> = 1的4 ^ n> 3n(n-1)+1的更强边界,不需要演算。只需使用(1 + 3)^ n = 1 + 3n + 9n(n-1)/ 2 + ...通过二项式展开的事实即可。第一项和第三项直接主化1 + 3n(n-1),因此如果存在第三项(即,对于n> = 2),则不等式是立即的。这留下仅是微不足道的,因为RHS为1的情况下n = 1的
埃里克黄

90

六角,271字节

我向您介绍六角形自我解释器的前3%...

|./...\..._..>}{<$}=<;>'<..../;<_'\{*46\..8._~;/;{{;<..|M..'{.>{{=.<.).|.."~....._.>(=</.\=\'$/}{<}.\../>../..._>../_....@/{$|....>...</..~\.>,<$/'";{}({/>-'(<\=&\><${~-"~<$)<....'.>=&'*){=&')&}\'\'2"'23}}_}&<_3.>.'*)'-<>{=/{\*={(&)'){\$<....={\>}}}\&32'-<=._.)}=)+'_+'&<

在线尝试!您也可以自己运行它,但是大约需要5到10秒。

原则上,这可能适合边长9(分数为217或更小),因为它仅使用201条命令,而我首先编写的非高尔夫球版本(边长为30)仅需要178条命令。但是,我很确定实际上要使所有内容都适合需要永远的时间,因此我不确定是否会尝试。

通过避免使用最后一排或两排,还应该有可能将其打成10码,这样就可以省略尾随的无人操作,但作为第一条路径之一,这将需要大量重写连接利用左下角。

说明

让我们首先展开代码并注释控制流路径:

在此处输入图片说明

这仍然很混乱,所以这里是我最初编写的“ unolfed”代码的同一图(实际上,这是侧面长度为20的代码,最初我是用侧面长度为30的代码编写的,但是它是如此稀疏,以至于根本没有提高可读性,所以我只做了一点压缩以使其尺寸更合理):

在此处输入图片说明
点击查看大图。

除了一些非常小的细节外,颜色完全相同,non-control-flow命令也完全相同。因此,我将在非高尔夫球版本的基础上解释其工作原理,如果您真的想知道打高尔夫球的部件是如何工作的,则可以检查其中的哪些部分对应于较大的六角形部分。(唯一的问题是高尔夫球代码以镜子开头,因此实际代码从右角开始向左移动。)

基本算法几乎与我的CJam答案相同。有两个区别:

  • 我没有计算中心六边形方程,而是计算连续的中心六边形直到一个等于或大于输入的长度。这是因为Hexagony没有简单的方法来计算平方根。
  • 而不是立即对输入进行无操作填充,我稍后再检查是否已经用尽了输入中的命令,.如果有则打印一个。

这意味着基本思想可以归结为:

  • 在计算输入字符串的长度时读取并存储它。
  • 找到可以容纳整个输入的最小边长N(和相应的居中六边形hex(N))。
  • 计算直径2N-1
  • 对于每一行,计算缩进量和像元数(总和为2N-1)。打印缩进,打印单元格(.如果输入已经用尽,则使用),打印换行符。

请注意,只有无操作,因此实际代码从左上角开始($,它跳过了>,所以我们实际上,深灰色路径开始于)。

这是初始的内存网格:

在此处输入图片说明

因此,内存指针从标记为input的边开始,指向北。,从STDIN读取一个字节,或者-1如果我们已经将EOF打入该边缘,则从中读取一个字节。因此,<紧接其后的条件是我们是否已阅读所有输入的条件。现在让我们保持在输入循环中。我们执行的下一个代码是

{&32'-

这会将32写入边缘标记的空间,然后从边缘标记diff的输入值中减去它。请注意,这绝不能为负,因为我们保证输入仅包含可打印的ASCII。当输入为空格时,它将为零。(正如Timwi指出的那样,如果输入中可以包含换行符或制表符,这仍然可以工作,但是它也会去除字符代码少于32的所有其他不可打印字符。)在这种情况下,<将指令指针(IP)偏左然后采用浅灰色路径。该路径只是用重置MP的位置,{=然后读取下一个字符-因此,跳过了空格。否则,如果字符不是空格,则执行

=}}})&'+'+)=}

这首先通过长度边沿六边形移动,直到与diff边相反,即为=}}}。然后它将值从长度边的对面复制到长度边,并用递增)&'+'+)。我们将在第二秒看到为什么这是有道理的。最后,我们通过以下方式移动了新的优势=}

在此处输入图片说明

(特定的边值来自挑战中给出的最后一个测试用例。)这时,循环重复进行,但是所有东西都向东北移动了一个六边形。因此,在阅读了另一个字符之后,我们得到了:

在此处输入图片说明

现在您可以看到我们正在沿着东北对角线逐渐写入输入(减去空格),每个其他边上的字符,直到该字符的长度与标记为length的边平行存储。

当我们完成输入循环后,内存将如下所示(我已经为下一部分标记了一些新的边):

在此处输入图片说明

%是我们读到的最后一个字符,则29是我们读的非空格字符数。现在我们要找到六边形的边长。首先,深绿色/灰色路径中有一些线性初始化代码:

=&''3{

在这里,=&将长度(在我们的示例中为29)复制到标记为length的边中。然后''3移至标记为3的边并将其值设置为3(我们只需要在计算中将其作为常数)即可。最后{移动到标记为N(N-1)的边缘。

现在我们进入蓝色循环。该循环递增N(存储在标记为N的单元格中),然后计算其居中的六边形数,并从输入长度中减去它。这样做的线性代码是:

{)')&({=*'*)'-

这里,{)移动到并递增Ñ')&(移动到标记为N-1的边缘,在N此处复制并递减。{=*计算其乘积N(N-1)'*)将其乘以常数,3并在标记为hex(N)的边中增加结果。如预期的那样,这是第N个居中的六角形数字。最后'-计算该长度与输入长度之间的差。如果结果是肯定的,则边长还不够大,并重复循环(}}将MP返回到标记为N(N-1)的边缘)。

一旦边长足够大,差异将为零或负,我们得到以下结果:

在此处输入图片说明

首先,现在有很长的线性绿色路径,该路径对输出回路进行了一些必要的初始化:

{=&}}}32'"2'=&'*){=&')&}}

{=&通过复制结果在开始DIFF边缘插入长度边缘,因为我们以后需要非正面那里。}}}32在标记为space的边缘写入32 。'"2将常数2写入diff上方未标记的边缘。'=&复制N-1到具有相同标签的第二条边。'*)将其乘以2并递增,以便在顶部标记为2N-1的边缘中获得正确的值。这是六边形的直径。{=&')&将直径复制到标记为2N-1的另一边中。最后}}移回顶部标记为2N-1的边缘。

让我们重新标记边缘:

在此处输入图片说明

我们当前位于(仍保留六边形直径)的边缘将用于在输出的各行上进行迭代。标记为缩进的边将计算当前行上需要多少空格。带有边缘标记的单元格将用于迭代当前行中的单元格数量。

我们现在在计算indent的粉红色路径上。('-减少迭代器,并将其从N-1中减去(缩进边缘)。代码中的蓝色/灰色短分支只是计算结果的模数(~如果该值是负数或零,则取反,如果是正数,则无任何反应)。粉色路径的其余部分是从直径"-~{减去凹痕到像边缘,然后移回凹痕边缘。

现在,肮脏的黄色路径将打印缩进。循环内容实际上只是

'";{}(

'"移动到空间边缘,;打印它,{}移动回缩进(递减它。

完成后,(第二个)深灰色路径将搜索要打印的下一个字符。的=}在位置移动时(这意味着,到细胞边缘,指向南)。然后,我们有一个非常紧密的循环,{}该循环只是简单地沿西南方向向下移动了两个边缘,直到到达存储字符串的末尾:

在此处输入图片说明

注意,我在EOF处重新标记了一条边吗?。处理完此字符后,将使该边为负,以便{}循环将在此处终止而不是下一次迭代:

在此处输入图片说明

在代码中,我们位于深灰色路径的末尾,在该路径的'后退一步到输入字符。如果情况是最后两个图表之一(即输入中仍有一个字符尚未打印),那么我们正在走绿色道路(最下面的道路是针对那些对绿色和绿色不好的人)蓝色)。那很简单:;打印角色本身。'移动到相应的空间边缘,该边缘仍保持较早的32,并;打印该空间。然后{~使我们的EOF?下一次迭代的结果为负,请'后退一步,以便我们可以通过另一个紧密}{循环返回到字符串的西北端。在长度上结束单元格(十六进制(N)下的非正数。最后}移回到单元格边缘。

如果我们已经用尽了输入,那么搜索EOF的循环?实际上将在此处终止:

在此处输入图片说明

在这种情况下,'移动到长度单元格上,我们改为采用浅蓝色(顶部)路径,该路径打印无操作。该分支中的代码是线性的:

{*46;{{;{{=

{*46;写入一个46到边缘标记的无操作并打印(即,周期)。然后{{;移至空白边缘并进行打印。该{{=给移回细胞边缘为下一次迭代。

在这一点上,路径重新连接在一起并(减小了单元的边缘。如果迭代器还不为零,我们将采用浅灰色路径,该路径将MP的方向简单地反转=,然后寻找下一个要打印的字符。

否则,我们将到达当前行的末尾,而IP将采用紫色路径。这是内存网格在那时的样子:

在此处输入图片说明

紫色路径包含以下内容:

=M8;~'"=

=再次反转MP的方向。M8将其值设置为778(因为Mis 77和数字的字符代码会将其自身附加到当前值)。碰巧是10 (mod 256),因此当我们使用进行打印时;,我们得到了换行符。然后~使边缘再次'"变为负值,移回边缘并再次=反转MP。

现在,如果线的边缘为零,就完成了。IP将采用(非常短的)红色路径,从而@终止程序。否则,我们将继续沿着紫色的路径前进,该路径将循环回到粉红色的路径,以打印另一行。


用Timwi的HexagonyColorer创建的控制流程图。用可视调试器在他的Esoteric IDE中创建的内存图。


19
我发现自己在六角形答案中经常说这句话:哇。
Conor O'Brien

5
呵呵...但是.. wat ...头脑=吹了
Adnan

我希望有人能做到这一点,...哇。我无语了。棒极了。
Arcturus

19
第二步-写其他97%。:)
ASCIIThenANSI

第三步-用最少的字节数作为答案。
汤姆M

19

CJam,56 52 50 48字节

我的第一个想法是,“嘿,我已经有此代码了!” 但是后来我就不费心将Ruby代码中的必要部分组合在一起,特别是因为它们似乎不太适合打高尔夫球。所以我改为在CJam中尝试其他方法...

lS-{_,4*(3/mq:D1%}{'.+}wD{D(2/-z_S*D@-@/(S*N@s}/

在这里测试。

说明

首先是关于中心六边形的数学运算。如果正六边形具有边长N,则它将包含3N(N-1)+1必须等于源代码长度的单元格k。我们可以解决这个问题,N因为它是一个简单的二次方程式:

N = 1/2 ± √(1/4 + (k-1)/3)

我们可以忽略负根,因为这样可以得到负N。要对此具有解决方案,我们需要平方根为半整数。换句话说,√(1 + 4(k-1)/3) = √((4k-1)/3)必须是一个整数(幸运的是,这个整数恰好是D = 2N-1我们仍然需要的六边形的直径)。因此,我们可以重复添加一个,.直到满足该条件。

其余的是一个简单的循环,它排列了六边形。对于此部分的一个有用观察是,缩进中的空格加上每行代码中非空格的总和等于直径。

lS-     e# Read input and remove spaces.
{       e# While the first block yields something truthy, evaluate the second...
  _,    e#   Duplicate the code and get its length k.
  4*(   e#   Compute 4k-1.
  3/    e#   Divide by 3.
  mq    e#   Take the square root.
  :D    e#   Store this in D, just in case we're done, because when we are, this happens
        e#   to be the diameter of the hexagon.
  1%    e#   Take modulo 1. This is 0 for integers, and non-zero for non-integers.
}{      e# ...
  '.+   e#   Append a no-op to the source code.
}w
D{      e# For every i from 0 to D-1...
  D(2/  e#   Compute (D-1)/2 = N, the side length.
  -z    e#   Subtract that from the current i and get its modulus. That's the size of the
        e#   indentation on this line.
  _S*   e#   Duplicate and get a string with that many spaces.
  D@-   e#   Subtract the other copy from D to get the number of characters of code
        e#   in the current line.
  @/    e#   Pull up the source code and split into chunks of this size.
  (S*   e#   Pull off the first chunk and riffle it with spaces.
  N     e#   Push a linefeed character.
  @s    e#   Pull up the remaining chunks and join them back into a single string.
}/

事实证明,我们根本不需要使用双精度算术(平方根除外)。由于乘以4,所以除以3时不会发生冲突,并且期望的k将是第一个产生整数平方根的对象。


8

Perl中,203 200 198

包括+1 -p

s/\s//g;{($l=y///c)>($h=1+3*++$n*($n-1))&&redo}$s=$_.'.'x($h-$l);for($a=$n;$a<($d=2*$n-1);$a++){$s=~s/.{$a}/$&\n/,$s=reverse($s)for 0..1}$_=join$/,map{(' 'x abs($n-$i++-1)).$_}$s=~/\S+/g;s/\S/ $&/g

运行为: echo abc | perl -p file.pl

一个非常幼稚的方法:

#!/usr/bin/perl -p

s/\s//g;                            # ignore spaces and EOL etc.
{                                   # find the smallest hex number:
    ($l=y///c)                      # calc string length
    > ($h=1+3*++$n*($n-1))          # 
    && redo                         # (should use 'and', but..)
}

$s = $_                             # save $_ as it is used in the nested for
   . '.' x ($h-$l);                 # append dots to fill hexagon

for ( $a = $n; $a < ($d=2*$n-1); $a++ )
{
        $s=~s/.{$a}/$&\n/,          # split lines
        $s=reverse($s)              # mirror
    for 0..1                        # twice
}

$_ = join$/,                        # join using newline
map {                               # iterate the lines
    (' 'x abs($n-$i++-1)) .$_       # prepend padding
} $s=~/\S+/g;                       # match lines

s/\S/ $&/g                          # prepend spaces to characters
                                    # -p takes care of printing $_

  • 更新200保存一个字节的移动变量分配,并通过省略final来保存另外2个字节;;现在将自己编码为200个字节以下!
  • 更新198通过使用$s=~/\S+/g代替来保存2个字节split/\n/,$s

7

的JavaScript(ES6),162 172

匿名功能

找到六边形的大小,可以解决维基百科的方程式

3*n*(n-1)-1 = l

求解公式基本上是

n = ceil(3+sqrt(12*l-3))/6)

随着一些代数和一些近似(也@@ user18655的thx),它变成

n = trunc(sqrt(l/3-1/12)+1.4999....)
s=>eval("s=s.match(/\\S/g);m=n=Math.sqrt(s.length/3-1/12)+1.49999|0;p=o=``;for(i=n+n;--i;i>n?++m:--m)for(o+=`\n`+` `.repeat(n+n-m),j=m;j--;o+=` `)o+=s[p++]||`.`")

更具可读性

s=>{
  s=s.match(/\S/g);
  m=n=Math.sqrt(s.length/3-1/12)+1.49999;
  p=o='';
  for(i=n+n; --i; i>n?++m:--m)
    for(o += '\n'+' '.repeat(n+n-m), j=m; j--; o += ' ')
      o+=s[p++]||'.';
  return o
}

测试代码段(更好的整页-运行时间〜1分钟)

f=s=>eval("s=s.match(/\\S/g);m=n=Math.sqrt(s.length/3-1/12)+1.49999|0;p=o=``;for(i=n+n;--i;i>n?++m:--m)for(o+=`\n`+` `.repeat(n+n-m),j=m;j--;o+=` `)o+=s[p++]||`.`")

t=0;
r='0';
(T=_=>t++<816?(O.innerHTML=f(r=t%10+r),setTimeout(T,20)):0)()
pre { font-size: 66% }
<pre id=O></pre>


1
您可以使用n=...+1-1e-9|0而不是n=Math.ceil(...)节省2个字节。您也可以使用ES7而**0.5不是使用它,Math.sqrt但这取决于您。我通常只保留我的答案ES6,因为它们可以在我的浏览器中使用哈哈!
user81655

@ user81655好提示,谢谢
edc65

5

Pyth,52 51字节

Jfgh**3TtTl=H-zd1=+H*\.*lHTV+UJt_UJAcH]+JN+*-JNdjdG

在线尝试。 测试套件。

OP允许的每一行都有一个额外的引导空间。

说明

 f              1          |   find first number n for which
             -zd           |           remove spaces from input
           =H              |         put result in H
          l                |       length of input without spaces
  g                        |     is less than or equal to
   h**3TtT                 |       nth centered hexagonal number
J                          | put result (hexagon side length) in J
                           |
      *lHT                 |      ten times length of input without spaces
   *\.                     |   that amount of dots
=+H                        | append to H
                           |
  UJ                       |    numbers 0 up to side length - 1
 +  t_UJ                   |   add numbers side length - 2 down to 0
V                          | loop over result
            +JN            |       current loop number + side length
         cH]               |     split to two parts at that position
        A                  |   put parts to G and H
                 -JN       |       side length - current loop number - 1
                *   d      |     that many spaces
                     jdG   |     join code on the line (G) by spaces
               +           |   concatenate parts and print

5

视网膜,161字节

感谢FryAmTheEggman节省了2个字节。

这个答案是非竞争性的。自从这项挑战以来,Retina已经看到了一些更新,而且我很确定我正在使用一些较新的功能(尽管我没有检查)。

字节数假定为ISO 8859-1编码。第一行包含一个空格。请注意,大多数·实际上是中心点(0xB7)。

 

^
$._$*·¶
^·¶
¶
((^·|\2·)*)·\1{5}·+
$2·
^·*
$.&$* ·$&$&$.&$* 
M!&m`(?<=(?= *(·)+)^.*)(?<-1>.)+(?(1)!)|^.+$
+m`^( *·+)· *¶(?=\1)
$& 
·
 ·
O$`(·)|\S
$1
·
.
G-2`

在线尝试!

好...

说明

看起来最简单的方法是先仅使用一个字符(·在这种情况下)构建布局,然后使用输入字符填充结果布局。造成这种情况的主要原因是,使用单个字符使我可以使用反向引用和字符重复,而直接布置输入将需要昂贵的平衡组。

 

尽管看起来并不多,但此第一阶段会从输入中删除空格。

^
$._$*·¶

我们首先添加一条包含M中心点的附加线,其中M是输入的长度(删除空格后)。

^·¶
¶

如果输入是单个字符,我们将再次删除该中心点。这是一个不幸的特殊情况,下一阶段将不涉及。

((^·|\2·)*)·\1{5}·+
$2·

这将计算所需的边长N减去1。这是这样工作的:居中的六边形数的形式为3*N*(N-1) + 1。由于三角数为N*(N-1)/2,这意味着六角数是三角数加1的六倍。这很方便,因为1 + 2 + 3 + ... + N在正则表达式中匹配三角数(实际上只是)非常容易。本(^·|\2·)*场比赛最大的三角形数量就可以了。作为一个不错的选择,$2它将保留该三角形的索引。要将其乘以6,我们将其捕获到组中1,然后再匹配5次。我们要确保至少有两个···+。这样,找到的三角数的索引不会增加,直到比中心六边形数多一个字符为止。

最后,此匹配使我们的分组长度比所需六边形的边长少两个$2,因此我们将其与一个中心点一起写回以获得N-1

^·*
$.&$* ·$&$&$.&$* 

这会将我们的N-1中心点字符串转换为N-1空格,2N-1中心点和另一个N-1空格。请注意,这是最大压痕,然后是六边形的直径,再是压痕。

M!&m`(?<=(?= *(·)+)^.*)(?<-1>.)+(?(1)!)|^.+$

这太长了,但基本上它只是给我们所有重叠的匹配项,这些匹配项要么是a)2N-1字符长且在第一行,要么在b)第二行。这会将前一阶段的结果扩展为完整但呈凹状的六边形。例如,12345678我们得到的输入是:

  ···
 ····
·····
···· 
···  
12345678

这就是为什么我们还需要在上一阶段附加空格。

+m`^( *·+)· *¶(?=\1)
$& 

这通过重复缩进比前一条短的任何一条线(忽略尾随空格)来固定中心线的缩进,因此我们得到了以下结果:

  ···
 ····
·····
 ···· 
  ···  
12345678

现在我们只用

·
 ·

这给了我们:

   · · ·
  · · · ·
 · · · · ·
  · · · · 
   · · ·  
12345678

ew,做完了。

O$`(·)|\S
$1

是时候将输入字符串填充到中心点了。这是在排序阶段的帮助下完成的。我们匹配所有中心点和最后一行上的每个字符,并根据给定替换的结果对它们进行排序。对于最后一行的字符和·中心点,该替换为空,因此发生的情况是,中心点仅被简单地排序到末尾(因为排序是稳定的)。这会将输入字符移到适当位置:

   1 2 3
  4 5 6 7
 8 · · · ·
  · · · · 
   · · ·  
········

现在只剩下两件事:

·
.

这会将中心点变成规则的周期。

G-2`

这将丢弃最后一行。


1

JavaScript(ES6),144个字节

(s,n=1,l=0,p=0,m=s.match(/\S/g))=>m[n]?f(s,n+6*++l,l):[...Array(l+l+1)].map((_,i,a)=>a.map((_,j)=>j<l-i|j<i-l?``:m[p++]||`.`).join` `).join`\n`

其中\n代表文字换行符。使用一种创建六角形的技术,该技术我以前在其他几个答案中使用过。对于ES7,求平方根比递归方法要短一些:

(s,p=0,m=s.match(/\S/g),l=(~-m.length/3)**.5+.5|0)=>[...Array(l+l+1)].map((_,i,a)=>a.map((_,j)=>j<l-i|j<i-l?``:m[p++]||`.`).join` `).join`\n`

1

Python 3,144字节

c=input().replace(' ','')
n=x=1
while x<len(c):x+=n*6;n+=1
c=c.ljust(x,'.')
while c:print(' '*(x-n)+' '.join(c[:n]));c=c[n:];n-=(len(c)<x/2)*2-1

在线尝试!

对于不同大小的六边形,这会使用相当数量的前导空白,但是总体形状仍然存在。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.