超アクロスティックを作る


35

バックグラウンド

この問題の解決策が説明されているDyalog APL 16.0のリリースを祝う{⊢⌺(≢⍵)⊢⍵}

仕事

奇数の長さ nの印刷可能なASCII文字列を指定すると、文字列を水平方向に中央揃え、垂直方向に中央揃えに複製し、各行と列に同じ文字列のアクロスティックを含むn × nの正方形を作成します。正方形のサイズn × nを維持するために、中央にある文字列以外はすべて切り取られることに注意してください。

コードの説明は大歓迎です。

ルール

  1. 末尾に空白と改行がある場合があります(これには右下の三角形が含まれます)
  2. 文字列のリストを返すことがあります

文字列を使用した例ABXCD

  • nは5です。最初に、1つの水平方向と1つの垂直方向の2つの中心の文字列を描画します。

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

    (明確にするために5×5の境界ボックスが追加されました)

  • 次に、可能なすべてのアクロスティックを水平および垂直に配置します。

           A
          AB
      ┌─────┐┐
      │ABX│CD
      │ABXC│D
      │ABXCD│
     A│BXCD│
    AB│XCD│
      └─────┘┘
       CD
       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

謝辞

おかげdzaima漏れ修道女氏Xcoderすべてが、この挑戦の非常にアイデアのために。


1
右下のスペーストライアングルを含める必要がありますか?
-flawr

1
@flawrのOP:かもしれない
アダム・

回答:




4

網膜70 59バイト

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

オンラインでお試しください!編集:@MartinEnderの助けを借りて11バイトを保存しました。説明:最初の段階では、各文字に対して入力を1回繰り返し、各行に適切にパディングして、せん断を取得します。最後の段階では、各側から25%を削除して、望ましい結果を生成します。


私は以前59歳だったと思います。今すぐ詳細を掘り下げる時間はありませんが、基本的には最初の段階で、入力にn/2左右のスペースを埋めて((..)+.->のようなものを使用$#1$* $&$#1$*して末尾のスペースを付けます)、ちょうど文字が正確!&`......一致する場所を実行しました。nn
マーティンエンダー

あなたのアプローチは少なくとも63に短縮できます:tio.run
Martin Ender

@MartinEnderありがとう
ニール

2番目が必要$*spですか?
電卓

@CalculatorFelineはい、すべての行を同じ長さにする必要があるため、4で割ることができます。-
ニール

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)));}

@OlivierGrégoireのおかげで-17バイト。

説明:

ここで試してみてください。

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+1そして、バイトi-->1for(;i<l保存します。
オリビエグレゴワール

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バイト)。唯一の重要な変更点は、スペースを含む文字列が「オンザフライ」ではなく一度だけ生成されることです(もちろん、返される代わりに印刷されます)。
オリビエグレゴワール

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プロローグ、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

NB。

  1. 最後の行は1つの長い行です。この回答で水平スクロールバーを避けるために、ここに改行とスペースを追加しました。
  2. 質問にはパディングのためのスペースが含まれますが、Swish onlineはHTMLレンダリングインタラクションのためにそれらをきれいに表示しません。ブラウザ開発ツールでソースを表示してそれらが存在することを確認する必要があります。_ここでパディングを変更しました。これは、パディングが機能することを示しており、バイトカウントには影響しません。

Swishで実行する例:

テストケース

アプローチ、基本的に私が最初に仕事をすることができる最初のこと、そして間違いなく熟練したPrologユーザーはそれを大幅に短縮することができました:

  • 長さLの文字列を指定すると、出力にはL行が含まれ、各行はL文字長になるため、「L」が多く表示されます。行数の場合はLから0へのカウントダウン、各行の部分文字列の長さはL。
  • Lスペース(アンダースコア)の長さのパディング文字列を作成し、入力文字列の両端に追加します。これは単純な長さで、十分なパディングになります。
  • この3倍長文字列への開始オフセットを計算し、再帰して、毎回部分文字列を生成し、結果のリストにします。

コードの説明とコメント(実行されない場合があります)、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

APL(Dyalog Unicode)、10文字= 22バイト

{⊢⌺(≢⍵)⊢⍵}

オンラインでお試しください!

{... } 引数が表され匿名関数

 覆われた領域を提供するとき

⌺() サイズのステンシルをスライドさせる

   の長さ

   引数

 に

 引数

これが機能する方法は、各文字が入力と同じ長さの文字列の中央を形成し、必要に応じて左または右にパディングすることです。例ABXCD

文字列には5文字があるため、ステンシルの幅は5文字です。

┌──↓──┐     中央のマーカーとのステンシル開口部を
│ 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=>

parameterを介して引数として文字列を受け取る匿名関数s

[...s]

文字列を個々の文字の配列に分割します。

l=s.length

文字列の長さを取得し、変数に割り当てますl

.map((_,x)=>                                        )

配列にマッピングし、各要素を関数に渡しxます。現在の要素のインデックスです。

s.padStart(l*1.5)

各要素について、長さが元の長さの1.5倍になるまでスペースを前に付けた元の文字列を返します。

.substr(x,l)

l現在の要素のインデックスから始まる長さの部分文字列を取得します。


2

V14、11のバイト

òlÙxHÄ$x>>ê

オンラインでお試しください!

@nmjmcmanのおかげで3バイト節約されました!

Hexdump:

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ああ、それは天才だ!私は完全に忘れていましたê。ありがとう:)
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

Japt19 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そうそう、ありがとう!
オリバー


または、14バイトの配列を返すことが許可されています
シャギー



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

Haskell86 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

さらに、1つの文字列を返す必要がないため、さらに節約できます。文字列のリストも問題ありません。
-bartavelle


1

PowerShell133 119バイト

$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バイトバージョン)

これは最初に完全な文字列を生成し、次に正方形に合うようにそれをスライスします。


説明

n = input(); -入力を受け取り、変数nに割り当てます
          x = len(n)-入力の長さを変数xに割り当てます
for i in range(x):-範囲0 ... xを変数iで繰り返します
                   print-結果を出力します
                         ((2 * xi-1)* '' + n)-「ダイヤモンド」文字列を作成します
                                          [x + x / 2:2 * x + x / 2]-ボックスに収まるように文字列をトリミングします

(2*x+~i)バイトを保存するには
フェリペナルディバティスタ

@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の答え。string.Length()を必要としないため2バイトを節約し、2番目の引数はstring.Substring()endインデックスではなく長さであるため、さらに2バイトを節約しますが、Console.WriteLine()より長いため2バイトを失います。私はもっ​​と素朴な実装をしましたが、それは約2倍の長さでした...


0

Excel VBA、68バイト

ゴルフ

セルから入力を受け取り[A1]、VBEイミディエイトウィンドウに出力する匿名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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.