Hacer un súper acróstico


35

Fondo

Celebrando el lanzamiento de Dyalog APL 16.0 , donde la solución a este problema es la {⊢⌺(≢⍵)⊢⍵}explicación

Tarea

Dada una cadena ASCII imprimible de longitud impar n , haga un cuadrado n × n con la cadena centrada horizontalmente, duplicada para centrarse verticalmente, y con acrósticos de la misma cadena en cada fila y columna. Tenga en cuenta que todas las cadenas excepto las centradas se cortarán para mantener el tamaño del cuadrado n × n .

La explicación de su código será muy apreciada.

Reglas

  1. Puede tener espacios en blanco al final y nuevas líneas (esto incluye el triángulo inferior derecho)
  2. Puede devolver una lista de cadenas.

Ejemplo usando la cadena ABXCD:

  • n es 5. Primero dibujamos las dos cadenas centradas, una horizontal y otra vertical:

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

    (Se agregó un cuadro delimitador 5 × 5 para mayor claridad)

  • Luego colocamos todos los acrósticos posibles, horizontal y verticalmente:

           UNA
          AB
      ┌─────┐
      │ ABX│CD
      │ ABXC│D
      │ABXCD│
     A│BXCD │
    AB│XCD │
      └─────┘
       discos compactos
       re
    
  • Finalmente, devolvemos solo lo que está dentro del cuadro delimitador:

      ABX
     ABXC
    ABXCD
    BXCD 
    XCD  
    

Casos de prueba

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

Expresiones de gratitud

Gracias a dzaima , Leaky Nun , Mr. Xcoder por todo menos la idea de este desafío.


1
¿El espacio-triange en la parte inferior derecha tiene que ser incluido o no?
flawr

1
@flawr OP: mayo
Adám

Respuestas:



5

MATL , 8 bytes

nXyPGZ+c

Pruébalo en línea!

Explicación

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én pensó que me gustaría esta respuesta: D
flawr

1
@flawr Sí, quién hubiera pensado
Luis Mendo el

4

Retina , 70 59 bytes

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

Pruébalo en línea! Editar: guardado 11 bytes con ayuda de @MartinEnder. Explicación: La primera etapa repite la entrada una vez para cada carácter, rellenándola adecuadamente en cada línea para obtener el corte. La última etapa luego elimina el 25% de cada lado para producir el resultado deseado.


Creo que tenía 59 antes. No tengo tiempo para desenterrar los detalles ahora, pero esencialmente en la primera etapa simplemente rellené la entrada con n/2espacios a la izquierda y a la derecha (usando algo como (..)+.-> $#1$* $&$#1$*con un espacio final) y luego hice un lugar !&`...donde ...coincide nexactamente con los ncaracteres.
Martin Ender

Su enfoque al menos se puede acortar a 63: tio.run/##K0otycxL/…
Martin Ender

@ Martininder ¡Gracias, y he jugado otros 4 bytes de descuento!
Neil

¿Necesitas el segundo $*sp?
CalculatorFeline

@CalculatorFeline Sí, necesito que todas las líneas tengan la misma longitud, así que puedo dividirlo entre 4.
Neil

3

Java 8, 120 103 bytes

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 bytes gracias a @ OlivierGrégoire .

Explicación:

Pruébalo aquí

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+1y i-->1y for(;i<lguardar un byte.
Olivier Grégoire

1
Y ... totalmente golfizado: 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 bytes). El único cambio significativo es que la cadena con espacios se genera de una vez por todas en lugar de "sobre la marcha" (y, por supuesto, la impresión en lugar de volver).
Olivier Grégoire

3

Haskell, 64 62 bytes

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

Pruébalo en línea! Cómo funciona:

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 bytes

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

Tal vez intente en línea aquí: http://swish.swi-prolog.org/p/hEKigfEl.pl

NÓTESE BIEN.

  1. La última línea es una línea larga, agregué un salto de línea y espacios aquí solo para evitar la barra de desplazamiento horizontal en esta respuesta.
  2. La pregunta involucra espacios para el relleno, pero Swish en línea no los muestra limpiamente debido a las interacciones de representación HTML, debe ver la fuente en las herramientas de desarrollo del navegador para verificar que estén presentes (lo están). He cambiado el relleno para que esté _aquí, ya que demuestra que funciona y no afecta el recuento de bytes.

Ejemplos que se ejecutan en Swish:

Casos de prueba

Enfoque, básicamente lo primero que podría hacer que funcione, y sin duda un usuario experto de Prolog podría acortarlo mucho:

  • Dada una cadena de longitud L, la salida tendrá L líneas, y cada línea tendrá una longitud de L caracteres, por lo que 'L' aparece mucho. Cuenta regresiva de L a 0 para el número de líneas, L para la longitud de la subcadena para cada línea.
  • Cree una cadena de relleno de L espacios (guiones bajos) de largo, agréguelo a ambos extremos de la cadena de entrada, porque esa es una longitud simple que definitivamente será suficiente relleno.
  • Calcule un desplazamiento inicial en esta cadena de triple longitud y recurse, generando una subcadena cada vez, en una lista de resultados.

Código explicado y comentado (podría no ejecutarse), leer desde superacrostic()abajo, luego el helper()cuerpo principal, luego el helper()caso 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 bytes

g;úIvDIg£,À

Pruébalo en línea!

Explicación

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 caracteres = 22 bytes

{⊢⌺(≢⍵)⊢⍵}

Pruébalo en línea!

{... } función anónima donde el argumento está representado por

 proporcionar el área cubierta cuando

⌺(... ) deslizando una plantilla de tamaño

   longitud de

   el argumento

 en

 el argumento

La forma en que esto funciona es dejando que cada carácter forme el centro de una cadena con la misma longitud que la entrada, rellenando a la izquierda o derecha según sea necesario. Tomar egABXCD :

La cadena tiene cinco caracteres, por lo que la plantilla tendrá una "apertura" de cinco caracteres de ancho.

┌──↓──┐     abertura de la plantilla con marcador medio
│ ABX│CD   permiten Aestar en el medio
 │ ABXC│D   a continuación, B
  │ABXCD|   etc.
  A|BXCD | 
  AB|XCD  |
    └──↑──┘ posición final stencil



2

JavaScript (ES8), 66 63 62 bytes

Devuelve una matriz.

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

Intentalo

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>


Explicación

s=>

Función anónima que toma la cadena como argumento a través de un parámetro s.

[...s]

Divida la cadena en una matriz de caracteres individuales.

l=s.length

Obtenga la longitud de la cadena y asígnela a la variable l.

.map((_,x)=>                                        )

Asigne sobre la matriz, pasando cada elemento a través de una función, donde xestá el índice del elemento actual.

s.padStart(l*1.5)

Para cada elemento, devuelva la cadena original con espacios antepuestos hasta que su longitud sea 1.5 veces mayor que su longitud original.

.substr(x,l)

Obtenga la subcadena de longitud a lpartir del índice del elemento actual.


2

V , 14 , 11 bytes

òlÙxHÄ$x>>ê

Pruébalo en línea!

¡3 bytes guardados gracias a @nmjmcman!

Hexdump:

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

Enfoque original (18 bytes):

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

Explicación:

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

Ahorre un par de bytes: ¡ Pruébelo en línea!
nmjcman101

@ nmjcman101 ¡Ah, eso es genial! Me olvidé por completo ê. Gracias :)
DJMcMayhem

2

PowerShell Core , 68 bytes

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

Pruébalo en línea!

Explicación sin golf

# 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
¿Quieres ungolf a la unión [($_..($_+$L))]?
raíz

@ raíz respuesta corta, (no va con la unión, está haciendo -join ($Padding + $Text)[0,1,2,3,4]seleccionar varios caracteres de una cadena acolchada para una línea de salida, y unirlos en una cadena para ser una forma más corta de hacerlo .SubString(). y está generando el relleno en el lugar y el rango de caracteres en el lugar. Explicación completa de ungolf agregada a mi respuesta.
TessellatingHeckler

2

Japt , 19 17 14 bytes

Guardado 5 bytes gracias a @ETHproductions y @Shaggy

¬£iSp½*Ul¹tYUl

¡Pruébelo en línea! -RSe agregó una bandera para unirse a las nuevas líneas (con fines de visibilidad)

Explicación

¬£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
Debería haber una forma mucho más corta de generar Sp½*Ul, pero no creo que haya un sXX+YtXYs == .slicet == .substr
cajero automático

@ETHproductions ¡Oh sí, gracias!
Oliver


O, ya que está permitido devolver una matriz, 14 bytes .
Shaggy


1

Jalea , 11 bytes

LH⁶ẋ;ṫJḣ€LY

Pruébalo en línea!

Cómo funciona

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 bytes

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

Hombre, es hora de que agregue space$a QBIC ...

Explicación

  ;             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

Ejecución de la muestra

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

1

Mathematica, 88 bytes

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

1

Haskell , 86 70 bytes

Esto es (todavía) demasiado largo, pero gracias @bartavelle por recordarme que también es aceptable generar una lista de cadenas.

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

Pruébalo en línea!


Solo pude llegar a 82: ¡ Pruébelo en línea!
bartavelle

@bartavelle Eso no se ve bien. Tu lado derecho no está cortado.
Adám

Sí, introduje un error! Puede ganar un poco soltando su concat: ¡ Pruébelo en línea!
bartavelle

¡Y con el corte es 84, mejorando su enfoque! Pruébalo en línea!
bartavelle

Y puede ahorrar mucho más, ya que no necesita devolver una sola cadena, ¡las listas de cadenas también están bien!
bartavelle


1

PowerShell , 133 119 bytes

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

Pruébalo en línea!

Sin golf

$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
¡Buena respuesta! Bienvenido al sitio. :)
DJMcMayhem

1

Python 2 ,76 74 73 bytes

-1 gracias a @FelipeNardiBatista

Por supuesto, no es tan corto como la otra respuesta de Python, pero vale la pena probar un método completamente diferente:

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

Pruébalo en línea! (con la versión de 74 bytes)

Esto genera primero la cadena completa y luego la corta para que se ajuste al cuadrado.


Explicación

n = input (); - toma la entrada y la asigna a una variable n
          x = len (n): asigna la longitud de la entrada a una variable x
para i en rango (x): - itera en el rango 0 ... x, con una variable i
                   print - muestra el resultado
                         ((2 * xi-1) * '' + n) - crea la cadena de "diamante"
                                          [x + x / 2: 2 * x + x / 2]: recorta la cadena para que se ajuste a la caja

(2*x+~i)para salvar un byte
Felipe Nardi Batista

@FelipeNardiBatista Gracias.

1

J , 19 bytes

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

Pruébalo en línea!

Explicación

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

Funciona con ''el reemplazo.
FrownyFrog

0

C # (.NET Core) , 101 bytes

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

Básicamente la respuesta de @ KevinCruijssen. Guarda 2 bytes porque string.Lengthno necesita () y otros 2 bytes porque el segundo argumento de string.Substring()es length en lugar de end Index, pero luego pierde 2 bytes porque Console.WriteLine()es más largo. Tuve una implementación más ingenua, pero fue aproximadamente el doble de tiempo, así que ...


0

Excel VBA, 68 bytes

Golfed

Función de ventana inmediata anónima de VBE que toma entrada de la celda [A1]y salidas a la ventana inmediata de VBE

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

Sin golf

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.