引爆一根弦


34

给定任何字符串,以三角形的形式打印它,其中文本沿每个对角线上下移动。例如,输入的"Hello World"应输出:

                    d
                  l  
                r   d
              o   l  
            W   r   d
              o   l  
        o   W   r   d
      l       o   l  
    l   o   W   r   d
  e   l       o   l  
H   l   o   W   r   d
  e   l       o   l  
    l   o   W   r   d
      l       o   l  
        o   W   r   d
              o   l  
            W   r   d
              o   l  
                r   d
                  l  
                    d

为了保持正确的格式,一行中每个字符之间的空格必须至少为1。


1
我们可以假设字符串不为空吗?
Xcoder先生17年

@ Mr.Xcoder是的,你可能
马基雅维利

1
一行中每个字符之间的间距必须至少为1:这是否表示这H l o W r d是有效的中心行?问,因为在您的示例中,每行之间每个字符之间有3个空格。
Emigna '17

1
抱歉,@ Emigna我误解了您的问题。是的,您的示例将是有效的。
machiavelli

1
允许前导空格还是尾随空格?
路易斯·门多

Answers:


19

木炭10 7字节

↗ELθ✂θιUE¹

在线尝试! 在线尝试!链接指向详细版本的代码。说明:

    ↗       Print up and to the right
     ELθ✂θι All suffixes of the input, as a list down and to the right
    UE¹     Insert blank columns

第一次使用UE命令。


我知道木炭将是这里的第一个答案。.我几乎很想开始自己,但是我没有经验,无法及时完成解决方案,无论如何它都会变得过时了..;)
凯文Cruijssen

6
@Emigna ...但这是我使用的最大机会UE...
Neil

6
@EriktheOutgolfer ...但这是我使用的最大机会UE..
Neil

1
@Neil -3个字节!-3是个不错的牺牲!谁不想要漂亮的-3?
暴民埃里克(Erik the Outgolfer)'17年

4
@EriktheOutgolfer您应该说的是,“您不能让05AB1E击败您,可以吗?”
尼尔,



8

C,86 78 73 70字符

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

在线尝试!

说明

天真的实现:两个周期,从上到下,从左到右填充(99个字节):

for(int j=1;j<n*2;j++){for(int i=0;i<n;i++)printf("%c ",(i+j)%2&&i+1>=abs(j-n)?s[i]:' ');puts("");}

在这里,puts()仅将\ n打印到输出中。让我们结合变量声明并将j ++与某些东西(94字节)结合起来:

for(int i,j=0;++j<n*2;){for(i=0;i<n;i++)printf("%c ",(i+j)%2&&i>=abs(j-n)?s[i]:' ');puts("");}

好。变量j的范围为0 ... 2n; 让它在-n ... n之内,这使数学更简单。请注意,&&右侧的布尔表达式始终具有0或1的值。这意味着我们可以将&&替换为&。91个字节:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)printf("%c ",~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

现在我们意识到我们可以打印更多的空间。是的,我们不需要printf()仅打印单个符号。86个字节:

for(int i,j=-n;++j<n;){for(i=0;i<n;i++)putchar(~(i+j)%2&i>=abs(j)?s[i]:' ');puts("");}

更好。注意条件i * i> = j * j与i> = abs(j)相同,但更短。让我们将puts()移到for循环增量表达式中。你猜怎么着?实际上,我们不需要围绕i + j的括号。78个字节:

for(int i,j=-n;++j<n;puts(""))for(i=0;i<n;i++)putchar(i*i>=j*j&~i+j?s[i]:' '); 

您是否知道putchar()返回它已打印的字符?让我们使用XOR来测试数字是否相等。让我们用其ASCII码32代替空间。记住行尾字符码为13。最后:您是否知道GCC / Clang支持https://en.wikipedia.org/wiki/Elvis_operator?73个字节:

for(int i,j=-n;++j<n;)for(i=0;putchar(i*i>=j*j&~i+j?s[i]?:13:32)^13;i++);

最后,您猜怎么着?我们不需要两个for循环。我们可以用ij代替丑陋的〜i + j。70个字节:

for(int i=1,j=1-n;i=putchar(j*j<i*i&i-j?s[i-1]?:13:32)^13?i+1:++j<n;);

未来的工作:改变循环方向?如果正确完成,这可能会节省一些字节。


5

SOGL V0.1213 10 9 个字节

ēI*@∑}¹╚H

这使用了我一个功能只是增加了,但被记录在案前一阵子。

在这里尝试!
在该链接,中添加是因为这期望输入堆栈上的内容,并{添加了链接,因为否则,每次都会在循环中执行该链接

implicitly start loop over POP
ē            increase the variable E, on first push which will be 0
 I           increase by 1
  *          multiply the current character that many times
   @∑        join with spaces
     }     end loop
      ¹    wrap everything on stack in an array
       ╚   center vertically
        H  rotate counter-clockwise


3

盖亚 16字节

$:ċ⟪×$§×⟫†€|$¦tụ

在线尝试!

说明

$                 Split into list of chars
 :ċ               Push [1 .. len(input)]
   ⟪×$§×⟫†        Apply this block to corresponding elements of the two lists:
    ×              Repetition
     $             Split into chars
      §×           Join with spaces
          €|      Centre align the rows
            $¦    Split each line into chars
              t   Transpose
               ụ  Join each row with spaces, then join the rows together with newlines




3

Java,292个字节(对不起)

public class D{
public static void main(String[]r){
String s=r[0];int L=s.length(),n=L*2-1,x=L-1,d=-1,i,j;boolean a=false,o=L%2==1;
for(i=0;i<n;i++){
for(j=0;j<L;j++)System.out.print(j<x||a&&j%2==(o?0:1)||!a&&j%2==(o?1:0)?' ':s.charAt(j));
System.out.println();
x+=d;if(x<0){x=0;d=1;}a=!a;}}}

1
您可以删除换行符,否则,看起来不错!
扎卡里

1
您可以打更多高尔夫球:1 boolean a=1<0,o=L%2>0;。2.如果不需要i,请使用以下循环:for(i=0;i++<n;)。3.您可以摆脱oj%2<L%2然后j%2>L%2。4. d用作翻页需要很多字符:只需做j<(x<0?-x:x)。5.您拥有比所需更多的变量。6.您不需要完整的程序:lambda或方法就足够了。-如果您想打高尔夫的Java示例,请查看我的回答
奥利维尔·格雷戈尔


3

Java(OpenJDK 8),116字节

s->{for(int l=s.length(),i=-l;++i<l;)System.out.printf("%"+l+"s%n",s.substring(i<0?-i:i).replaceAll("(.).","$1 "));}

在线尝试!

说明

s->{                                // Consumer<String> lambda
 for(int l=s.length(),i=-l;++i<l;)  // For each length between l and 1 and back to l, 
  System.out.printf("%"+l+"s%n",    // Print with align to right
    s.substring(i<0?-i:i)           // skip the first |i| characters
     .replaceAll("(.).","$1 ")      // replace every even-positioned character with a space.
   );
}


3

Haskell中140个 137字节

(m#n)s=(\(i,x)->' ':(last$"  ":[x:" "|rem i 2==m&&i>n]))=<<zip[0..]s
g s=((++)=<<reverse.tail)$id=<<[[(0#n)s,(1#n)s]|n<-[-1,1..length s]]

在线尝试!

将3字节的字节保存到Challenger5

我认为那不是最佳...

f产生其中一行(m= 0或1是行号的模,是行号n

g 插入“奇数”和“偶数”行,并在结果中添加自身的镜像。


您可以通过定义f为infix函数(如中的(m#n)s=...)而不是前缀函数来保存字节。
硕果累累



2

Mathematica 105字节

(c=Characters@#;l=Length@c;StringRiffle@Table[If[Abs[j-l]<i&&EvenQ[j+i],c[[i]]," "],{j,1,2l+1},{i,1,l}])&

也许我可以再剃掉一两个字节,但是在Mathematica中处理字符串的字符计数开销给像这样的简单竞争带来了挑战。


2

J,54个字节

[:|:|.@i.@#(>@],~' '#~[)"_1[:(,' '&,)/&.>>:@i.@#<@#"0]

在线尝试!(请注意,TIO上的输出具有换行符和三个空格,但这不是来自函数调用-可能只是J解释器自动执行的操作)。

我认为解决此问题的总体思路是正确的,但是我可能在优化过程中有些次要的小事情正在增加字节数。

以前的变体

55字节

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1>:@i.@#(,' '&,)/@#"0]

56个字节

<:@+:@#{.[:|:|.@i.@#(],~' '#~[)"_1#{.[:(,' '&,)//.[:]\.]

说明

这将分为几个功能。另外,我对解释的后半部分还不够全面,因此,如果您想对某个部分进行更好的解释,请告诉我,我可以对其进行编辑。

dup   =. >:@i.@# <@#"0 ]
space =. (,' '&,)/&.>
pad   =. |.@i.@# (>@],~' '#~[)"_1 ]
trans =. |:
  • dup 将每个字符重复其在字符串中的索引(加一)的次数
  • space 在每个字符之间插入空格
  • pad 用适当的空格填充字符
  • trans 转置结果矩阵

样品通话:

   trans pad space dup 'abc'
  c
 b 
a c
 b 
  c

杜普

>:@i.@# <@#"0 ]
>:@i.@#         Indices of each character plus one
      #          Length of the string
   i.            Range [0,length)
>:               Add one
        <@#"0 ] Duplicate each character as many times as it index (plus one)
           "0   For each
          #   ]  Copy the character
>:@i.@#           as many times as it index
        <        Box the result

结果用方框框起来,以防止J用空格填充末端(因为它们的长度不均匀)。

样品通话:

   dup 'abc'
┌─┬──┬───┐
│a│bb│ccc│
└─┴──┴───┘

空间

(,' '&,)/&.>
         &.>  For each boxed element
(,' '&,)/      Insert spaces between each

样品通话:

   space dup 'abc'
┌─┬───┬─────┐
│a│b b│c c c│
└─┴───┴─────┘

|.@i.@# (>@],~' '#~[)"_1 ]
        (>@],~' '#~[)      Pad the right arg with spaces given by the left arg
|.@i.@#                    Indices in reverse order
   i. #                     Range [0,length)
|.                          Reverse

基本上,将第一个元素的长度为1个空格,第二个元素的长度为2个,依此类推。它还会删除装箱。

样品通话:

   pad space dup 'abc'
  a  
 b b 
c c c

转置

这只是内置函数|:,需要对矩阵进行转置。


1
我使用了类似的方法,但是避免了装箱。45个字节:|:@(-@i.@-@#|."0 1((,@,.~' '#~#)@$"0~1+i.@#))。它肯定可以打得更远。这部分-@i.@-@#是一些悬而未决的水果,最有可能
乔纳(Jonah)2017年

@Jonah我无法快速解读您的答案的工作原理,因此如果您愿意,我会把它留给您发布,因为我想对我的答案进行解释。我想对于我来说,J现在是仅写语言。
科尔

有助于快速解密:f=. <some tacit expression>,然后5!:2 <'f'提供框状的可视化效果并5!:4 <'f'提供树的可视化效果。在我的情况下,首先尝试$"0~1+i.@#使用某个字符串运行,然后在的右侧运行所有内容|."0 1,然后理解|."0 1所有内容在左侧(保存最后的转置)只是在进行必要的旋转。
约拿(Jonah)

1
哦,我没想到您会更新您的答案。它更像是“嘿,您可能会发现这很有趣”。我本可以发布它,但是觉得高级方法足够相似,这是不值得的。
约拿(Jonah)

2
刚刚记得#这里的帮助的复杂论点,26个字节,含|:@((-#)|."_1(1j1##)"0)~#\
英里

1

JavaScript(ECMAScript 6),161字节

(s,n=console.log)=>s.split("").map((q,i,a,p)=>n(p=" ".repeat(q=a.length-++i)+a.map((v,j)=>j>=q&&j%2==q%2?a[j]+' ':'').join(''))||p).reverse().map((v,i)=>i&&n(v))

在线尝试!


1

Perl 5、86 + 2(-F)= 88字节

使用@Dom的建议和我自己的一些调整来减少字节数。

for$k(0..$#F){$i=1;$a[$#F+$k]=$a[$#F-$k]=[map$i++<$k|($i+$k)%2?$":$_,@F]}say"@$_"for@a

在线尝试!


抱歉,很高兴您能得到答案!当我尝试修复我的问题并且无法解决时,您做了一些工作,您的方法是更好的选择!可以使用几个-aF字母来放几个字节,@F然后进行一些小的调整(-F因为之后需要一个空格,所以算作3):在线尝试!
Dom Hastings

1
为什么-F算为3?最多不应该是2吗?是不是之间的差异perl -e'code...'perl -eF 'code...'。还-a使用时不需要-F,所以字节可被切割。
Xcali

就是这样。所以,-F接受一个参数,但我们并不想传递一个在(-F让我们来对照一下-a上,没有参数分割,分割等等,每个字符),所以它的区别perl -ae '...'perl -aF -e '...'。默认情况下,-a分割为/\s+/。希望有助于澄清!
Dom Hastings

另外,很好用$#F!永远不要忘记那件事!
Dom Hastings

0

q / kdb +,55个字节

解:

-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x};

例:

q)-1(+){{1_a,((2*y)#" ",z),a:x#" "}'[(|)c;1+c:(!)(#)x]x}"Hello World";
          d
         l
        r d
       o l
      W r d
       o l
    o W r d
   l   o l
  l o W r d
 e l   o l
H l o W r d
 e l   o l
  l o W r d
   l   o l
    o W r d
       o l
      W r d
       o l
        r d
         l
          d

说明:

去做。非高尔夫版本为66个字节:

-1 flip{{1_a,((2*y)#" ",z),a:x#" "}'[reverse c;1+c:til count x]x};

奖金:

要获得与示例相同的输出(74个字节):

q)-1(+){1_'raze{(a,((2*y)#" ",z),a:x#" ";(2*y+x)#" ")}'[(|)c;1+c:(!)(#)x]x}"Hello World";
                    d
                  l
                r   d
              o   l
            W   r   d
              o   l
        o   W   r   d
      l       o   l
    l   o   W   r   d
  e   l       o   l
H   l   o   W   r   d
  e   l       o   l
    l   o   W   r   d
      l       o   l
        o   W   r   d
              o   l
            W   r   d
              o   l
                r   d
                  l
                    d
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.