Сделать супер акростих


35

Задний план

Празднование выпуска Dyalog APL 16.0 , где решением этой проблемы является {⊢⌺(≢⍵)⊢⍵}Объяснение

задача

Если задана печатаемая строка ASCII нечетной длины n , сделайте квадрат размером 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
       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 , Leaky Nun , Mr. Xcoder за все, кроме самой идеи этого вызова.


1
Должен ли быть включен пробел в правом нижнем углу или нет?
flawr

1
@flawr OP: май
Адам

Ответы:



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
flawr

1
@flawr Да, кто бы мог подумать
Луис Мендо

4

Retina , 70 59 байт

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

Попробуйте онлайн! Редактировать: Сохранено 11 байтов с некоторой помощью @MartinEnder. Объяснение: Первый этап повторяет ввод один раз для каждого символа, дополняя его соответствующим образом в каждой строке, чтобы получить сдвиг. Последняя стадия затем удаляет 25% с каждой стороны, чтобы получить желаемый результат.


Я думаю, у меня было 59 раньше. Сейчас у меня нет времени копать детали, но по сути на первом этапе я просто заполнил ввод n/2пробелами влево и вправо (используя что-то вроде (..)+.-> $#1$* $&$#1$*с завершающим пробелом), а затем просто сделал, !&`...где ...совпадения nточно совпадают с nсимволами.
Мартин Эндер

Ваш подход может быть сокращен до 63: tio.run/##K0otycxL/…
Мартин Эндер,

@MartinEnder Спасибо, и я отыграл еще 4 байта!
Нил

Вам нужен второй $*sp?
CalculatorFeline

@CalculatorFeline Да, мне нужно, чтобы все строки были одинаковой длины, поэтому я могу разделить их на 4.
Нил

3

Java 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+1и i-->1и for(;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. Последняя строка - одна длинная строка, я добавил здесь разрыв строки и пробелы, чтобы избежать горизонтальной полосы прокрутки в этом ответе.
  2. Вопрос касается пробелов для отступов, но Swish онлайн не показывает их из-за взаимодействий при рендеринге HTML, вы должны просмотреть исходный код в инструментах разработчика браузера, чтобы убедиться, что они присутствуют (они есть). Я изменил заполнение, чтобы оно было _здесь, так как оно демонстрирует, что оно работает и не влияет на количество байтов.

Примеры работы на 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

APL (Dyalog Unicode) , 10 символов = 22 байта

{⊢⌺(≢⍵)⊢⍵}

Попробуйте онлайн!

{} Анонимная функция, где аргумент представлен

 предоставить покрытую площадь, когда

⌺(... ) трафарет размера

   длина

   Аргумент

 на

 Аргумент

Это работает, позволяя каждому символу образовывать середину строки с той же длиной, что и ввод, с заполнением влево или вправо по мере необходимости. Взять например ABXCD:

Строка имеет пять символов, поэтому трафарет будет иметь «отверстие» шириной пять символов.

┌──↓──┐     Трафарет отверстие со средним маркером
│ ABX│CD   LET 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

Получить длину строки и назначить ее переменной l.

.map((_,x)=>                                        )

Карта по массиву, передавая каждый элемент через функцию, где xнаходится индекс текущего элемента.

s.padStart(l*1.5)

Для каждого элемента возвращайте исходную строку с пробелами в начале, пока ее длина не будет в 1,5 раза больше ее исходной длины.

.substr(x,l)

Получить подстроку длины, lначиная с индекса текущего элемента.


2

V , 14 , 11 байтов

òlÙxHÄ$x>>ê

Попробуйте онлайн!

3 байта сохранены благодаря @nmjmcman!

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

@ nmjcman101 Ах, это гений! Я полностью забыл о ê. Спасибо :)
DJMcMayhem

2

PowerShell Core , 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(). и он генерирует заполнение на месте и диапазон символов на месте. К моему ответу добавлено полное объяснение негольфом.
TessellatingHeckler

2

Japt , 19 17 14 байтов

Сохранено 5 байтов благодаря @ETHproductions и @Shaggy

¬£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на tXY( s == .slice, t == .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

Хаскелл , 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 Это выглядит не так. Ваша правая сторона не порезана.
Адам

Да, я представил ошибку! Вы можете немного выиграть, бросив свой конкат: попробуйте онлайн!
bartavelle

И с рубкой это 84, делая ваш подход лучше! Попробуйте онлайн!
bartavelle

И вы можете сэкономить гораздо больше, потому что вам не нужно возвращать одну строку, списки строк тоже в порядке!
bartavelle


1

PowerShell , 133 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}

Попробуйте онлайн!

Ungolfed

$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 2 ,76 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
          x = len (n) - назначает длину ввода переменной x
для i в диапазоне (x): - повторяется в диапазоне 0 ... x с переменной i
                   print - выводит результат
                         ((2 * xi-1) * '' + n) - создает строку "diamond"
                                          [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. Экономит 2 байта, потому чтоstring.Length что не нужно (), и еще 2 байта, потому что вторым аргументом string.Substring()является длина, а не конец индекса, но затем теряется 2 байта, потому что Console.WriteLine()он длиннее. У меня была более наивная реализация, но она была вдвое длиннее, так что ...


0

Excel VBA, 68 байт

Golfed

Функция анонимного непосредственного окна VBE, которая принимает входные данные из ячейки [A1]и выводит их в непосредственное окно VBE

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

Ungolfed

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.