슈퍼 곡예 만들기


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 │
      └─────┘
       CD
       디
    
  • 마지막으로 경계 상자 안에있는 것만 반환합니다.

      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 , Leaky Nun , Xcoder 씨에게이 도전에 대한 아이디어를 제외한 모든 것에 감사합니다 .


1
오른쪽 하단의 공백이 포함되어야합니까?
flawr

1
@flawr 영업 이익 : 수도
아담

답변:




4

망막 , 70 59 바이트

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

온라인으로 사용해보십시오! 편집 : @MartinEnder의 도움으로 11 바이트를 저장했습니다. 설명 : 첫 번째 단계는 각 문자에 대해 입력을 한 번 반복하여 각 행에 적절하게 채워서 전단을 얻습니다. 그런 다음 마지막 단계에서 각면에서 25 %를 제거하여 원하는 결과를 얻습니다.


나는 59 이전에 생각했다. 지금 세부 사항을 파헤칠 시간이 없지만 본질적으로 첫 번째 단계에서는 입력을 n/2왼쪽과 오른쪽 으로 공백으로 채우고 ( (..)+.> $#1$* $&$#1$*와 같이 후행 공백으로) 패딩 한 다음 정확히 문자 와 일치 하는 !&`...위치를 수행했습니다 . ...nn
마틴 엔더


@MartinEnder 고마워, 나는 또 다른 4 바이트를 골프했습니다!
Neil

두 번째가 필요 $*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)));}

@ 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+1i-->1for(;i<l바이트를 저장합니다.
Olivier Grégoire

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 바이트). 유일한 중요한 변화는 공백이있는 문자열이 "즉시"대신 (그리고 물론 반환 대신 인쇄) 한 번에 생성된다는 것입니다.
Olivier Grégoire

3

하스켈, 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. 마지막 줄은 하나의 긴 줄입니다.이 대답에서 가로 스크롤 막대를 피하기 위해 줄 바꿈과 공백을 추가했습니다.
  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

자바 스크립트 (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

V , 14 , 11 바이트

òlÙxHÄ$x>>ê

온라인으로 사용해보십시오!

@nmjmcman 덕분에 3 바이트가 절약되었습니다!

16 진 덤프 :

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

@root 짧은 대답, (조인과 함께 -join ($Padding + $Text)[0,1,2,3,4]가지 않고 출력 줄을 위해 채워진 문자열에서 여러 문자를 선택하고 더 짧은 방법으로 문자열에 조인합니다 .SubString(). 그리고 그 자리에 패딩과 문자 범위를 생성합니다. 내 대답에 전체 ungolf 설명이 추가되었습니다.
TessellatingHeckler

2

apt , 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하지만, 한 가지 ATM이 있다고 생각하지 않습니다 ... BTW, 일반적 sXX+Y으로 tXY( s == .slice, t == .substr)로 변경할 수 있습니다
ETHproductions

@ETHproductions 예, 감사합니다!
Oliver


또는 배열을 반환하는 것으로 허용되는 경우 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

수학, 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 그건 옳지 않아. 오른쪽이 잘리지 않습니다.
Adám

네, 버그를 소개했습니다! 당신은 당신의 연결을 삭제하여 조금 얻을 수 있습니다 : 온라인 사용해보십시오!
bartavelle

그리고 잘게 자르면 84로 접근 방식이 향상됩니다! 온라인으로 사용해보십시오!
bartavelle

단일 문자열을 반환 할 필요가 없으므로 문자열 목록도 괜찮습니다.
bartavelle


1

PowerShell , 133119 바이트

$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

파이썬 2 ,76 74 73 바이트

@FelipeNardiBatista 덕분에 -1

물론 다른 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 = 입력 (); -입력을 받아서 변수 n에 할당
          x = len (n)-입력 길이를 변수 x에 대입
범위 (x)의 i의 경우 :-변수 i를 사용하여 범위 0 ... x에서 반복
                   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 코어) , 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 바이트를 절약 하고 두 번째 인수 string.Substring()가 end Index가 아닌 길이 이므로 2 바이트를 절약 한 다음 Console.WriteLine()더 길기 때문에 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.