Alinhando linhas!


31

Alinhando linhas!

Dado um caractere e uma sequência de linhas múltiplas, seu trabalho é preencher cada linha da sequência para que elas se alinhem entre o delimitador fornecido.

Exemplos

Entrada:

,
Programming, Puzzles
And, Code golf

Saída:

Programming, Puzzles
        And, Code golf

Entrada

A entrada será uma cadeia de linhas múltiplas e um caractere (no qual você alinhará), você pode levá-los em qualquer ordem / formato que desejar. O personagem aparecerá exatamente uma vez por linha. Cada linha da entrada pode ter um comprimento diferente.

A entrada pode ser por meio de argumentos de função ou STDIN.

Saída

A saída deve ser a mesma string centralizada. Você tem uma nova linha à direita e nenhum espaço em branco à direita.

A saída deve ser preenchida com a quantidade mínima de espaços. Você não pode remover nenhum espaço em branco à esquerda na entrada (se existir).

A saída pode ser do retorno da função ou STDOUT.


A entrada para um programa completo é proveniente de argumentos da linha de comando ou isso é proibido?
DLosc

@DLosc Sim, é claro
Downgoat 12/09/2015

1. Para argumentos de função / linha de comando, devemos ler uma única string ou uma linha por argumento é admissível? 2. Temos que preencher as linhas com a quantidade mínima de espaços?
Dennis

@ Dennis Você pode levá-lo em uma única string. Ou uma linha por argumento. "você pode tomá-los em qualquer ordem que desejar" . Sim, você precisa preencher as linhas com a quantidade mínima de espaços. Vou editar as especificações
Downgoat

@vihan As funções podem ter uma linha por argumento?
xnor

Respostas:



13

APL (37)

APL simplesmente não é muito bom no processamento de strings (ou eu não sou bom em golfe, é claro).

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

Isso leva o caractere como argumento à esquerda e a cadeia de linhas múltiplas como argumento à direita. Supõe-se que a cadeia de linhas múltiplas termine com um avanço de linha (por exemplo, em A\nB\nC\nvez de A\nB\nC.) Como eu posso usar "qualquer formato [I] desejo", e esse também é o formato convencional para arquivos de texto, acho que isso é razoável.

Explicação:

  • S←⌽⍵: inverta a string e armazene-a S.
  • R←S⊂⍨S=⊃S: divida Sem seu primeiro caractere e armazene a matriz de seqüências de caracteres R.
  • ⍺⍳¨⌽¨R: inverta cada sequência Re encontre o índice de ⍺ (o caractere) em cada sequência.
  • (⌈/-+): subtraia cada um dos índices do maior índice, fornecendo a quantidade de espaços necessários
  • ' '/⍨¨: para cada um desses valores, gere esse número de espaços
  • R,¨: adicione os espaços a cada sequência R.
  • : juntar todas as cordas
  • : inverta (para recuperar o pedido original)

Exemplo:

      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

Agradecimentos a Dennis por salvar 2 bytes.

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

Isso lê as linhas dos argumentos da linha de comando e o caractere de STDIN.

O intérprete online não suporta argumentos de linha de comando, mas você pode testar uma versão equivalente aqui.

Explicação

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 seqüências de caracteres como argumentos de linha de comando e delimitador de STDIN ( ideia emprestada da resposta CJam de Martin ). Usa -nsinalizador para imprimir valores de saída em linhas 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)

E um exemplo de execução:

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`
`

Não é tão curto quanto os idiomas de golfe publicados até agora. Aceita entrada como dois argumentos de função, por exemplo f(',','Programming, Puzzles\nAnd, Code golf'). O trecho de código abaixo é simples e inclui um método fácil de testar.

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

Ungolfed:

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)

Bem direto. Ele encontra a posição do caractere na string duas vezes: uma vez para encontrar o máximo (bem, uma vez por linha) e uma vez para encontrar o deslocamento. Eu tentei combinar isso, mas foi mais longo.

Python 3 é usado para descompactar a entrada. MY IDLE parece ter seqüências de linhas múltiplas como entrada.


O @DLosc funciona para mim na colagem IDLE em uma sequência de múltiplas linhas.
xnor

Hmm. Quando faço isso (IDLE 3.3.4, Windows 7), cobtém o delimitador e suma lista vazia. Chamadas subsequentes para input()retornar as linhas restantes, uma a uma.
DLosc

@DLosc Strange. Estou copiando e colando a string diretamente do meu navegador no prompt Idle. Você está fazendo o mesmo? IDLE 3.2.2, Windows 7, caso isso importe.
xnor

Mesmo. Aqui está uma captura de tela ...
DLosc 12/09/2015

@DLosc Ainda funciona para mim ( captura de tela ). Embora eu não entenda o que está acontecendo, vou dizer que esse é um comportamento específico do compilador ou do ambiente e editei para tentar especificar as informações relevantes. A versão da função tem 3 caracteres a mais no Python 2.
xnor

3

Gelatina , 12 bytes

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

Experimente online!

Feito e golfed com coinheringaahing caird em J elly H Yper T chover (JHT) , a nossa prática sala de chat geléia.

Como funciona

O terceiro argumento da linha de comando (primeira entrada) deve ser a sequência de várias linhas e o caractere deve ser o quarto argumento da linha de comando (segunda entrada).

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

Split ~ Divida a string por novas linhas.
 © ~ Copie o resultado no registro.
  w € ~ Obtenha o índice da primeira ocorrência do caractere em cada linha.
      Take ~ Tire o máximo.
    µ And ~ E subtraia-o de cada índice, assumindo o valor absoluto.
       Rep ~ Repita um espaço tantas vezes (vetorize).
         Interleave com o que foi armazenado no registro.
           Y ~ Junte-se a novas linhas e imprima implicitamente.

Não tenho certeza se a entrada de entrada como uma lista de linhas é permitida, portanto, isso exige uma seqüência de linhas múltiplas como entrada. Se fosse permitido:

10 bytes

w€µạṀ⁶ẋż³Y

Experimente online!


1
é quando você sabe que criou uma sala de sucesso
Erik the Outgolfer

2

Matlab / Octave, 106 bytes

Função que usa três argumentos separados para caractere, sequência, sequência; e dá resultado em 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])

Exemplo no Matlab:

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

Ou tente online com o 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,'
'))

Ungolfed:

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 seqüências de caracteres de modelo, as duas novas linhas são significativas e contadas.

Teste a execução do snippet em qualquer navegador compatível com EcmaScript 6 (que é o FireFox. O Chrome não suporta parâmetros padrão)

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

Chamado assim:

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]);}}}

Versão não destruída:

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]);
        }
    }
}

Aceita no máximo 9999 linhas ...


2

Dyalog APL , 22 20 16 bytes

-4 graças a ngn.

O APL, na verdade, não é tão ruim no processamento de strings, se for permitido trabalhar com matrizes. Nesse desafio, podemos escolher o formato mais apropriado, que para APL significa um vetor de vetores de texto como argumento à esquerda e o delimitador como um argumento à direita escalar. Isso até lida com vários delimitadores por linha e alinha o primeiro de cada linha.

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

⊣,¨⍨ acrescente cada linha com

' '⍴¨⍨ tantos espaços quanto

⌈.⍳ o índice mais à direita do caractere entre as linhas

- menos

⍳¨ o índice do caractere em cada linha

Experimente o APL online! ( adicionado à saída de impressão verticalmente)

Bônus? Funciona para qualquer número de seqüências de caracteres e delimitadores (alinha pela esquerda).


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

Sim, claro.
Adám

1

C #, 191

Como uma função. Aproximadamente uma portabilidade da minha resposta 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}}

e chame assim

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="")

Função sem nome que recebe 3entradas; cqual é o caractere a alinhar, xé a primeira e ya segunda string.

Em R, a função regexprretorna a posição de um determinado padrão em uma sequência. A solução funciona aplicando regexprem ambas as strings e repetindo espaços em branco que equivalem à diferença e, posteriormente, apenas imprima ambas as entradas separadas por uma nova linha.


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

Chamado com:

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)

Isso retorna uma função que recebe 2 argumentos. O primeiro é a string, o segundo é o caractere a ser alinhado. Esses argumentos são o argumento implícito @ e n.

Primeiro, anexo uma nova linha à string, para facilitar o processamento.

@='
'..@

Agora, eu gero uma lista das posições de cada caractere de alinhamento usando gmatch. Em seguida, substituo a nova linha antes de cada linha pelo número correto de espaços e apare a nova linha que adicionei no início.


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

Não é tão curto quanto as outras respostas, mas esta é a minha primeira: D


0

Retina , 71 bytes

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

Experimente online! Nota: Isso deixa o caractere de alinhamento na saída; Ele pode ser excluído a um custo de 4 bytes. Se apenas duas cadeias precisarem ser alinhadas, então para 52 bytes:

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

Explicação:

^(.)¶

Isso corresponde ao caractere de alinhamento.

((.)*\1.*¶)

Isso corresponde à primeira linha e também controla quantos caracteres havia antes do caractere de alinhamento. (O .NET mantém uma pilha de correspondências para cada variável, neste caso $3,.)

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

Isso corresponde à segunda linha, tentando contabilizar o número de caracteres encontrado na primeira linha. ?<-3>faz com que a correspondência apareça a pilha de cada caractere, até que ela esteja vazia; nesse ponto, a correspondência falhará e, em (.)*seguida, corresponderá aos caracteres restantes antes do caractere de alinhamento. Neste ponto, temos as seguintes variáveis:

  • $1 contém o caractere de alinhamento
  • $2 contém a primeira linha
  • $3 contém uma pilha cujo comprimento é o prefixo da primeira linha menos o prefixo da segunda linha
  • $4 contém a segunda linha
  • $5 contém uma pilha cujo comprimento é o prefixo da segunda linha menos o prefixo da primeira linha

$#5$*prefixa o número necessário de espaços para alinhar a primeira linha com a segunda e vice-versa para $#3$*.

Lógica semelhante se aplica à resposta principal, exceto aqui temos que encontrar duas linhas que não se alinham para que possamos alinhá-las (é aqui que elas ?(5)entram) e depois repetir o alinhamento sobre todas as linhas até que todas estejam igualmente alinhadas .


0

Lisp comum, 101 bytes

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

O primeiro parâmetro é o caractere, o segundo é uma lista de cadeias a serem alinhadas.

Experimente online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.