Hacer palabras cuadradas

38

El reto

Su tarea es crear un programa que tome cualquier entrada de cadena dada y la envíe en formato cuadrado. Las cadenas vacías deberían devolver una cadena vacía.

Ejemplos

Dada la entrada:

golf

Su programa debería generar:

golf
o  l
l  o
flog

Entrada:

123

Salida:

123
2 2
321

Entrada:

a

Salida:

a

Entrada:

Hello, world!

Salida (observe el espacio entre, y w - la brecha no es solo una nueva línea):

Hello, world!
e           d
l           l
l           r
o           o
,           w

w           ,
o           o
r           l
l           l
d           e
!dlrow ,olleH

Tanteo

Este es el , por lo que gana la respuesta más corta en cada idioma.

SpookyGengar
fuente
@DJMcMayhem Sí, mis disculpas me había olvidado de agregar eso.
SpookyGengar
2
No se preocupe, solo verifique dos veces. Bonito primer desafío por cierto! Bienvenido al sitio :)
DJMcMayhem
@SpookyGengar ¿Agregaría un caso de prueba para una entrada de una letra?
musicman523
@ musicman523 ¿ya no tengo uno? El tercer ejemplo involucra solo la letra 'a'.
SpookyGengar
1
@SpookyGengar mi mal, aparentemente estoy ciego
musicman523

Respuestas:

17

Carbón , 7 5 bytes

θ‖O↙↘

Pruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 2 bytes gracias a @CarlosAlejo. Explicación:

θ       Print the input string, making the top row
 ‖O     Reflect with overlap...
   ↙    ... down and left, to create the left side
    ↘   ... down and right, to create the bottom and right sides

(Múltiples direcciones al comando Reflect se ejecutan consecutivamente en lugar de simultáneamente).

Neil
fuente
Vaya, Jesús, sigo pensando que el carbón era la mejor idea de esolang.
Urna mágica de pulpo
1
Puede guardar dos bytes si sólo imprime la cadena de entrada y reflexionar que downleftwards y downrightwards: θ‖B↙↘. Pruébalo en línea!
Charlie
Ahora que lo pienso, tal vez debería haber usado en ReflectOverlaplugar de ReflectButterflyevitar voltear caracteres. :-)
Charlie
1
Este es uno de los raros casos en que una respuesta de golf en un lenguaje esotérico es más fácil de leer y comprender que las versiones completas sin lenguaje de idiomas populares de uso general.
Caleb
Su respuesta aquí también funciona para 4 bytes.
Oliver
10

MATL , 20 16 11 bytes

otYTO6Lt&(c

Pruébalo en MATL en línea!

EDITAR: el código funciona en la versión 20.2.1, que es anterior al desafío. El enlace usa esa versión. (En 20.2.2 el código sería más corto, pero es posterior al desafío).

Explicación

o     % Implicitly input a string. Convert chars to ASCII codes
t     % Duplicate
YT    % 2-input Toeplitz matrix
O     % Push 0
6L    % Push predefined literal [2, -1+1j]. When used as an index, this is
      % interpreted as 2:end-1 (indexing is 1-based)
t     % Duplicate
&(    % 4-input assignment indexing. This writes 0 at the square formed by
      % rows 2:end-1 and columns 2:end-1 
c     % Convert to char. Char 0 is shown as space. Implicitly display
Luis Mendo
fuente
¡Muy impresionante! :) ¿Es posible eliminar la línea en blanco en la parte inferior de cada salida, o es eso necesario para la funcionalidad?
SpookyGengar
2
@SpookyGengar Es una solicitud muy común para permitir una nueva línea final.
Jonathan Allan
@SpookyGengar ¡Gracias! MATL siempre muestra una nueva línea final. Como dice Jonathan, eso generalmente está permitido
Luis Mendo
1
@LuisMendo Aprendes algo nuevo todos los días. :) Gracias por la presentación, ¡definitivamente el mejor hasta ahora!
SpookyGengar
6

Jalea ,  29 22  17 bytes

Carbón de leña será derrotar a + d esta partitura ...

J⁶ẋa0,1¦"ṚṚ;$ṖŒḌY

Un enlace monádico que toma y devuelve una lista de personajes; o un programa completo imprimiendo el resultado.

Pruébalo en línea!

¿Cómo?

J⁶ẋa0,1¦"ṚṚ;$ṖŒḌY - Link: list of characters, w     e.g. "whole"
 ⁶                - literal space character              ' '
J                 - range(length(w))                     [1,2,3,4,5]
  ẋ               - repeat                               [" ","  ","   ","    ","     "]
         Ṛ        - reverse w                            "elohw"
        "         - zip with:
       ¦          -   sparse application of:
   a              -     and (vectorises)
    0,1           -     to indexes: [0,1] (last and 1st) ["e","ll","o o","h  h","w   w"]
            $     - last two links as a monad:
          Ṛ       -   reverse                            ["w   w","h  h","o o","ll","e"]
           ;      -   concatenate                        ["w   w","h  h","o o","ll","e","e","ll","o o","h  h","w   w"]
             Ṗ    - pop (remove last entry)              ["w   w","h  h","o o","ll","e","e","ll","o o","h  h"]
              ŒḌ  - reconstruct matrix from diagonals    ["whole","h   l","o   o","l   h","elohw"]
                Y - join with newlines                   "whole\nh   l\no   o\nl   h\nelohw"
                  - if running as a full program implicit print
Jonathan Allan
fuente
¡Muy genial! Hasta ahora, la solución más corta, pero no funciona con entradas de un solo carácter, y cadenas que consisten en números, es decir, '123'.
SpookyGengar
Ah, tendré que manejar el caso límite de un solo carácter, sí. Funciona con cadenas de caracteres de dígitos, la entrada del programa realmente debería ser citada, como 'Hello'"Spooky's" "123", etc. (Python se usa para interpretar la entrada).
Jonathan Allan
@SpookyGengar: lo arregló para el caso de 1 carácter.
Jonathan Allan
Buena reducción de longitud!
Luis Mendo
2
Tienes razón sobre el carbón.
Neil
3

C, 109 bytes

i,j;f(char*s){for(i=j=printf("%s\n",s)-2;1[++s];)printf("%c%*c\n",*s,i,s[j-=2]);for(;*s*~i--;)putchar(*s--);}

Pruébalo en línea!

Trucos notables:

  • En lugar de perder bytes strlen, simplemente tomamos la longitud de la cadena mientras imprimimos simultáneamente la primera línea:

    i=j=printf("%s\n",s)-2

    Esto funciona porque printfdevuelve el número de bytes escritos.

  • Para las líneas intermedias, necesitamos recorrer la cadena pero excluir tanto el primer como el último carácter. Esto se logra con la condición

    1[++s]

    (que es más corto que (++s)[1]), que omite el primer carácter debido a que ++está en la condición y omite el último deteniéndose cuando el personaje pasa el carácter actual '\0'(en lugar de detenerse en '\0' ).

  • En el cuerpo del primer bucle,

    printf("%c%*c\n",*s,i,s[j-=2])

    imprimimos el carácter actual, luego el carácter "reflejado" apropiado (haciendo un seguimiento j, que entra en los negativos, lo que resulta en una situación extraña de indexación en una cadena con un número negativo) acolchado a una longitud de iespacios (donde iestá convenientemente strlen(s) - 1).

  • La impresión invertida en la última línea es bastante sencilla; El único truco es el *s*~i--, que es la forma más corta de obtener i+2iteraciones del cuerpo del bucle (que no depende de i; todo lo que ise utiliza es contar). La *s*parte funky se asegura de que el ciclo no se ejecute si *ses así '\0', lo que sucede en la entrada de longitud 1.

Pomo de la puerta
fuente
3

Octava, 40 bytes

@(s,t=toeplitz(s),u=t(x=2:end-1,x)=32)t;

Pruébalo en línea!

Es mi respuesta, pero publicado después de @Luis MATL answer

rahnema1
fuente
2
Muy buena respuesta. Por cierto: su código bloqueó la rama de desarrollo de GNU Octave 4.3.1 (b481a9baeb61) y ahora forma parte del conjunto de pruebas :-) hg.savannah.gnu.org/hgweb/octave/rev/c94e9509461b
Andy
1
@Andy Gracias y bienvenidos a codegolf! ¡Me alegro si puede ayudar a mejorar el proyecto Octave!
rahnema1
3

Haskell , 84 78 bytes

f s@(_:x)|_:y<-r x=s:[a:(y>>" ")++[b]|(a,b)<-zip x y]++[r s];f s=[s]
r=reverse

Pruébalo en línea! Uso: f "test". Devuelve una lista de líneas.

Editar: -6 bytes gracias a dianne!

Laikoni
fuente
1
puede guardar algunos bytes usando el protector de patrón como protector y definiendo un sinónimo para reverse; r=reverse;f s@(_:x)|_:y<-r x=s:[a:(y>>" ")++[b]|(a,b)<-zip x y]++[r s];f s=[s]es de 78 bytes.
dianne
2

Python 2 , 89 81 88 86 bytes

i=input();n=k=len(i)-2
print i
exec'print i[~k]+" "*n+i[k];k-=1;'*n
if~k:print i[::-1]

Pruébalo en línea!

Koishore Roy
fuente
Misma falla para cuerdas de longitud 1 que la mía.
Stephen
@StepHen lo arregló y jugó más: D
Koishore Roy
2

R , 113 bytes

function(s){n=length(s<-strsplit(s,'')[[1]])
m=matrix(' ',n,n)
m[n,n:1]=m[,1]=m[1,]=m[n:1,n]=s
write(m,'',n,,'')}

Pruébalo en línea!

Giuseppe
fuente
Mi respuesta al desafío del engaño es más corta: ¡qué diferencia puede hacer un año!
Giuseppe
2

05AB1E , 17 16 15 19 bytes

ÂDÂø¦¨Dgú€Ás)˜»Igi¨

Pruébalo en línea!

Explicación

Ejemplo con input = golf

ÂDÂ                  # bifurcate, duplicate, bifurcate
                     # STACK: 'golf', 'flog', 'flog', 'golf'
   ø                 # zip the top 2 items
                     # STACK: 'golf', 'flog', ['fg', 'lo', 'ol', 'gf']
    ¦¨               # remove the first and last element
                     # STACK: 'golf', 'flog', ['lo', 'ol']
      Dg             # get the length of the list
                     # STACK: 'golf', 'flog', ['lo', 'ol'], 2
        ú            # prepend that many spaces to each element
                     # STACK: 'golf', 'flog', ['  lo', '  ol']
         €Á          # rotate each right
                     # STACK: 'golf', 'flog', ['o  l', 'l  o']
           s         # swap the top 2 items
                     # STACK: 'golf', ['o  l', 'l  o'], 'flog'
            )˜       # wrap in a flattened list
                     # STACK: ['golf', 'o  l', 'l  o', 'flog']
              »      # join on newline
               Igi¨  # if input is length 1, remove last char

La solución para la entrada de 1 letra era bastante costosa.
Siento que un enfoque diferente podría ser mejor ahora.

Emigna
fuente
1

Python 2 , 99 88 bytes

-4 bytes gracias a musicman523.

lambda s:s[1:]and[s]+[s[i]+' '*(len(s)-2)+s[~i]for i in range(1,len(s)-1)]+[s[::-1]]or s

Pruébalo en línea!

Devuelve una lista de cadenas.

totalmente humano
fuente
¡Cerca! La salida no es exactamente lo que estoy pidiendo.
SpookyGengar
1
89 bytes moviéndose sy entrando s[::-1]en eljoin
musicman523
Esto no funciona para cadenas de longitud 1
musicman523
2
Solo para tener en cuenta, todos los problemas se han solucionado.
totalmente humano
1

Mathematica, 128 bytes

(c=Column;g=Length[x=Characters@#]-1;If[g==0,#,c@{#,c@Table[""<>{x[[i]],""<>Table[" ",g-1],x[[-i]]},{i,2,g}],StringReverse@#}])&
J42161217
fuente
1

C, 96 bytes

i,l;f(char*s){for(i=l=puts(s)-2;--i;)printf("%c%*c\n",s[l-i],l,s[i]);for(;l+1;)putchar(s[l--]);}

Versión de bonificación (122 bytes):

x,y,i,l;f(char*s){for(i=l=puts(s)-1;++i<l*-~l;putchar(x==l?10:x%~-l*(y%~-l)?32:s[(x*y?l+l-2-x-y:x+y)%l]))x=i%-~l,y=i/-~l;}
orlp
fuente
1

Swift 3 , 215 199 bytes

let s=readLine()!,c=s.characters,r:[Character]=c.reversed(),b=c.count
print(s)
if b>1{for i in 0..<b-2{print("\(r.reversed()[i+1])\(String.init(repeating:" ",count:b-2))\(r[i+1])")};print(String(r))}

Pruébalo en línea

Mic1780
fuente
1

Python 3, 88 bytes

w=input();p=print;l=len(w)-2
[p(w[n+1]+' '*l+w[l-n])for n in range(l)]
l+1and p(w[::-1])
Levi
fuente
1
Bienvenido a PPCG!
Martin Ender
¡Bienvenido al sitio también! Creo que l+1 andpodría reescribirse l+1andpara guardar un byte.
Wheat Wizard
@WheatWizard editado - ¡gracias! Me sorprendió que funcionó ...
Levi
Funcionará excepto en el caso de 0or, donde python no se analiza porque 0oes un prefijo octal.
Wheat Wizard
Cuando ejecuto esto, no parece imprimir la línea superior ... tio.run/##FcoxCsQgEAXQPqeYLk7EwqRL8CRiEVh3Iww/…
Coty Johnathan Saxman
1

JavaScript (ES8), 108 112 bytes

let f = 

s=>(n=s.length)<2?s:(r=[...s].reverse()).slice(1,-1).reduce((a,v,i)=>a+`
`+s[i+1].padEnd(n-1)+v,s)+`
`+r.join``

o.innerHTML = f("hello folks!")
<pre id="o"></pre>

Menos golfo

s=>
   (n=s.length) < 2 ?    // record and check length
   s :                   // s has 0 or 1 char, else
   (r=[...s].reverse())  // reverse characters,
   .slice(1,-1)          // exclude 1st and last
   .reduce((a,v,i)=>     // append inner lines
      a +'\n' +s[i+1].padEnd(n-1) + v
    ,s)                  // to first line
    + '\n' +r.join("")   // append characters reversed

Gracias a Justin Mariner por guardar muchos bytes, que luego se agotaron agregando la comprobación de caracteres cero o individual necesaria para cumplir con el desafío. Tu consigues eso :-(

traktor53
fuente
Puede guardar 7 bytes haciendo la segunda línea `+s[i+1].padEnd(s.length-1)+v,s)+`y usando r.join``.
Justin Mariner
Gracias @JustinMariner por los consejos String.prototype.padStarty etiquetados literales de plantilla. Lo necesitaba para mantener la ayuda además de la verificación de longitud al mínimo :-)
traktor53
Tu espacio es un personaje demasiado corto ahora; puedes arreglar eso y ahorrar un par más haciendo (n=s.length-1)?(r=<...>+r.join``:sy usando padEnd(n). Si la longitud es 1, length-1es 0(falso).
Justin Mariner
El espaciado de @JustinMariner es fijo, pero he mantenido la prueba de longitud; según tengo entendido, tanto las cadenas de longitud cero como las cadenas de un carácter se devuelven sin retorno de carro ni repetición de la cadena.
traktor53
1
padEndes ES2017.
Neil
1

PHP , 118 bytes

echo $s=$argv[1];$l=strlen($r=strrev($s))-1;for($i=$l-1;$l&&$i;)echo "\n".str_pad($r[$i],$l).$s[$i].(--$i?"":"\n$r");

Pruébalo en línea!

echo $s = $argv[1];
$l = strlen($r = strrev($s)) - 1;

for ($i = $l - 1; $l && $i;)
    echo "\n" . str_pad($r[$i], $l) . $s[$i] . (--$i ? "" : "\n$r");
marcv
fuente
1

APL , 58 bytes

{(' ',⍵)[x+(x←∘.{((c-1)=⍺⌈⍵)∨0=⍺⌊⍵}⍨r)×o⌊⌽⊖o←∘.⌈⍨r←⍳c←≢⍵]}

Con ⎕IO←0 .

Pruébalo en línea!

¿Cómo?

c←≢⍵ - longitud de la cuerda

r←⍳ - distancia

o←∘.⌈⍨ - producto exterior con mínimo

123
223
333

o⌊⌽⊖- minimizar con sí mismo cumplió 180 o

123  ⌊  333  =  123
223  ⌊  322  =  222
333  ⌊  321  =  321

× - multiplicar con

x←∘....⍨r - producto exterior de la gama con

    ((c-1)=⍺⌈⍵)∨0=⍺⌊⍵ - el marco de la matriz

111  ×  123  =  123
101  ×  222  =  202
111  ×  321  =  321

x+ - agregar el marco

111  +  123  =  234
101  +  202  =  303
111  +  321  =  432

(' ',⍵)[...] - obtener por índice de la cadena concatenada al espacio

Uriel
fuente
Puede ⍉⊖⍉⊖ser ⌽⊖?
Zacharý
@ Zacharý gracias
Uriel
0

JavaScript (ES2017), 87 bytes

s=>[...s].reverse(l=s.length-1).map((c,i,z)=>i?l-i?s[i].padEnd(l)+c:z.join``:s).join`
`

Versión ES6: 93 bytes

s=>[...s].reverse(l=s.length-1).map((c,i,z)=>i?l-i?s[i]+' '.repeat(l-1)+c:z.join``:s).join`
`

Menos golf

s => (
  l = s.length-1,
  [...s].reverse().map( // scan string backwards
     (c, i, z) => 
     i != 0 // check if top row
     ? l-i != 0 // check if bottom row
       ? s[i].padEnd(l) + c // any middle row
       : z.join`` // bottom row: string reversed
     :s // top row: original string
  ).join`\n`
)

F=
s=>[...s].reverse(l=s.length-1).map((c,i,z)=>i?l-i?s[i].padEnd(l)+c:z.join``:s).join`
`

function update() {
  O.textContent = F(I.value)
}

update()
<input id=I value='Hello, world!' oninput='update()'>
<pre id=O></pre>

edc65
fuente
padEndes ES2017.
Neil
@Neil gracias, cambiaré mi título
edc65
Puede guardar un byte en su versión ES6 mediante el uso l+~i, esto evita tener que restar 1 dos veces en lugar de restar 2 una vez.
Neil
@Neil debería serl-~-i
edc65
Estaba pensando s=>[...s].reverse(l=s.length).map((c,i,z)=>i?l+~i?s[i]+' '.repeat(l-2)+c:z.join``:s).join`\n` pero s=>[...s].reverse(l=s.length-2).map((c,i,z)=>i?i+~l?s[i]+' '.repeat(l)+c:z.join``:s).join`\n` también funciona.
Neil
0

Java, 191 bytes

(s)->{PrintStream o=System.out;int l=s.lenght();o.println(s);for(int i=0;i<l;i++){o.printf("%"+"s%"+(l-1)+"s%n",s.charAt(i),s.charAt(l-1-i));for(int i=0;i<l;i++){o.print(s.charAt(l-1-i));}}};
Rana servidor
fuente
(s)puede ser justo s. A los bucles con líneas individuales en el interior se les pueden quitar las llaves. Puede regresar en lugar de imprimir si eso le ahorrará bytes. Usas int ien ambos bucles, no puedo decir si están en diferentes ámbitos, pero vale la pena señalar. Inicializar variables similares juntas generalmente ahorra bytes. for(int i=0;i<l;i++){o.print(s.charAt(l-1-i));}-> for(int i=0;i<l;){o.print(s.charAt(l-1-i++));}. No necesitas el punto y coma final.
TheLethalCoder
Gracias por señalar;) (no muy familiarizado con el golf). Lo optimizará más tarde!
Serverfrog
0

C # (.NET Core) , 179161 bytes

-18 bytes gracias a TheLethalCoder

using System.Linq;
s=>{int l=s.Length-1,i=1;var d=s.Reverse().ToArray();while(i<l)s+="\n"+s[i]+new string(' ',l-1)+d[i++];if(l>1)s+="\n"+new string(d);return s;};

Pruébalo en línea!

No estoy seguro de las reglas, si esto es necesario para contar los bytes o no:

using System.Linq;

Alguien por favor corrígeme sobre esto.

Sin golf:

s =>
{
    int l = s.Length - 1, i = 1;
    var d = s.Reverse().ToArray();
    while (i < l)
        s += "\n" + s[i] + new string(' ', l - 1) + d[i++];
    if (l > 1)
        s += "\n" + new string(d);
    return s;
};
Grzegorz Puławski
fuente
Hola y bienvenidos a PPCG! Está utilizando Linq, por lo que debe incluirlo usingen su recuento de bytes. Como está utilizando Linq ToCharArray()puede ser justo ToArray(), ¿realmente lo necesita antes Reverse()? A medida que lo use String, debe calificarlo completamente o incluirlo, sin embargo, esto también se puede solucionar fácilmente cambiándolo string. El ifpodría ser más corto como un ternario s+=l>1?if code:"";. Puede eliminar el i++del bucle y publicar incrementarlo en d[i++].
TheLethalCoder
Inicializar icon me lgusta int l=s.Length-1,i=1;. ¡Y creo que podría ser eso!
TheLethalCoder
@TheLethalCoder gracias! Agregué tus sugerencias al código. Algunas notas: olvidé por completo que la cadena de hecho tiene IEnumerable; La cadena en lugar de la cadena era un residuo de Java con el que todavía lucho, de hecho, el ternario era exactamente igual de sorprendente; y después de sus cambios cambié por (; expr;) a while (expr) ya que se ve mejor y es el mismo conteo de bytes. Gracias de nuevo.
Grzegorz Puławski
¡Sin preocupaciones! A veces, los ternarios son más cortos, por lo que siempre vale la pena probarlos.
TheLethalCoder
0

Retina , 106 bytes

..+
$&¶$&
O$^`.(?=.*$)

\G.
$&$%'¶
r`.\G
¶$%`$&
+`(.+)¶¶((.*¶)*).(.*)
¶¶$1$4$2
T`p` `(?<=.¶.).*(?=.¶.)
G`.

Pruébalo en línea! Explicación:

..+
$&¶$&

Si hay al menos dos caracteres, duplique la entrada.

O$^`.(?=.*$)

Invierta el duplicado.

\G.
$&$%'¶
r`.\G
¶$%`$&

Convierte las cuerdas en triángulos. El triángulo superior comienza con la entrada y elimina el primer carácter cada vez, mientras que el triángulo inferior comienza con la primera letra de la entrada invertida y agrega un carácter cada vez.

+`(.+)¶¶((.*¶)*).(.*)
¶¶$1$4$2

Une los triángulos juntos, superpuestos para que el último personaje forme la /diagonal.

T`p` `(?<=.¶.).*(?=.¶.)

Cambia todos los personajes a espacios, si están al menos a un personaje del final en cada lado.

G`.

Elimine las líneas en blanco sobrantes.

Neil
fuente
0

Python 3, 85 bytes

Usando la entrada para la fila superior :)

a=input()
b=len(a)
for i in range(b-2):print(a[1+i]+" "*(b-2)+a[-2-i])
print(a[::-1])
abc123
fuente
¿Estás seguro de que esto da una respuesta correcta?
Koishore Roy
0

Lua , 104 bytes

print(s);for a=2,#s-1 do print(s:sub(a,a)..(" "):rep(#s-2)..s:sub(#s-a+1,#s-a+1)) end;print(s:reverse())

Pruébalo en línea!


fuente
pero solo usaste puna vez ...
Leaky Nun
Cierto ... va a cambiar eso.
0

Python 3, 106 bytes

Una versión funcional ...

w=input();p=print;l=len(w)-2
def f(k):p(w[k]+' '*l+w[-k-1]);l-k>0and f(k+1)
l<0 or f(1)or l<1or p(w[::-1])
Levi
fuente
0

Mathematica, 138 91 bytes

(b=Outer[" "&,#,#];Do[l={{1,k},{k,1}};b=ReplacePart[b,Join[l,-l]->#[[k]]],{k,Length@#}];b)&

Puede probarlo en línea pegando lo siguiente en Wolfram Cloud Sandbox y haciendo clic en "evaluar celda" o presionando Shift + Enter o Numpad Enter:

(b=Outer[" "&,#,#];Do[l={{1,k},{k,1}};b=ReplacePart[b,Join[l,-l]->#[[k]]],{k,Length@#}];b)&@{"g","o","l","f","y"}//MatrixForm
Marcas.
fuente