做出超级杂技


35

背景

庆祝Dyalog APL 16.0的发布,该问题的解决方案是{⊢⌺(≢⍵)⊢⍵}说明

任务

给定具有奇数长度 n的可打印ASCII字符串,使n × n正方形,其中字符串水平居中,重复复制以垂直居中,并且在每行和每列中都具有相同的字符串。请注意,除居中的字符串以外的所有字符串都将被切除,以保持正方形的大小n × n

您的代码说明将不胜感激。

规则

  1. 您可能会有尾随空格和换行符(这包括右下三角形)
  2. 您可以返回字符串列表

使用字符串的示例ABXCD

  • n为5。首先,我们绘制两个居中的字符串,一个水平和一个垂直:

    ┌─────┐
    │A│
    │B│
    │ABXCD│
    │C│
    │D│
    └─────┘
    

    (为清晰起见,添加了5×5边界框)

  • 然后,我们水平和垂直放置所有可能的杂技:

           一种
          AB
      ┌─────┐
      │ABX│CD
      │ABXC│D
      │ABXCD│
     A│BXCD│
    AB│XCD│
      └─────┘
       光盘
       d
    
  • 最后,我们只返回边界框内的内容:

      ABX
     ABXC
    ABXCD
    BXCD 
    XCD  
    

测试用例

World

  Wor
 Worl
World
orld
rld

mississippi

     missis
    mississ
   mississi
  mississip
 mississipp
mississippi
ississippi
ssissippi
sissippi
issippi
ssippi

Pneumonoultramicroscopicsilicovolcanoconiosis

                      Pneumonoultramicroscopi
                     Pneumonoultramicroscopic
                    Pneumonoultramicroscopics
                   Pneumonoultramicroscopicsi
                  Pneumonoultramicroscopicsil
                 Pneumonoultramicroscopicsili
                Pneumonoultramicroscopicsilic
               Pneumonoultramicroscopicsilico
              Pneumonoultramicroscopicsilicov
             Pneumonoultramicroscopicsilicovo
            Pneumonoultramicroscopicsilicovol
           Pneumonoultramicroscopicsilicovolc
          Pneumonoultramicroscopicsilicovolca
         Pneumonoultramicroscopicsilicovolcan
        Pneumonoultramicroscopicsilicovolcano
       Pneumonoultramicroscopicsilicovolcanoc
      Pneumonoultramicroscopicsilicovolcanoco
     Pneumonoultramicroscopicsilicovolcanocon
    Pneumonoultramicroscopicsilicovolcanoconi
   Pneumonoultramicroscopicsilicovolcanoconio
  Pneumonoultramicroscopicsilicovolcanoconios
 Pneumonoultramicroscopicsilicovolcanoconiosi
Pneumonoultramicroscopicsilicovolcanoconiosis
neumonoultramicroscopicsilicovolcanoconiosis
eumonoultramicroscopicsilicovolcanoconiosis
umonoultramicroscopicsilicovolcanoconiosis
monoultramicroscopicsilicovolcanoconiosis
onoultramicroscopicsilicovolcanoconiosis
noultramicroscopicsilicovolcanoconiosis
oultramicroscopicsilicovolcanoconiosis
ultramicroscopicsilicovolcanoconiosis
ltramicroscopicsilicovolcanoconiosis
tramicroscopicsilicovolcanoconiosis
ramicroscopicsilicovolcanoconiosis
amicroscopicsilicovolcanoconiosis
microscopicsilicovolcanoconiosis
icroscopicsilicovolcanoconiosis
croscopicsilicovolcanoconiosis
roscopicsilicovolcanoconiosis
oscopicsilicovolcanoconiosis
scopicsilicovolcanoconiosis
copicsilicovolcanoconiosis
opicsilicovolcanoconiosis
picsilicovolcanoconiosis
icsilicovolcanoconiosis

致谢

多亏了dzaimaLeaky NunXcoder先生完成了本次挑战的所有构想。


1
是否必须包含右下角的空格三角形?
瑕疵

1
@flawr OP:可以
ADAM

Answers:



5

MATL,8字节

nXyPGZ+c

在线尝试!

说明

n    % Implicit input. Number of elements
Xy   % Identity matrix of that size
P    % Flip vertically
G    % Push input again
Z+   % 2D convolution, maintaining size
c    % Convert to char (char 0 is displayed as space). Implicitly display

1
谁以为我想要这个答案:D
虚张声势

1
@flawr是的,谁又能想到
路易斯Mendo

4

视网膜70 59字节

.
$.'$* $_$.`$* ¶
(?=((....))+)(?<-1>.)+(.*?)(?<-2>.)+¶
$3¶

在线尝试!编辑:@MartinEnder提供了一些帮助,保存了11个字节。说明:第一阶段为每个字符重复一次输入,将其适当地填充在每行上以获得剪切。然后,最后阶段从每一侧去除25%的光,以产生所需的结果。


我想我早些时候有59岁。现在没有时间去挖掘细节,但是基本上在第一阶段,我只是在输入上填充了n/2左右的空格(使用(..)+.->等$#1$* $&$#1$*带有尾随空格的空格),然后执行了一个与字符完全匹配的!&`...地方。...nn
Martin Ender

您的方法至少可以缩短为63:tio.run/##K0otycxL/…
Martin Ender

@MartinEnder谢谢,我又打了4个字节!
尼尔

您需要第二个$*sp吗?
CalculatorFeline

@CalculatorFeline是的,我需要所有行都具有相同的长度,因此我可以将其除以4。–
Neil

3

爪哇8,120个 103字节

s->{int l=s.length(),i=l/2;for(;i-->0;s=" "+s+" ");for(;++i<l;System.out.println(s.substring(i,l+i)));}

-17个字节,感谢@OlivierGrégoire

说明:

在这里尝试。

s->{                      // Method with String parameter and no return-type
  int l=s.length(),       //  Length of the input-String
      i=l/2;              //  Temp index-integer (starting at halve the length floored)
  for(;i-->0;             //  Loop (1) from `l/2` to 0 (exclusive)
    s=" "+s+" "           //   Add spaces before and after the input-String
  );                      //  End of loop (1)
                          //  (If the input was "World", it is now "  World  ")
  for(;++i<l;             //  Loop (2) from 0 to `l` (exclusive)
    System.out.println(   //   Print:
      s.substring(i,      //    Substring of the modified input from `i`
                    l+i)  //    to `l+i` (exclusive)
    )                     //   End of print
  );                      //  End of loop (2)
}                         // End of method

i=l/2+1i-->1for(;i<l保存一个字节。
OlivierGrégoire'7

1
而且...完全打高尔夫球:s->{int l=s.length(),i=l/2;while(i-->0)s=" "+s+" ";while(++i<l)System.out.println(s.substring(i,l+i));}(103个字节)。唯一的重大变化是,带有空格的字符串是一次性生成的,而不是“即时”生成的(当然是打印而不是返回)。
OlivierGrégoire'7

3

Haskell,64 62字节

f s|l<-length s=take l$take l<$>scanr(:)""(([2,4..l]>>" ")++s)

在线尝试! 怎么运行的:

l<-length s               -- let l be the length of the input string

      ([2,4..l]>>" ")     -- take l/2 spaces and
                     ++s  -- append s
    scanr(:)""            -- make a list of the inits of the above string, e.g.
                          -- "  world" -> ["  world"," world","world","orld"...]
  take l <$>              -- take the first l chars of each string
take l                    -- and the first l strings

3

SWI Prolog,234个字节

h(_,0,_,_,[]).
h(T,N,S,L,[H|U]):-sub_string(T,S,L,_,H),M is N-1,A is S+1,h(T,M,A,L,U).
s(T,R):-string_length(T,L),findall('_',between(1,L,_),A),string_chars(B,A),
                   string_concat(B,T,C),string_concat(C,B,D),S is L-((L-1)/2),h(D,L,S,L,R).

也许可以在这里在线尝试:http : //swish.swi-prolog.org/p/hEKigfEl.pl

注意

  1. 最后一行是一条长行,我在此处添加了一个换行符和空格,以避免在此答案中出现水平滚动条。
  2. 这个问题涉及填充空间,但是由于HTML呈现交互作用,Swish Online不能干净地显示它们,因此您必须在浏览器开发工具中查看源以检查它们是否存在。我将填充更改为_此处,因为它演示了它的工作原理,并且不影响字节数。

在Swish中运行的示例:

测试用例

方法,基本上,我可以做的第一件事,毫无疑问,熟练的Prolog用户可以大大缩短工作时间:

  • 给定一个长度为L的字符串,输出将有L行,每行将有L个字符长,因此'L'出现很多。从L到0倒数表示行数,L表示每行的子串长度。
  • 创建一个长度为L个空格(下划线)的填充字符串,并将其添加到输入字符串的两端,因为这是一个简单的长度,因此绝对足够填充。
  • 计算此三倍长度字符串的起始偏移量,然后递归,每次生成一个子字符串,然后进入结果列表。

说明和注释的代码(可能无法运行),从superacrostic()下往上阅读,然后是helper()主体,然后是helper()基本情况:

% helper function recursive base case, 
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]). 



% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-

    sub_string(Text, Offset, LineLength, _, Head),    % The list Head matches
                                                      % a substring of Text starting 
                                                      % from Offset, of LineLength chars 
                                                      % and

    NextCounter is Counter-1,                         % decrement the Counter

    NextOffset is Offset+1,                           % increment the offset

    helper(Text, NextCounter, NextOffset, LineLength, Tail).  % Recurse for list Tail



% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
    string_length(Text, Length),                   % Length is length of input, 
                                                   % Text = 'ABXCD', Length = 5
                                                   % and

    findall('_',between(1,Length,_),PaddingList),  % PaddingList is a list of padding
                                                   % chars Length items long, 
                                                   % ['_', '_', '_', '_', '_']
                                                   % and

    string_chars(PaddingString, PaddingChars),     % PaddingString is the string from 
                                                   % joining up that list of chars
                                                   % '_____'
                                                   % and

    string_concat(PaddingString, Text, Temp),      % Temp is Text input with a
                                                   % padding prefix
                                                   % Temp = '_____ABXCD'
                                                   % and

    string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with 
                                                    % a padded suffix
                                                    % Temp = '_____ABXCD_____'
                                                    % and


    S is Length - ((Length - 1) / 2),              % Starting offset S for the substring
                                                   % is just past the padding,
                                                   % then half the input length back
                                                   % '_____ABXCD_____'
                                                   %     |
                                                   % to start the first line,
                                                   % and


    helper(PaddedText, Length, S, Length, Result). % Result is the list generated from 
                                                   % the helper function, 

    % to recurse Length times for that many output rows, S starting offset, 
    % Length linelength, and Result 'output'.

2

05AB1E,11个字节

g;úIvDIg£,À

在线尝试!

说明

g;ú           # prepend len(input)/2 spaces to input
   Iv         # for each char of input do
     D        # duplicate current string
      Ig£     # take the first len(input) chars
         ,    # print
          À   # rotate the string to the left


2

APL(Dyalog Unicode),10个字符= 22个字节

{⊢⌺(≢⍵)⊢⍵}

在线尝试!

{} 匿名函数,其中的参数由represented表示

 提供覆盖区域

⌺() 滑动尺寸的模板

   的长度

   论点

 上

 论点

这种工作方式是通过让每个字符形成一个字符串中间的字符串,该字符串的长度与输入的长度相同,并根据需要向左或向右填充。以例如ABXCD

该字符串包含五个字符,因此模板将具有五个字符宽的“开口”。

┌──↓──┐     与中间标记模版开口
│ ABX│CD   让A在中间
 │ ABXC│D   然后B
  │ABXCD|   等
  A|BXCD | 
  AB|XCD  |
    └──↑──┘ 最终模版位置



2

JavaScript(ES8),66 63 62字节

返回一个数组。

s=>[...s].map((_,x)=>s.padStart(l*1.5).substr(x,l),l=s.length)

试试吧

o.innerText=(f=
s=>[...s].map((_,x)=>s.padStart(l*1.5).substr(x,l),l=s.length)
)(i.value="Pneumonoultramicroscopicsilicovolcanoconiosis").join`\n`;oninput=_=>o.innerText=f(i.value).join`\n`
<input id=i><pre id=o>


说明

s=>

匿名函数,通过参数将字符串作为参数s

[...s]

将字符串拆分为单个字符的数组。

l=s.length

获取字符串的长度并将其分配给variable l

.map((_,x)=>                                        )

在数组上映射,将每个元素传递给一个函数,其中x是当前元素的索引。

s.padStart(l*1.5)

对于每个元素,返回带有空格的原始字符串,直到其长度是其原始长度的1.5倍。

.substr(x,l)

获取l从当前元素的索引开始的长度的子字符串。


2

V14,11字节

òlÙxHÄ$x>>ê

在线尝试!

感谢@nmjmcman,节省了3个字节!

十六进制转储:

00000000: f26c d978 48c4 2478 3e3e ea              .l.xH.$x>>.

原始方法(18字节):

ø..
Duu@"ñLÙxHÄ$x>

说明:

ò           " Recursively:
 l          "   Move one char to the right (this will break the loop if we move too far
  Ù         "   Duplicate this line down
   x        "   Delete the first character on this line
    H       "   Move to the first line
     Ä      "   Duplicate this line up
      $     "   Move to the end of this line
       x    "   And delete a character
        >>  "   Put one space at the beginning of this line
          ê "   And move to this column on the last line
            " (implicit) ò, end the loop.

保存几个字节:在线尝试!
nmjcman101

@ nmjcman101啊,天才!我完全忘记了ê。谢谢:)
DJMcMayhem

2

PowerShell核心,68个字节

0..($L=($a="$args").Length-1)|%{-join(' '*($L/2)+$a)[($_..($_+$L))]}

在线尝试!

空洞的解释

# Input string ABXCD
# -> indexes  0,1,2,3,4  string indexing and num of output lines.
# -> Pad with half-len of spaces __ABXCD.
# -> sliding window array of chars:
# __ABXCD
# |    |       0..4
#  |    |      1..5
#   |    |     2..6
#    |    |    3..7   (selecting indexes past the end returns $nulls, no error)
#     |    |   4..8

# joining those chars into a line


$Text = "$args"                            # script args array to string.
$L    = $Text.Length - 1                   # useful number

$Offsets = 0..$L                           # range array 0,1,2,3,.. to last offset

$Offsets | ForEach-Object {                # Offsets doubles as number of output lines

    $LinePadding = ' ' * ($L / 2)          # lead padding string __
    $PaddedText  = $LinePadding + $Text    # -> __ABXCD

    $Chars = $_..($_+$L)                   # windows 0..4, then 1..5, then 2..6, etc.
    $Line  = $PaddedText[$Chars]           #_,_,A,B,X then _,A,B,X,C then A,B,X,C,D etc.

    -join $Line                            # __ABX  then _ABXC then ABXCD etc.

}

1
关心取消加入的资格[($_..($_+$L))]

@root简短答案,这(与连接不相关,它是-join ($Padding + $Text)[0,1,2,3,4]从填充字符串中为输出行选择几个字符,然后将它们连接到字符串中,这是一种较短的方法.SubString()。并就地生成填充和就地字符范围。完整的非高尔夫解释添加到了我的答案中。
TessellatingHeckler

2

杰普特19 17 14字节

@ETHproductions和@Shaggy节省了5个字节

¬£iSp½*Ul¹tYUl

在线测试! -R添加标记以与换行符结合(可见性)

说明

¬£iSp½*Ul¹tYUl
                U = Implicit input
¬               Split the input into an array of chars
 £              Map; At each char:
  i               Insert:
   S                Space " "
    p               repeated(
     ½*Ul           .5 * U.length times 
         ¹          )
          t        Substring(
           Y         Index,
            Ul       U.length) 

1
应该有一个更短的生成方式Sp½*Ul,但我不认为这是一个自动取款机......顺便说一句,你通常可以改变sXX+Y,以tXYs == .slicet == .substr
ETHproductions

@ETHproductions哦,是的,谢谢!
奥利弗(Oliver)


或者,看到允许返回一个数组,为14个字节
毛茸茸的


1

果冻,11字节

LH⁶ẋ;ṫJḣ€LY

在线尝试!

怎么运行的

LH⁶ẋ;ṫJḣ€LY   "ABXCD"
L             5
 H            2.5
  ⁶ẋ          "  "
    ;         "  ABXCD"
     ṫJ       ["  ABXCD"
               " ABXCD"
               "ABXCD"
               "BXCD"
               "XCD]
        ḣ€L   ["  ABX"
               " ABXC"
               "ABXCD"
               "BXCD"
               "XCD]
           Y  "  ABX
                ABXC
               ABXCD
               BXCD
               XCD"

1

QBIC,32字节

_L;|A=space$(a'\`2)+A[a|?_sA,b,a    

伙计,现在是我加入space$QBIC 的时候了...

说明

  ;             Read a cmd line parameter as A$
_L |            And take its length as 'a'
A=space$        Set A$ to a number of spaces
(a'\`2)           equal to its own length halved
+A                prepended to itself
[a|             FOR b= 1 to the length of A$
?_sA,b,a        Print a substring of our space-padded A$, starting at the b'th character, running for a chars

样品运行

Command line: acknowledgement
       acknowle
      acknowled
     acknowledg
    acknowledge
   acknowledgem
  acknowledgeme
 acknowledgemen
acknowledgement
cknowledgement
knowledgement
nowledgement
owledgement
wledgement
ledgement
edgement

1

Mathematica,88个字节

T=Table;Column@Reverse@T[T[" ",i]<>StringDrop[s=#,-i],{i,d=-⌊StringLength@s/2⌋,-d}]&

1

哈斯克尔86) 70字节

(仍然)时间太长,但是感谢@bartavelle提醒我,输出字符串列表也是可以的!

f s|m<-div(length s)2=take(2*m+1).(`drop`((*>)s" "++s))<$>[m+1..3*m+1]

在线尝试!


我只能达到82:在线尝试!
bartavelle

@bartavelle看起来不太正确。您的右侧没有被切碎。
亚当

是的,我介绍了一个错误!您可以放下concat来获得一些好处:在线试用!
bartavelle

斩波为84,使您的方法更好!在线尝试!
bartavelle

而且,您可以节省更多,因为您不需要返回单个字符串,字符串列表也可以!
bartavelle


1

PowerShell133119字节

$a="$args";$L=$a.Length;$m=($L+1)/2;$s=" "*($m-1)+$a+" "*($m-1);for($h=0;$h-lt$L;$h++){$r="";0..$L|%{$r+=$s[$_+$h]};$r}

在线尝试!

不打高尔夫球

$a="$args"
$L=$a.Length                        # the length of the input
$m=($L + 1) / 2                     # the midpoint of the input
$s=" " * ($m-1) + $a + " " * ($m-1) # create a string using the input and padded on both sides with spaces

for($h=0;$h -lt $L;$h++) {          # the height, matching the length of the input
    $r=""                           # init/reset the output string

    0..$L | % {                     # number range to represent each character in the string
        $r+=$s[$_+$h]               # append the output string with the next character
    }

    $r                              # write the output
}

1
好答案!欢迎来到该网站。:)
DJMcMayhem

1

Python 276 74 73字节

-1感谢@FelipeNardiBatista

当然,不如其他Python回答那么短,但是值得尝试一种完全不同的方法:

n=input();x=len(n)
for i in range(x):print((2*x-~i)*' '+n)[x+x/2:2*x+x/2]

在线尝试!(使用74字节版本)

这首先生成完整的String,然后将其切成合适的正方形。


说明

n = input(); -接受输入并将其分配给变量n
          x = len(n)-将输入的长度分配给变量x
对于范围(x)中的i:-使用变量i迭代范围0 ... x
                   打印-输出结果
                         ((2 * xi-1)*''+ n)-创建“钻石”字符串
                                          [x + x / 2:2 * x + x / 2]-裁剪字符串以适合框

(2*x+~i)保存一个字节
Felipe Nardi Batista

@FelipeNardiBatista谢谢。

1

J,19个字节

|.!.' '"{~2%~#\-#\.

在线尝试!

说明

|.!.' '"{~2%~#\-#\.  Input: string S
             #\      Length of each prefix of S, [1, 2, ..., len(S)]
                #\.  Length of each suffix of S, [len(s), ..., 2, 1]
               -     Subtract elementwise
          2%~        Divide by 2
                     We now have a range [(1-len(S))/2, ..., -1, 0, 1, ..., (len(S)-1)/2]
       "{~           Use each value to operate on S
|.!.' '                Perform a shift while replacing characters with ' '

''作为替代品。
FrownyFrog

0

C#(.NET Core),101字节

(a)=>{int L=a.Length,l=L/2;for(;l-->0;)a=" "+a+" ";for(;++l<L;)Console.WriteLine(a.Substring(l,L));};

基本上是@KevinCruijssen的答案。保存2个字节,因为string.Length不需要(),另外2个字节,因为的第二个参数string.Substring()是length而不是end Index,但是由于Console.WriteLine()更长而丢失2个字节。我有一个更幼稚的实现,但是大约是它的两倍...


0

Excel VBA,68字节

打高尔夫球

匿名VBE立即窗口功能,它从单元格获取输入[A1]并输出到VBE立即窗口

l=[Len(A1)]:For i=Int(-l/2)+2To l/2+1:?Mid(Space(l-i)&[A1],l,l):Next

不打高尔夫球

Sub C(ByVal s As String)
    Let l = Len(s)
    For i = Int(-l / 2) + 2 To l / 2 + 1 Step 1
        Debug.Print Mid(Space(l - i) & s, l, l)
    Next i
End Sub

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.