Faire un super acrostic


35

Contexte

Célébration de la publication de Dyalog APL 16.0 , où la solution à ce problème est {⊢⌺(≢⍵)⊢⍵}Explication

Tâche

Avec une chaîne ASCII imprimable de longueur impaire n , créez un carré n × n avec la chaîne centrée horizontalement, dupliquée pour être centrée verticalement et avec des acrostiches de la même chaîne dans chaque ligne et colonne. Notez que toutes les chaînes sauf les chaînes centrées seront coupées pour conserver la taille du carré n × n .

L'explication de votre code sera très appréciée.

Règles

  1. Vous pouvez avoir des espaces et des nouvelles lignes à la fin (cela inclut le triangle inférieur droit)
  2. Vous pouvez retourner une liste de chaînes

Exemple utilisant la chaîne ABXCD:

  • n est 5. On commence par dessiner les deux chaînes centrées, l'une horizontale et l'autre verticale:

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

    (5 × 5 cadre de sélection ajouté pour plus de clarté)

  • Ensuite, nous plaçons tous les acrostiches possibles, horizontalement et verticalement:

           UNE
          UN B
      ┌─────┐
      │ ABX│CD
      │ ABXC│D
      │ABXCD│
     A│BXCD │
    AB│XCD │
      └─────┘
       CD
       ré
    
  • Enfin, nous ne renvoyons que ce qui se trouve à l'intérieur du cadre de sélection:

      ABX
     ABXC
    ABXCD
    BXCD 
    XCD  
    

Cas de test

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

Remerciements

Merci à dzaima , Leaky Nun , à M. Xcoder pour tout sauf l’idée même de ce défi.


1
Les espaces en bas à droite doivent-ils être inclus ou non?
Flawr

1
@flawr OP: mai
Adám

Réponses:



5

MATL , 8 octets

nXyPGZ+c

Essayez-le en ligne!

Explication

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
Qui a pensé que j'aimerais cette réponse: D
flawr

1
@flawr Oui, qui aurait pensé
Luis Mendo

4

Retina , 70 59 octets

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

Essayez-le en ligne! Edit: 11 octets enregistrés avec l’aide de @MartinEnder. Explication: La première étape répète l'entrée une fois pour chaque caractère, en la complétant correctement sur chaque ligne pour obtenir le cisaillement. La dernière étape supprime ensuite 25% de chaque côté pour produire le résultat souhaité.


Je pense que j'avais 59 ans plus tôt. Vous n’avez pas le temps de détailler les détails maintenant, mais lors de la première étape, j’ai simplement rempli l’entrée avec des n/2espaces à gauche et à droite (en utilisant quelque chose comme (..)+.-> $#1$* $&$#1$*avec un espace de fin) et en faisant juste un !&`......correspond nexactement aux ncaractères.
Martin Ender

Votre approche peut au moins être réduite à 63: tio.run/##K0otycxL/…
Martin Ender

@MartinEnder Merci, et j'ai encore joué 4 octets au golf!
Neil

Avez-vous besoin de la seconde $*sp?
CalculatriceFeline

@CalculatorFeline Oui, j'ai besoin que toutes les lignes aient la même longueur pour pouvoir la diviser par 4.
Neil

3

Java 8, 120 103 octets

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 octets grâce à @ OlivierGrégoire .

Explication:

Essayez ici.

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+1et i-->1et for(;i<léconomisez un octet.
Olivier Grégoire

1
Et ... totalement joué au golf: 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 octets). Le seul changement significatif est que la chaîne avec des espaces est générée une fois pour toutes au lieu de "à la volée" (et bien sûr, l'impression au lieu de revenir).
Olivier Grégoire

3

Haskell, 64 62 octets

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

Essayez-le en ligne! Comment ça marche:

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 octets

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).

Peut-être essayer en ligne ici: http://swish.swi-prolog.org/p/hEKigfEl.pl

NB

  1. La dernière ligne est une longue ligne, j'ai ajouté un saut de ligne et des espaces ici juste pour éviter la barre de défilement horizontale dans cette réponse.
  2. La question implique des espaces pour le remplissage, mais Swish online ne les affiche pas proprement à cause des interactions de rendu HTML, vous devez afficher le source dans les outils de développement du navigateur pour vérifier leur présence (ce qui est le cas). J'ai changé le padding pour qu'il soit _ici, car cela montre qu'il fonctionne et n'affecte pas le nombre d'octets.

Exemples en cours d'exécution dans Swish:

Cas de test

L’approche, c’est la première chose que je pouvais faire fonctionner, et sans doute un utilisateur expérimenté de Prolog pourrait la raccourcir beaucoup:

  • Étant donné une chaîne de longueur L, la sortie comportera L lignes, et chaque ligne comportera L caractères, ainsi «L» en affichera beaucoup. Compte à rebours de L à 0 pour le nombre de lignes, L pour la longueur de sous-chaîne pour chaque ligne.
  • Créez une chaîne de remplissage de L espaces (traits de soulignement) longs, ajoutez-la aux deux extrémités de la chaîne d'entrée, car il s'agit d'une longueur simple qui va certainement suffire.
  • Calculez un décalage de départ dans cette chaîne de trois longueurs et recurse, générant une sous-chaîne à chaque fois, dans une liste de résultats.

Code expliqué et commenté (peut ne pas s'exécuter), lu de superacrostic()bas en haut, puis helper()corps principal, puis helper()scénario de base:

% 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 octets

g;úIvDIg£,À

Essayez-le en ligne!

Explication

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 caractères = 22 octets

{⊢⌺(≢⍵)⊢⍵}

Essayez-le en ligne!

{... } fonction anonyme où l'argument est représenté par

 fournir la zone couverte lorsque

⌺() Glissant un pochoir de taille

   longueur de

   l'argument

 sur

 l'argument

Cela fonctionne en laissant chaque caractère former le milieu d'une chaîne avec la même longueur que l'entrée, en complétant la marge à gauche ou à droite selon les besoins. Prenez par exemple ABXCD:

La chaîne a cinq caractères, donc le pochoir aura une "ouverture" de cinq caractères de large.

┌──↓──┐     ouverture pochoir avec un marqueur milieu
│ ABX│CD   laissa Aêtre au milieu
 │ ABXC│D   puis , B
  │ABXCD|   etc.
  A|BXCD | 
  AB|XCD  |
    └──↑──┘ position finale pochoir



2

JavaScript (ES8), 66 63 62 octets

Retourne un tableau.

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

L'essayer

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>


Explication

s=>

Fonction anonyme prenant la chaîne en argument avec paramètre s.

[...s]

Fractionner la chaîne en un tableau de caractères individuels.

l=s.length

Obtenez la longueur de la chaîne et assignez-la à variable l.

.map((_,x)=>                                        )

Carte sur le tableau, en passant chaque élément à travers une fonction, où xest l'index de l'élément actuel.

s.padStart(l*1.5)

Pour chaque élément, renvoyez la chaîne d'origine avec les espaces précédés de caractères jusqu'à ce que sa longueur soit 1,5 fois celle de sa longueur d'origine.

.substr(x,l)

Obtenir la sous-chaîne de longueur à lpartir de l'index de l'élément en cours.


2

V , 14 , 11 octets

òlÙxHÄ$x>>ê

Essayez-le en ligne!

3 octets sauvés grâce à @nmjmcman!

Hexdump:

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

Approche originale (18 octets):

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

Explication:

ò           " 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.

Économisez quelques octets: essayez-le en ligne!
nmjcman101

@ nmjcman101 Ah, c'est du génie! J'ai totalement oublié ê. Merci :)
DJMcMayhem

2

PowerShell Core , 68 octets

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

Essayez-le en ligne!

Explication non-golfée

# 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
Tu veux ungolf la rejoindre [($_..($_+$L))]?
racine le

@root short answer, (cela ne va pas avec la jointure, il -join ($Padding + $Text)[0,1,2,3,4]faut sélectionner plusieurs caractères dans une chaîne complétée pour une ligne de sortie, et les joindre dans une chaîne est un moyen plus rapide de le faire .SubString(). et il génère le remplissage sur place et la gamme de caractères sur place. Une explication complète sur l’ungolf a été ajoutée à ma réponse.
TessellatingHeckler

2

Japt , 19 17 14 octets

5 octets sauvés grâce à @ETHproductions et @Shaggy

¬£iSp½*Ul¹tYUl

Testez-le en ligne! -Rflag ajouté pour rejoindre les nouvelles lignes (fins de visibilité)

Explication

¬£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
Il devrait y avoir un moyen beaucoup plus court de générer Sp½*Ul, mais je ne pense pas qu'il y ait un atm ... BTW, vous pouvez généralement changer sXX+Yen tXY( s == .slice, t == .substr)
ETHproductions

@ETHproductions Oh oui, merci!
Oliver


Ou, étant donné que le retour d'un tableau est autorisé, 14 octets .
Shaggy


1

Gelée , 11 octets

LH⁶ẋ;ṫJḣ€LY

Essayez-le en ligne!

Comment ça marche

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 octets

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

Man, il est temps pour moi d'ajouter space$à QBIC ...

Explication

  ;             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

Échantillon échantillon

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

1

Mathematica, 88 octets

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

1

Haskell , 86 70 octets

C'est (encore) beaucoup trop long, mais merci à @bartavelle de me rappeler que la sortie d'une liste de chaînes est acceptable aussi!

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

Essayez-le en ligne!


Je n'ai pu atteindre que 82 ans: essayez-le en ligne!
bartavelle

@bartavelle Cela ne semble pas correct. Votre côté droit n'est pas haché.
Adám

Oui j'ai introduit un bug! Vous pouvez gagner un peu en laissant tomber votre concat: essayez-le en ligne!
bartavelle

Et avec le découpage c'est 84, améliorant votre approche! Essayez-le en ligne!
bartavelle

Et vous pouvez économiser beaucoup plus, car vous n'avez pas besoin de renvoyer une seule chaîne, les listes de chaînes sont également acceptables!
bartavelle


1

PowerShell , 133 119 octets

$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}

Essayez-le en ligne!

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
Bonne réponse! Bienvenue sur le site. :)
DJMcMayhem

1

Python 2 ,76 74 73 octets

-1 grâce à @FelipeNardiBatista

Bien sûr, pas aussi courte que l’autre réponse Python, mais cela vaut la peine d’essayer une méthode complètement différente:

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

Essayez-le en ligne! (avec la version à 74 octets)

Cela génère d'abord la chaîne complète, puis la découpe en tranches pour correspondre au carré.


Explication

n = entrée (); - prend une entrée et l'assigne à une variable n
          x = len (n) - assigne la longueur de l'entrée à une variable x
pour i dans la plage (x): - itère sur la plage 0 ... x, avec une variable i
                   print - affiche le résultat
                         ((2 * xi-1) * '' + n) - crée la chaîne "losange"
                                          [x + x / 2: 2 * x + x / 2] - coupe la chaîne pour l'adapter à la boîte

(2*x+~i)pour économiser un octet
Felipe Nardi Batista

@ FelipeNardiBatista Merci.

1

J , 19 octets

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

Essayez-le en ligne!

Explication

|.!.' '"{~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 ' '

Fonctionne avec ''comme remplaçant.
FrownyFrog le

0

C # (.NET Core) , 101 octets

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

En gros, la réponse de KevinCruijssen. Enregistre 2 octets car string.Lengthn'a pas besoin de () et 2 autres octets car le deuxième argument de string.Substring()est length plutôt que end Index, mais perd ensuite 2 octets car il Console.WriteLine()est plus long. J'ai eu une implémentation plus naïve, mais elle était environ deux fois plus longue alors ...


0

Excel VBA, 68 octets

Golfé

Fonction de fenêtre immédiate VBE anonyme qui prend les entrées de la cellule [A1]et les envoie à la fenêtre VBE immédiate

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.