Зробіть супер акростик


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 , містеру Xcoder за все, крім самої ідеї цього виклику.


1
Чи потрібно включати пробіли-трикутники праворуч внизу чи ні?
недолік

1
@flawr OP: травень
Adám

Відповіді:



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 Так, хто міг би подумати
Луїс Мендо

4

Сітківка , 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 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

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   нехай 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 коротка відповідь, що (не йде з приєднанням, це -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, але я не думаю, що є один атм ... BTW, зазвичай можна змінити 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

Математика, 88 байт

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

1

Haskell , 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}

Спробуйте в Інтернеті!

Безумовно

$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 байти

-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 = вхід (); - приймає введення та присвоює йому змінну n
          x = len (n) - призначає довжину введення змінній x
для i в діапазоні (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. Зберігає 2 байти, тому string.Lengthщо не потрібен () та ще 2 байти, оскільки другий аргумент - string.Substring()це довжина, а не кінцевий індекс, але потім втрачає 2 байти, оскільки Console.WriteLine()довший. Я мав більш наївну реалізацію, але це було приблизно вдвічі довше ...


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.