Tallar un cuadrado de una cuerda

21

Su desafío hoy es tomar una cadena multilínea y generar el cuadrado más grande contenido dentro de la cadena que incluye la esquina superior izquierda.

Una cadena cuadrada es aquella donde:

  • Cada línea tiene el mismo número de caracteres.
  • El número de caracteres en cada línea es igual al número de líneas.

Considere la siguiente cadena de entrada posible:

abcde
fgh
asdf
foobar

El cuadrado más grande que puede tomar de él que incluye el primer carácter ( aen la esquina superior izquierda) es este:

abc
fgh
asd

No puede haber un cuadrado de longitud lateral 4, porque la segunda línea no es lo suficientemente larga. Ahora considere esta entrada potencial:

a
bcd
edf
ghi

La plaza más grande aquí es justa a. El cuadrado de 3x3 formado en la parte inferior no contiene el primer carácter, y no cuenta.

Aquí hay algunos casos de prueba más:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Puede requerir que la entrada esté delimitada por su elección de LF, CR o CRLF.

Los caracteres de nueva línea no se consideran parte de la longitud de la línea.

Puede requerir que haya o no una nueva línea final en la entrada, que no cuenta como una línea adicional.

La entrada es una cadena o matriz de caracteres 1D; No es una lista de cadenas.

Puede suponer que la entrada no está vacía y que todas las líneas no están vacías, y que solo contiene ASCII imprimible, incluidos espacios y líneas nuevas (para el delimitador de línea) pero no pestañas.

Este es el , ¡la menor cantidad de bytes gana!

Pavel
fuente
relacionado
Pavel
55
+1 para un desafío interesante, -1 para E / S estricta
Dennis
@Dennis no todas las soluciones deben usarse, .split('\n')así que no veo por qué algunas deberían obtenerla de forma gratuita.
Pavel
2
No se trata (solo) de tener que agregar bytes para una repetitiva aburrida. Algunos enfoques (p. Ej., Funciones recursivas) se vuelven completamente poco prácticos si hay un procesamiento previo o posterior.
Dennis
@ Dennis No lo había pensado así. ¿Crees que debería cambiarlo ahora o es demasiado tarde?
Pavel

Respuestas:

5

Brachylog , 11 bytes

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

Pruébalo en línea!

Explicación

ṇ             Split on linebreaks
 ⊇ᵐ           Take a subset of each line
   ẹ          Split the lines into list of chars
    a₀        Take a prefix of this list of lists of chars
      ṁ       It is a square matrix
       cᵐ     Concatenate the list of chars back into strings
         ~ṇ   Join the strings with linebreaks
Fatalizar
fuente
Buen trabajo en la solución más corta (hasta ahora), a Brachylog le gustan los cuadrados, ¿no?
Pavel
@Pavel ¡El incorporado es bastante útil!
Fatalize
7

Cáscara , 13 bytes

►oΛ≈S+TzṀ↑Nḣ¶

Pruébalo en línea!

Explicación

►oΛ≈S+TzṀ↑Nḣ¶  Implicit input, say "ab\nc".
            ¶  Split at newlines: ["ab","c"]
           ḣ   Take prefixes: [["ab"],["ab","c"]]
       z  N    Zip with [1,2,3..
        Ṁ↑     by taking that many characters from each row: [["a"],["ab","c"]]
►o             Find rightmost element that satisfies this:
  Λ            all strings in
    S+T        the list concatenated to its transpose
   ≈           have the same length: ["a"]
               Implicitly print separated by newlines.
Zgarb
fuente
1
¿Cómo es esto incluso un lenguaje de programación? ¡Acabas de pegar algunos oscuros caracteres Unicode! ;)
nabo
1
@Petar Bienvenido al mundo de los idiomas de golf, que están diseñados específicamente para usar la menor cantidad de bytes posible para realizar una determinada tarea. Parte de esto es tener una página de códigos personalizada, de modo que haya un carácter para cada byte posible, en lugar del ASCII imprimible 95 habitual. Pero no se preocupe, también hay idiomas de golf mucho más legibles; por ejemplo mi entrada MATL [/ autopromoción descarada]
Sanchises
5

GNU sed , 106 + 1 94 + 2 = 96 bytes

+2 bytes para -rzbanderas. Utiliza caracteres no imprimibles NUL y BEL, mostrados como @y #aquí. Vea a continuación un volcado xxd.

Gracias a @seshoumara por enviarme por el camino -z.

s/^/@/gm
s/.*/#&\n/
:B
s/@(.)/\1@/mg
s/#(.+\n)/\1#/m
/#.*@./M!b
/@\n.*#/!bB
:
s/@[^\n]*|#.*//g

Pruébalo en línea!

Explicación

Esto funciona insertando dos cursores en el texto: uno para pasar sobre líneas y otro para pasar sobre columnas. Los cursores están representados por NUL (0x00) y BEL (0x07), respectivamente, pero en los siguientes ejemplos usaré @y #. Supongamos que tenemos esta entrada:

abcde
fgh
asdf
foobar

El cursor BEL se inserta antes de la columna 0 y el cursor BEL antes de la línea 0 (aquí he mantenido las columnas alineadas para la legibilidad; pero en realidad no hay relleno izquierdo):

#@abcde
 @fgh
 @asdf
 @foobar

En un bucle, los cursores se mueven un carácter hacia la derecha y una línea hacia abajo, respectivamente:

 a@bcde
#f@gh
 a@sdf
 f@oobar
 ab@cde
 fg@h
#as@df
 fo@obar
 abc@de
 fgh@
 asd@f
#foo@bar

Después de cada iteración, verifica dos condiciones:

  1. En la línea con el cursor de línea, ¿hay un cursor de columna y el cursor de columna puede moverse hacia la derecha?
  2. En las líneas antes del cursor de línea, ¿puede moverse cada cursor de columna hacia la derecha?

Si cualquiera de las condiciones es falsa, el ciclo termina. El script finaliza eliminando todo lo que sigue @en cada línea y todo lo que sigue# en el espacio del patrón.

volcado xxd

00000000: 732f 5e2f 002f 676d 0a73 2f2e 2a2f 0726  s/^/./gm.s/.*/.&
00000010: 5c6e 2f0a 3a42 0a73 2f00 282e 292f 5c31  \n/.:B.s/.(.)/\1
00000020: 002f 6d67 0a73 2f07 282e 2b5c 6e29 2f5c  ./mg.s/.(.+\n)/\
00000030: 3107 2f6d 0a2f 072e 2a00 2e2f 4d21 620a  1./m./..*../M!b.
00000040: 2f00 5c6e 2e2a 072f 2162 420a 3a0a 732f  /.\n.*./!bB.:.s/
00000050: 005b 5e5c 6e5d 2a7c 072e 2a2f 2f67       .[^\n]*|..*//g
Jordán
fuente
Puede eliminar el primer bucle, A, porque la instrucción dice que tiene que leer la entrada como una cadena, para que pueda recibir "line1 \ nline2 \ nline3", etc. Otras respuestas también hicieron esto. Eso debería tener el recuento por debajo de 100 :)
seshoumara
@seshoumara Otras respuestas ¿ line1\nline2\nline3dónde \nestá \x5C\x6E? ¿Cual?
Jordan
¿Puedes darme un enlace? (Haga clic en "compartir" al final de cualquier respuesta). ¿O muéstreme en un TiO a qué se refiere? En todas las respuestas de Python y PHP que veo \nse interpreta como un carácter de nueva línea ( \x0A, no \x5C\x6E) y no puedo encontrar una manera de hacer que sed ingrese los caracteres de nueva línea como una sola línea.
Jordan
@seshoumara Hah, no importa, acabo de recordar la -zbandera. ¡Gracias!
Jordan
4

Python 2 , 81 bytes

l=input().split('\n')
i=0
while zip(*l[:i+1])[i:]:i+=1
for x in l[:i]:print x[:i]

Pruébalo en línea!


Un método interesante, pero 2 bytes más largo.

Python 2 , 83 bytes

l=input().split('\n')
while len(zip(*l))<len(l):l.pop()
for x in l:print x[:len(l)]

Pruébalo en línea!

xnor
fuente
1
¿No inputsolo lee una línea?
Pavel
@Pavel, si mira el ejemplo en línea, puede ver que está usando caracteres de nueva línea explícitos para mantener la entrada como una cadena de una línea. Probablemente opte por este método porque raw_input()agregaría más bytes.
Xavier Dass
4

JavaScript (ES6), 77 bytes

f=(s,i=1,m=s.match(`^${`(.{${i}}).*
`.repeat(i)}`))=>m?f(s,i+1)||m.slice(1):0

Utiliza recursivamente una expresión regular para buscar un cuadrado cada vez más grande hasta que no se encuentre ninguno.

La expresión regular sería esta para un cuadrado de 3x3:

^(.{3}).*
(.{3}).*
(.{3}).*

Se espera que la entrada termine con una nueva línea, y la salida es una lista.

Explicación:

f = (s,                                            //input
     i = 1,                                        //start searching for a 1x1 square
     m = s.match(`^${`(.{${i}}).*\n`.repeat(i)}`)  //match on the regex
    )=>
    m ? f(s, i+1)                   //if there's a match, recurse on the next-sized square
        || m.slice(1) :             //if there's not a next-sized square, return the match
        0                           //no match for this square, so stop recursing

Retazo:

Rick Hitchcock
fuente
3

Perl 5 , 84 bytes

chomp(@a=<>);map$.&&=y///c>$i,@a[0..$i]while$.&&$i++<$#a;say/(.{$i})/ for@a[0..$i-1]

Pruébalo en línea!

Cumple el "abcde\nfghij\nklm\nno"caso de prueba.

Xcali
fuente
podría usar en choplugar de chompy en ++$i<@alugar de$i++<$#a
Nahuel Fouilleul
3

R , 84 83 81 76 bytes

-5 bytes portando el enfoque de Dennis consum

cat(substr(x<-readLines(),1,m<-sum(cummin(nchar(x))>=seq(x)))[1:m],sep='\n')

Pruébalo en línea!

lee desde stdin, imprime en stdout sin una nueva línea final.

Ligeramente incólume:

x <- readLines()                    # read in input one line at a time;
                                    # saved as a vector of strings
minChar <- cummin(nchar(x))         # rolling minimum of all line lengths
lineNum <- seq(x)                   # line number
mins <- minChar>=lineNum            # the min between the line number and the line lengths
m <- sum(mins)                      # the sum of those is the size of the square
cat(substr(x,1,m)[1:m],sep='\n')    # print the first m characters of the first m lines,
                                    # and join with newlines

Giuseppe
fuente
3

C (gcc) , 162 159 151 147 144 142 137 bytes

Debe haber algunos golpes para jugar golf aquí ...

i,l=9;char*p,s[9][8];main(t){for(p=s;~(*p=getchar());)p=*p<32?*p=0,l=(t=strlen(s+i))<l?t:l,s[++i]:p+1;for(i=0;i<l;puts(s+i++))s[i][l]=0;}

Pruébalo en línea!

cleblanc
fuente
¿Pueden !=-1ser >-1o getchar()los valores de salida son menores que menos uno? ¿Podría ser +1?
Jonathan Frech
Potencial 158 bytes .
Jonathan Frech
@ JonathanFrech Puedo usar ~para detectar menos uno.
cleblanc
1
@RickHitchcock parece funcionar en la última versión de golf.
cleblanc
2

Jalea , 15 bytes

L€«\‘>Jx@Z
ỴÇÇY

Pruébalo en línea!

Cómo funciona

ỴÇÇY        Main link. Argument: s (string)

Ỵ           Split s at linefeeds, yielding a string array.
 Ç          Apply the helper link.
  Ç         Apply the helper link again.
   Y        Join, separating by linefeeds.


L€«\‘>Jx@Z  Helper link. Argument: A (string array/2D character array)

L€          Compute the length of each row/line.
  «\        Take the cumulative minimum.
    ‘       Increment each minimum.
      J     Indices; yield [1, ..., len(A)].
     >      Perform elementwise comparison. If the output should have n lines, this
            yields an array of n ones and len(A)-n zeroes.
         Z  Zip/transpose A.
       x@   For each string t in the result to the right, repeat its characters as
            many times as indicated in the result to the left, discarding all but
            the first n characters.
Dennis
fuente
2

Java 8, 150 bytes

s->{String q[]=s.split("\n"),r="";int l=q[0].length(),i=0,t;for(;i<l;l=t<l?t:l)t=q[i++].length();for(i=0;i<l;)r+=q[i++].substring(0,l)+"\n";return r;}

Explicación:

Pruébalo aquí

s->{                          // Method with String as both parameter and return-type 
  String q[]=s.split("\n"),   //  Split the input on new-lines, and put it in an array
         r="";                //  Result-String, starting empty
  int l=q[0].length(),        //  Length of the lines, starting at the length of line 1
      i=0,                    //  Index-integer, starting at 0
      t;                      //  Temp integer
  for(;i<l;                   //  Loop (1) from 0 to `l` (exclusive)
      l=t<l?                  //    After every iteration: if `t` is smaller than `l`:
         t                    //     Change `l` to `t`
        :                     //    Else:
         l)                   //     Leave `l` the same
    t=q[i++].length();        //   Set `t` to the length of the current line
                              //  End of loop (1) (implicit / single-line body)
  for(i=0;i<l;                //  Loop (2) from 0 to `l` (the determined square dimension)
    r+=                       //   Append the result-String with:
       q[i++].substring(0,l)  //    The current row chopped at `l-1`
       +"\n"                  //    + a new-line
  );                          //  End of loop (2)
  return r;                   //  Return the result-String
}                             // End of method
Kevin Cruijssen
fuente
2

MATL , 33 bytes

10-~ft1)wdhqY<tn:vX<X>:GYbowt3$)c

Pruébalo en línea!

Mi sentido arácnido me dice que probablemente haya un camino más corto (estoy pensando en algo Ybodesde el principio) ... Requiere una nueva línea al final. (Nota: diseñé un poco más, ya que esto también manejará líneas vacías, lo cual no es necesario. Veré si puedo reducir el bytecount, porque en el código de golf, no es una característica, sino un error)

Sanchises
fuente
1
@Pavel Guiseppe se refería a otra versión, que retiré porque realmente tenía un error.
Sanchises
1

Python 2 , 132 bytes

def f(s):s=s.split("\n");return["\n".join([l[:j+1]for l in s[:j+1]])for j,v in enumerate(s[0])if all(len(l)>j for l in s[:j+1])][-1]

Pruébalo en línea!

Jonathan Frech
fuente
1

JavaScript (ES6), 95 bytes

f=
s=>(g=s=>s.slice(0,a.findIndex((e,i)=>a.some((s,j)=>j<=i&!s[i]))))(a=s.split`
`).map(g).join`
`
<textarea oninput=o.textContent=f(this.value+`\n`)></textarea><pre id=o>

Requiere una nueva línea final en la entrada.

Neil
fuente
1

APL (Dyalog) , 25 bytes *

Función de prefijo tácito. Devuelve una matriz.

(↑↑⍨2⍴(⌊/≢,≢¨))⎕AV[3]∘≠⊆⊢

Pruébalo en línea!

Es realmente una cima de dos funciones independientes, a saber, ⎕AV[3]∘≠⊆⊢que se ocupa del formato de entrada incómodo y ↑↑⍨2⍴(⌊/≢,≢¨)que hace el trabajo interesante real.

⎕AV[3]∘≠ diferencia de LF (el tercer elemento de la A tomic V ector - el conjunto de caracteres)

 particiones (subcadenas que comienzan en valores mayores que su predecesor y caen en 0)

 el argumento

(... ) aplique la siguiente función tácita:

2⍴(... ) remodelar lo siguiente a la longitud 2:

  ⌊/ el mínimo de

   la cantidad de cuerdas

  , seguido por

  ≢¨ la cantidad de caracteres en cada cadena

↑⍨ tomar tantas filas y columnas de

 Las cadenas se mezclan para formar una matriz (relleno con espacios)


* En el clásico con ⎕ML( M igraci L evel) 3(por defecto en muchos sistemas) y sustituyendo por y para el extremo izquierdo . Tio!

Adán
fuente
Si tiene la misma longitud en Dyalog Classic, también podría decir que es Dyalog Classic y no usar la nota al pie.
Pavel
@Pavel Tanto Classic como ⎕ML←3están en desuso, por lo que prefiero mostrar el idioma como normalmente aparecería. De hecho, casi todas mis soluciones Dyalog APL asumen Classic solo porque contamos bytes en lugar de caracteres, aunque incluso la versión Unicode asigna significado a menos de 256 caracteres.
Adám
1

PHP, 123 bytes

for(;preg_match("#^(\S{".++$i."}.*
){"."$i}#",$s="$argv[1]
"););while($k<$i-1)echo substr(split("
",$s)[+$k++],0,$i-1),"
";

requiere PHP 5.4, 5.5 o 5.6. Reemplazar splitconexplode para PHP más tarde.

Ejecutar php -nr '<code> '<string>'
o probarlo en línea . (¡Asegúrese de seleccionar una versión PHP adecuada!)

Tito
fuente
1

Perl 5, 60 +5 (-0777p) bytes

$.++while/^(.{$.}.*
){$.}/;$_=join"
",(/.{$.}/gm)[0..--$.-1]

Pruébalo en línea

  • La última línea de entrada debe terminar con una nueva línea en caso de que pertenezca a la salida.
  • En caso de dos líneas nuevas consecutivas, la opción -00 puede cambiarse por -0777.
Nahuel Fouilleul
fuente
Dos líneas nuevas consecutivas son posibles, por lo que necesitará -0777. Qué hacer -00y -0777qué hacer, de todos modos.
Pavel
-0es especificar el separador de registros en formato octal 777es un valor especial para indicar que no hay separador para que se lea todo el archivo, 0es otro valor especial para indicar el "modo de párrafo", el separador es más de 1 nueva línea consecutiva
Nahuel Fouilleul
1

Perl 6 , 158 140 bytes

my$c;for ^(my@b=lines).elems {any(@b.head(++$c).map({.substr(0,$c).chars <$c}))&&$c--&&last;};say @b.head($c).map({.substr(0,$c)}).join("
")

Pruébalo en línea!

¡Hurra por mi primera respuesta de Perl 6! Jugaré con algunas opciones de línea de comandos para ver si puedo jugar un poco más. ¡Toda la ayuda para guardar bytes es bienvenida!

Luke
fuente
1

Scala , 201 bytes

type S=String
def c(s:S):S={val? =s split "\n"
var(z,q:Seq[S])=(Seq(?size,?(0).size).min,Nil)
while(1<2){?map(i=>{if(i.size>=z)q=q:+i.take(z)
if(q.size==z)return q mkString "\n"})
q=Nil;z-=1}
return""}

Pruébalo en línea!

Golf por primera vez en este idioma, así que quizás no sea el mejor.

El inicializador
fuente