Linee di allineamento!


31

Linee di allineamento!

Dato un carattere e una stringa multilinea, il tuo compito è quello di riempire ogni riga della stringa in modo che si allineino tra il delimitatore specificato.

Esempi

Ingresso:

,
Programming, Puzzles
And, Code golf

Produzione:

Programming, Puzzles
        And, Code golf

Ingresso

L'input sarà una stringa multilinea e un carattere (tra cui ti allineerai), puoi prenderli in qualsiasi ordine / formato desideri. Il personaggio apparirà esattamente una volta per riga. Ogni riga dell'ingresso può avere una lunghezza diversa.

L'input può avvenire tramite argomenti di funzione o STDIN.

Produzione

L'output deve essere centrato sulla stessa stringa. È consentita una nuova riga finale e nessuno spazio vuoto finale.

L'output deve essere riempito con la quantità minima di spazi. Non è possibile rimuovere spazi vuoti iniziali nell'input (se esiste).

L'uscita può essere dal ritorno di funzione o STDOUT.


L'input in un programma completo può provenire da argomenti della riga di comando o è proibito?
DLosc,

@DLosc Sì, certo
Downgoat,

1. Per gli argomenti della funzione / riga di comando, dovremmo leggere una singola stringa o una riga per argomento sarebbe ammissibile? 2. Dobbiamo riempire le linee con la minima quantità di spazi?
Dennis,

@Dennis Puoi prenderlo in una sola stringa. O una riga per argomento. "puoi prenderli nell'ordine che desideri" . Sì, devi riempire le linee con la minima quantità di spazi.
Modificherò

@vihan Le funzioni possono contenere una riga per argomento?
xnor,

Risposte:



13

APL (37)

L'APL non è molto bravo nell'elaborazione delle stringhe (o non sono bravo nel golf, ovviamente).

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

Questo prende il carattere come argomento di sinistra e la stringa multilinea come argomento di destra. Si presume che le estremità multilinea stringa in un avanzamento riga (ad esempio A\nB\nC\n, piuttosto che A\nB\nC.) Dal momento che posso utilizzare "qualsiasi formato [I] desiderio", e questo è anche il formato tradizionale per i file di testo, credo che questo sia ragionevole.

Spiegazione:

  • S←⌽⍵: inverti la stringa e memorizzala in S.
  • R←S⊂⍨S=⊃S: dividi Sil suo primo carattere e archivia l'array di stringhe R.
  • ⍺⍳¨⌽¨R: inverti ciascuna stringa Re poi trova l'indice di ⍺ (il carattere) in ogni stringa.
  • (⌈/-+): sottrarre ciascuno degli indici dall'indice più grande, fornendo la quantità di spazi necessari
  • ' '/⍨¨: per ciascuno di questi valori, genera tanti spazi
  • R,¨: aggiungi gli spazi a ciascuna stringa in R.
  • : unisci tutte le stringhe insieme
  • : inverti (per ripristinare l'ordine originale)

Esempio:

      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 byte

Grazie a Dennis per aver salvato 2 byte.

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

Questo legge le righe dagli argomenti della riga di comando e il carattere da STDIN.

L'interprete online non supporta gli argomenti della riga di comando, ma puoi testare una versione equivalente qui.

Spiegazione

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 byte

Y_@?qMgsX(MXy)-y.g

Prende stringhe come argomenti della riga di comando e delimitatore da STDIN ( idea presa in prestito dalla risposta CJam di Martin ). Utilizza -nflag per stampare i valori di output su righe separate.

                    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 un esempio:

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 byte

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

Non abbastanza breve come le lingue del golf pubblicate finora. Accetta input come due argomenti di funzione, ad es f(',','Programming, Puzzles\nAnd, Code golf'). Lo snippet di seguito è ungolfed e include un metodo semplice per testare.

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 byte

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)

Abbastanza diretto. Questo trova la posizione del carattere nella stringa due volte: una volta per trovare il massimo (bene, una volta per riga) e una volta per trovare l'offset. Ho provato a combinarli ma è stato più lungo.

Python 3 viene utilizzato per il disimballaggio dell'input. MY IDLE sembra prendere stringhe multilinea come input.


@DLosc Funziona per me in IDLE incollando in una stringa multilinea.
xnor,

Hmm. Quando lo faccio (IDLE 3.3.4, Windows 7), cottiene il delimitatore e sottiene un elenco vuoto. Chiamate successive per input()restituire le linee rimanenti una per una.
DLosc,

@DLosc Strange. Sto copiando e incollando la stringa direttamente dal mio browser nel prompt Idle. Stai facendo lo stesso? IDLE 3.2.2, Windows 7 nel caso in cui sia importante.
xnor,

Stesso. Ecco uno screenshot ...
DLosc,

@DLosc Funziona ancora per me ( screenshot ). Anche se non capisco cosa stia succedendo, sto per dire che si tratta di un compilatore o di un comportamento specifico dell'ambiente e ho modificato per provare a specificare le informazioni pertinenti. La versione della funzione è più lunga di 3 caratteri in Python 2.
xnor

3

Gelatina , 12 byte

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

Provalo online!

Effettuata e giocata a golf con il caos coinheringaahing in J elly H yper T Piove (JHT) , la nostra chat room per la pratica della Jelly.

Come funziona

Il terzo argomento della riga di comando (primo input) dovrebbe essere la stringa multilinea e il carattere dovrebbe essere il quarto argomento della riga di comando (secondo input).

W © w € µạṀ⁶ẋż®Y ~ Programma completo.

Split ~ Dividi la stringa per newline.
 © ~ Copia il risultato nel registro.
  w € ~ Ottieni l'indice della prima occorrenza del personaggio su ogni riga.
      Ṁ ~ Prendi il massimo.
    µạ ~ E sottralo da ciascun indice, prendendo il valore assoluto.
       ⁶ẋ ~ Ripeti uno spazio molte volte (vettorializza).
         ż® ~ Interlaccia con ciò che è stato memorizzato nel registro.
           Y ~ Partecipa con le nuove righe e stampa implicitamente.

Non sono sicuro che sia consentito prendere input come elenco di righe, quindi questo richiede una stringa multilinea come input. Se fosse permesso:

10 byte

w€µạṀ⁶ẋż³Y

Provalo online!


1
è allora che sai di aver creato una stanza di successo
Erik the Outgolfer il

2

Matlab / Octave, 106 byte

Funzione che utilizza tre argomenti separati per carattere, stringa, stringa; e dà il risultato in 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])

Esempio in Matlab:

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

Oppure provalo online con l'interprete Octave.


2

Julia, 80 byte

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

Utilizzando le stringhe modello, le 2 nuove righe sono significative e contate.

Prova a eseguire lo snippet in qualsiasi browser compatibile con EcmaScript 6 (ovvero FireFox. Chrome non supporta i parametri predefiniti)

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 byte

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

Chiamato così:

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

2

C # 4.0, 329 320 307 byte

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

Versione non golfata:

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

Accetta un massimo di 9999 righe ...


2

Dyalog APL , 22 20 16 byte

-4 grazie a ngn.

APL in realtà non è poi così male nell'elaborazione delle stringhe, se consentito lavorare con array. In questa sfida, possiamo scegliere il formato più appropriato, che per APL significa un vettore di vettori di testo come argomento di sinistra e il delimitatore come argomento di scala scalare. Questo gestisce anche più delimitatori per riga e allinea il primo di ogni riga.

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

⊣,¨⍨ anteporre ogni riga con

' '⍴¨⍨ tanti spazi quanti

⌈.⍳ l'indice più a destra del personaggio tra le righe

- meno

⍳¨ l'indice del carattere in ciascuna riga

Prova APL online! ( aggiunto all'output di stampa in verticale)

Bonus? Funziona con qualsiasi numero di stringhe e delimitatori (allineato all'estrema sinistra).


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

Sì, naturalmente.
Adám,

1

C #, 191

Come una funzione. Circa un porting della mia risposta 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

Rubino, 74 byte

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

e chiamalo come

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

1

R, 68 byte

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

Funzione senza nome che accetta 3input; cche è il carattere da allineare, xè la prima stringa e yla seconda stringa.

In R, la funzione regexprrestituisce la posizione di un dato modello in una stringa. La soluzione funziona applicando regexprsu entrambe le stringhe e ripetendo spazi bianchi pari alla differenza e successivamente stampa entrambi gli input separati da una nuova riga.


0

Python 2, 67 66 byte

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

Chiamato con:

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

0

Moonscript, 138 byte

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

Ciò restituisce una funzione che accetta 2 argomenti. La prima è la stringa, la seconda è il carattere su cui allinearsi. Questi argomenti sono l'argomento implicito @ e n.

Innanzitutto, aggiungo una nuova riga alla stringa, per facilitare l'elaborazione.

@='
'..@

Ora, creo un elenco delle posizioni di ogni carattere di allineamento, usando gmatch. Quindi, sostituisco la nuova riga prima di ogni riga con il numero corretto di spazi, quindi taglio la nuova riga aggiunta all'inizio.


0

Lua, 169 byte

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

Non breve come le altre risposte, ma questa è la mia prima: D


0

Retina , 71 byte

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

Provalo online! Nota: questo lascia il carattere di allineamento nell'output; può essere eliminato al costo di 4 byte. Se è necessario allineare solo due stringhe, quindi per 52 byte:

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

Spiegazione:

^(.)¶

Questo corrisponde al carattere di allineamento.

((.)*\1.*¶)

Questo corrisponde alla prima riga e tiene anche traccia di quanti caratteri c'erano prima del carattere di allineamento. (.NET mantiene uno stack di corrispondenza per ogni variabile, in questo caso $3.)

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

Questo corrisponde alla seconda riga, cercando di rendere conto di quanti caratteri abbiamo trovato sulla prima riga. ?<-3>fa sì che la corrispondenza faccia apparire la pila per ogni personaggio, fino a quando non è vuota, a quel punto la corrispondenza fallisce e (.)*quindi corrisponde ai caratteri rimanenti prima del carattere di allineamento. A questo punto abbiamo le seguenti variabili:

  • $1 contiene il carattere di allineamento
  • $2 contiene la prima riga
  • $3 contiene uno stack la cui lunghezza è il prefisso della prima riga meno il prefisso della seconda riga
  • $4 contiene la seconda riga
  • $5 contiene uno stack la cui lunghezza è il prefisso della seconda riga meno il prefisso della prima riga

$#5$* quindi prefigura il numero necessario di spazi per allineare la prima riga con la seconda e viceversa $#3$* .

Una logica simile si applica alla risposta principale, tranne qui dobbiamo trovare due linee che non si allineano in modo da poterle allineare (qui è dove ?(5)entra) e quindi ripetere l'allineamento su tutte le linee fino a quando non sono tutte ugualmente allineate .


0

Lisp comune, 101 byte

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

Il primo parametro è il carattere, il secondo è un elenco di stringhe da allineare.

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.