Alineando líneas!


31

Alineando líneas!

Dado un carácter y una cadena multilínea, su trabajo consiste en rellenar cada línea de la cadena para que se alineen entre el delimitador dado.

Ejemplos

Entrada:

,
Programming, Puzzles
And, Code golf

Salida:

Programming, Puzzles
        And, Code golf

Entrada

La entrada será una cadena multilínea y un carácter (con el que se alineará), puede tomarlos en el orden / formato que desee. El personaje aparecerá exactamente una vez por línea. Cada línea de la entrada puede tener una longitud diferente.

La entrada puede ser a través de argumentos de función o STDIN.

Salida

La salida debe ser la misma cadena centrada. Se le permite una nueva línea final y ningún espacio en blanco final.

La salida debe rellenarse con la cantidad mínima de espacios. No puede eliminar ningún espacio en blanco inicial en la entrada (si existe).

La salida puede ser de retorno de función o STDOUT.


¿Puede la entrada a un programa completo provenir de argumentos de línea de comandos, o está prohibido?
DLosc

@DLosc Sí, por supuesto
Downgoat

1. Para argumentos de función / línea de comando, ¿deberíamos leer una sola cadena o sería admisible una línea por argumento? 2. ¿Tenemos que rellenar las líneas con la mínima cantidad de espacios?
Dennis

@Dennis Puede tomarlo en una sola cadena. O una línea por argumento. "puede tomarlos en el orden que desee" . Sí, necesita rellenar las líneas con la cantidad mínima de espacios.
Editaré

@vihan ¿Pueden las funciones tomar una línea por argumento?
xnor

Respuestas:



13

APL (37)

APL simplemente no es muy bueno en el procesamiento de cadenas (o no soy bueno en el golf, por supuesto).

{⌽∊R,¨' '/⍨¨(⌈/-+)⍺⍳⍨¨⌽¨R←S⊂⍨S=⊃S←⌽⍵}

Esto toma el carácter como argumento izquierdo y la cadena multilínea como argumento derecho. Se supone que la cadena de varias líneas termina en un salto de línea (p . Ej., En A\nB\nC\nlugar de A\nB\nC). Dado que puedo usar "cualquier formato que desee", y este también es el formato convencional para archivos de texto, creo que esto es razonable.

Explicación:

  • S←⌽⍵: invierte la cadena y la almacena S.
  • R←S⊂⍨S=⊃S: se divide Sen su primer carácter y almacena la matriz de cadenas en R.
  • ⍺⍳¨⌽¨R: invierte cada cadena Ry luego encuentra el índice de ⍺ (el carácter) en cada cadena.
  • (⌈/-+): resta cada uno de los índices del índice más grande, dando la cantidad de espacios necesarios
  • ' '/⍨¨: para cada uno de esos valores, genera tantos espacios
  • R,¨: agrega los espacios a cada cadena R.
  • : une todas las cuerdas
  • : invertirlo (para recuperar el pedido original)

Ejemplo:

      NL←⎕UCS 10 ⍝ newline
      test←'Programming, Puzzles',NL,'And, Code golf',NL
      test ⍝ test string
Programming, Puzzles                
And, Code golf                      

      ⍝ run the function
      +X←','{⌽∊R,¨' '/⍨¨(⌈/-+)⍺⍳⍨¨⌽¨R←S⊂⍨S=⊃S←⌽⍵}test
Programming, Puzzles                        
        And, Code golf                      

      ⍴X ⍝ result is really a string with newlines, not a matrix
44

9

CJam, 23 22 20 bytes

Gracias a Dennis por guardar 2 bytes.

ea_rf#_:e>\fm.{S*\N}

Esto lee las líneas de los argumentos de la línea de comandos y el carácter de STDIN.

El intérprete en línea no admite argumentos de línea de comandos, pero puede probar una versión equivalente aquí.

Explicación

ea    e# Get the lines from ARGV.
_rf#  e# Duplicate input, read the character and find index of character in each line.
_:e>  e# Duplicate indices and find maximum.
\fm   e# Subtract each index from the maximum index.
.{    e# Apply this block to each pair of line and (max_index - index).
  S*  e#   Get a string with the right amount of spaces.
  \N  e#   Swap spaces with line and push a line feed.
}

9

Pip , 22 20 18 + 1 = 19 bytes

Y_@?qMgsX(MXy)-y.g

Toma cadenas como argumentos de línea de comandos y delimitador de STDIN ( idea tomada de la respuesta CJam de Martin ). Utiliza la -nbandera para imprimir valores de salida en líneas separadas.

                    g is list of cmdline args; s is space (implicit)
    q               Read the delimiter from stdin
 _@?                Construct a lambda function that takes a string and returns
                       the index of the delimiter in it
     Mg             Map that function to each remaining item in g
Y                   Yank the resulting list of indices into the variable y

         (MXy)-y    Take the max of y minus each element in y
       sX           Space, repeated that many times...
                .g  ... concatenated to each item in g
                    Print, newline-separated (implicit, -n flag)

Y un ejemplo de ejecución:

C:\Users\dlosc> pip.py -ne Y_@?qMgsX(MXy)-y.g "Programming, Puzzles" "And, Code golf"
,
Programming, Puzzles
        And, Code golf

7

JavaScript ES 2015, 113 bytes

f=(c,s)=>s.split`
`.map((e,_,a)=>' '.repeat(a.map(j=>j.indexOf(c)).reduce((g,h)=>g>h?g:h)-e.indexOf(c))+e).join`
`

No es tan corto como los idiomas de golf publicados hasta ahora. Toma la entrada como dos argumentos de función, por ejemplo f(',','Programming, Puzzles\nAnd, Code golf'). El fragmento a continuación no tiene golf e incluye un método fácil de probar.

f=function(c,s){
  return s
    .split('\n')
    .map(function(e,_,a){
      return ' '.repeat(
        a.map(function(f){
          return f.indexOf(c)
        }).reduce(function(g,h){
          return g>h?g:h
        })-e.indexOf(c)
      )+e
    })
    .join('\n')
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('char').value,document.getElementById('string').value)};document.getElementById('run').onclick=run;run()
<label>Character: <input type="text" id="char" value="," maxlength="1" /></label>
<textarea id="string" rows="4" cols="30" style="display:block">
Programming, Puzzles
And, Code Golf</textarea><button id="run">Run</button><br />
<pre id="output"></pre>



5

Julia, 117 bytes

f(c,t)=(s=[split(l,c)for l=split(t,"\n")];join(map(i->lpad(i[1],maximum(map(i->length(i[1]),s))," ")*c*i[2],s),"\n"))

Sin golf:

function f(c::String, t::String)
    # Create an array of arrays by splitting on newlines and
    # then on the given delimiter
    s = [split(l, c) for l in split(t, "\n")]

    # Find the maximum length on the left side of the delimiter
    m = maximum(map(i -> length(i[1]), s))

    # Rejoin on the delimiter and pad each line with spaces,
    # and rejoin this with newlines
    join(map(i -> lpad(i[1], m, " ") * d * i[2], s), "\n")
end

5

Python 3, 85 (IDLE 3.2.2, Windows)

c,*s=input().split('\n')
for x in s:print(' '*(max(z.find(c)for z in s)-x.find(c))+x)

Muy claro. Esto encuentra la posición del personaje en la cadena dos veces: una para encontrar el máximo (bueno, una vez por línea), y una vez para encontrar el desplazamiento. Traté de combinar estos pero fue más largo.

Python 3 se usa para desempaquetar la entrada. MY IDLE parece tomar cadenas multilínea como entrada.


@DLosc funciona para mí en IDLE pegando en una cadena multilínea.
xnor

Hmm Cuando hago eso (IDLE 3.3.4, Windows 7), cobtiene el delimitador y sobtiene una lista vacía. Llamadas posteriores para input()devolver las líneas restantes una por una.
DLosc

@DLosc Strange. Estoy copiando y pegando la cadena directamente desde mi navegador en el indicador de espera. ¿Estás haciendo lo mismo? IDLE 3.2.2, Windows 7 en caso de que sea importante.
xnor

Mismo. Aquí hay una captura de pantalla ...
DLosc

@DLosc Todavía funciona para mí ( captura de pantalla ). Aunque no entiendo lo que está sucediendo, voy a decir que este es un comportamiento específico del compilador o del entorno , y lo edité para tratar de especificar la información relevante. La versión de la función es 3 caracteres más larga en Python 2.
xnor

3

Jalea , 12 bytes

Ỵ©w€µạṀ⁶ẋż®Y

Pruébalo en línea!

Dado y golfed con coinheringaahing caird en J Elly H yper T lluvia (JHT) , nuestra práctica sala de chat jalea.

Cómo funciona

El tercer argumento de línea de comando (primera entrada) debería ser la cadena de varias líneas, y el carácter debería ser el cuarto argumento de línea de comando (segunda entrada).

Ỵ © w € µạṀ⁶ẋż®Y ~ Programa completo.

Ỵ ~ Dividir la cadena por nuevas líneas.
 © ~ Copie el resultado en el registro.
  w € ~ Obtenga el índice de la primera aparición del carácter en cada línea.
      Ṁ ~ Toma el máximo.
    µạ ~ Y restarlo de cada índice, tomando el valor absoluto.
       ⁶ẋ ~ Repite un espacio que muchas veces (vectoriza).
         ż® ~ Intercalar con lo que estaba almacenado en el registro.
           Y ~ Únete por nuevas líneas e imprime implícitamente.

No estoy seguro de si se permite tomar entradas como una lista de líneas, por lo que esto toma una cadena de varias líneas como entrada. Si se permitiera:

10 bytes

w€µạṀ⁶ẋż³Y

Pruébalo en línea!


1
es entonces cuando sabes que has creado una habitación exitosa
Erik the Outgolfer

2

Matlab / Octave, 106 bytes

Función que usa tres argumentos separados para carácter, cadena, cadena; y da resultado en stdout:

function f(c,s,t)
p=find(s==c)-find(t==c);disp([repmat(32,1,max(-p,0)) s]),disp([repmat(32,1,max(p,0)) t])

Ejemplo en Matlab:

>> f(',', 'Programming, Puzzles', 'And, Code golf')
Programming, Puzzles
        And, Code golf

O pruébelo en línea con el intérprete Octave.


2

Julia, 80 bytes

f(c,s)=(t=split(s,'
');u=[search(i,c)for i=t];join([" "].^(maxabs(u)-u).*t,'
'))

Sin golf:

function f(c,s)
  # converts multiline string to array of single-line strings
  t=split(s,'\n')

  # creates array of positions of delimiter
  u=[search(i,c)for i=t]

  # Appends appropriate number of spaces to each line
  # (uses elementwise operations to achieve this result)
  v=[" "].^(maxabs(u)-u).*t

  # Recombines array of strings to multiline string and returns
  return join(v,'\n')
end

2

JavaScript (ES6), 105

Usando cadenas de plantilla, las 2 nuevas líneas son significativas y contadas.

Pruebe a ejecutar el fragmento en cualquier navegador compatible con EcmaScript 6 (es decir, FireFox. Chrome no admite parámetros predeterminados)

f=(s,c,p=(s=s.split`
`).map(r=>m<(v=r.indexOf(c))?m=v:v,m=0))=>s.map((r,i)=>' '.repeat(m-p[i])+r).join`
`

// Ungolfed
f=(s,c)=>{
  s=s.split('\n')
  p=s.map(r=>r.indexOf(c))
  m=Math.max(...p)
  s=s.map((r,i)=>' '.repeat(m-p[i])+r)
  return s.join('\n')
}  

// TEST
out=x=>O.innerHTML+=x+'\n'

out(f(`Programming, Puzzles
And, Code golf`,','))
<pre id=O></pre>


2

Python 2, 93 bytes

def f(x,y,z):
 p=y.index(x)-z.index(x)
 if p<0:y=" "*abs(p)+y
 else:z=" "*p+z
 print y+'\n'+z

Llamado así:

f(',','Programming, Puzzles','And, Code Golf')

2

C # 4.0, 329 , 320, 307 bytes

using System;class P{static void Main(){Func<char,dynamic>f=(d)=>Console.ReadLine().Split(d);var c=f(' ')[0][0];var m=0;var l=new string[9999][];var z=0;for (l[z]=f(c);l[z].Length==2;l[z]=f(c)){m=Math.Max(l[z][0].Length,m);z++;}for(var i=0;i<z;i++){Console.WriteLine("{0,"+m+"}"+c+"{1}",l[i][0],l[i][1]);}}}

Versión sin golf:

using System;
class P
{
    static void Main()
    {
        // lamba to to read a line and split on a char, returns an array of 
        Func<char,dynamic>f=(d)=>Console.ReadLine().Split(d); 
        // read the separator char by taking the first char of the first string 
        // in the array
        // use our lambda
        var c=f(' ')[0][0];
        var m=0; // max position where char is found
        var l=new string[9999][]; // hold all input
        var z=0; // count valid entries in l
        // loop until the input doesn't contain an
        // array with 2 elements
        // here we use our lambda agian, twice
        for (l[z]= f(c);l[z].Length==2;l[z] = f(c))
        {
            // calculate max, based on length 
            // of first element from the string array
            m=Math.Max(l[z][0].Length,m);
            z++; // increase valid items
        }
        // loop over all valid items
        for(var i=0;i<z;i++)
        {
        // use composite formatting with the padding option
        // use the max to create a format string, when max =4 
        // and seperator char is , this will give
        // "{0,4},{1}"
            Console.WriteLine("{0,"+ m +"}"+c+"{1}",l[i][0],l[i][1]);
        }
    }
}

Acepta un máximo de 9999 líneas ...


2

Dyalog APL , 22 20 16 bytes

-4 gracias a ngn.

APL en realidad no es tan malo en el procesamiento de cadenas, si se le permite trabajar con matrices. En este desafío, podemos elegir el formato más apropiado, que para APL significa un vector de vectores de texto como argumento izquierdo, y el delimitador como argumento escalar derecho. Esto incluso maneja múltiples delimitadores por línea, y alinea el primero de cada línea.

⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨

⊣,¨⍨ anteponer cada línea con

' '⍴¨⍨ tantos espacios como

⌈.⍳ el índice más a la derecha del personaje entre las líneas

- menos

⍳¨ el índice del personaje en cada línea

¡Prueba APL en línea! ( agregado a la salida de impresión verticalmente)

¿Prima? Funciona para cualquier número de cadenas y delimitadores (se alinea por el extremo izquierdo).


⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨
ngn

Sí, por supuesto.
Adám

1

C #, 191

Como una función. Aproximadamente un portado de mi respuesta JS.

using System.Linq;string f(string s,char c){var q=s.Split('\n');int m=0,v;Array.ForEach(q,x=>m=m<(v=x.IndexOf(c))?v:m);return String.Join("\n",q.Select(x=>new String(' ',m-x.IndexOf(c))+x));}

1

Ruby, 74 bytes

l=lambda{|d,s|s.each{|e|puts ' '*(s.map{|f|f.index(d)}.max-e.index(d))+e}}

y llámalo como

l.call ',',['Programming, Puzzles','And, Code golf']

1

R, 68 bytes

function(c,x,y,r=regexpr)cat(x,"\n",rep(" ",r(c,x)-r(c,y)),y,sep="")

Función sin nombre que toma 3entradas; ccuál es el carácter a alinear, xes la primera cadena y yla segunda cadena.

En R, la función regexprdevuelve la posición de un patrón dado en una cadena. La solución funciona mediante la aplicación regexpren ambas cadenas y repitiendo espacios en blanco equivalentes a la diferencia y, posteriormente, solo imprime ambas entradas separadas por una nueva línea.


0

Python 2, 67 66 bytes

def a(d,l):
 i=l[0].index(d)
 for e in l:print' '*(i-e.index(d))+e

Llamado con:

a(',', ['Programming, Puzzles', 'And, Code golf'])

0

Moonscript, 138 bytes

(n)=>
 i=0
 @='
'..@
 l=[b-a for a,b in @gmatch "
().-()"..n]
 m=math.max unpack l
 (@gsub '
',(a)->
  i=i+1
  a..(' ')\rep m-l[i])\sub(2)

Esto devuelve una función que toma 2 argumentos. El primero es la cadena, el segundo es el carácter para alinear. Estos argumentos son el argumento implícito @, y n.

Primero, agrego una nueva línea a la cadena, para facilitar el procesamiento.

@='
'..@

Ahora, genero una lista de las posiciones de cada carácter de alineación, usando gmatch. Luego, reemplazo la nueva línea antes de cada línea con el número correcto de espacios, luego recorto la nueva línea que agregué al principio.


0

Lua, 169 bytes

function a(d,t)m={}for k,v in pairs(t)do m[#m+1]=string.find(v,d)end o=math.max(unpack(m))for k,v in pairs(t)do print(string.rep(" ",o-(string.find(v,d)or 0))..v)end end

No es tan breve como otras respuestas, pero esta es la primera: D


0

Retina , 71 bytes

+`^((.)(.*¶)*)((.)*\2.*¶)((?<-5>.)*(?(5)\2|(.)\2).*)
$1$#7$* $4$#5$* $6

Pruébalo en línea! Nota: Esto deja el carácter de alineación en la salida; Se puede eliminar a un costo de 4 bytes. Si solo hay que alinear dos cadenas, entonces para 52 bytes:

^(.)¶((.)*\1.*¶)((?<-3>.)*(.)*\1.*)
$#5$* $2$#3$* $4

Explicación:

^(.)¶

Esto coincide con el carácter de alineación.

((.)*\1.*¶)

Esto coincide con la primera línea y también realiza un seguimiento de cuántos caracteres había antes del carácter de alineación. (.NET mantiene una pila de coincidencias para cada variable, en este caso, $3).

((?<-3>.)*(.)*\1.*)

Esto coincide con la segunda línea, tratando de dar cuenta de tantos caracteres como encontramos en la primera línea. ?<-3>hace que la coincidencia haga estallar la pila para cada personaje, hasta que esté vacía, en cuyo punto la coincidencia falla, y (.)*luego coincide con los caracteres restantes antes del carácter de alineación. En este punto tenemos las siguientes variables:

  • $1 contiene el carácter de alineación
  • $2 contiene la primera línea
  • $3 contiene una pila cuya longitud es el prefijo de la primera línea menos el prefijo de la segunda línea
  • $4 contiene la segunda línea
  • $5 contiene una pila cuya longitud es el prefijo de la segunda línea menos el prefijo de la primera línea

$#5$*luego prefijos el número necesario de espacios para que la primera línea se alinee con la segunda, y viceversa para $#3$*.

Una lógica similar se aplica a la respuesta principal, excepto que aquí tenemos que encontrar dos líneas que no se alinean para que podamos alinearlas (aquí es donde ?(5)entra) y luego repetir la alineación sobre todas las líneas hasta que todas estén igualmente alineadas .


0

Lisp común, 101 bytes

(lambda(c l)(dolist(x l)(format t"~,,v@a~%"(-(apply'max(mapcar(lambda(x)#1=(position c x))l))#1#)x)))

El primer parámetro es el carácter, el segundo es una lista de cadenas a alinear.

Pruébalo en línea!

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.