Linien ausrichten!

31

Linien ausrichten!

Wenn Sie ein Zeichen und eine mehrzeilige Zeichenfolge haben, müssen Sie jede Zeile der Zeichenfolge so auffüllen, dass sie unter dem angegebenen Trennzeichen ausgerichtet sind.

Beispiele

Eingang:

,
Programming, Puzzles
And, Code golf

Ausgabe:

Programming, Puzzles
        And, Code golf

Eingang

Die Eingabe besteht aus einer mehrzeiligen Zeichenfolge und einem Zeichen (an dem Sie sich ausrichten). Sie können diese Zeichen in einer beliebigen Reihenfolge und in einem beliebigen Format eingeben. Das Zeichen wird genau einmal pro Zeile angezeigt. Jede Zeile der Eingabe kann unterschiedlich lang sein.

Die Eingabe kann über Funktionsargumente oder STDIN erfolgen.

Ausgabe

Die Ausgabe sollte die gleiche zentrierte Zeichenfolge sein. Sie dürfen eine nachgestellte Zeile und kein nachgestelltes Leerzeichen verwenden.

Die Ausgabe sollte mit der Mindestanzahl an Leerzeichen aufgefüllt werden. Sie dürfen keine führenden Leerzeichen in der Eingabe entfernen (falls vorhanden).

Die Ausgabe kann über Funktionsrückgabe oder STDOUT erfolgen.

Downgoat
quelle
Kann eine Eingabe in ein vollständiges Programm über Befehlszeilenargumente erfolgen oder ist dies verboten?
DLosc,
@ DLosc Ja, natürlich
Downgoat
1. Sollten wir für Funktions- / Befehlszeilenargumente eine einzelne Zeichenfolge lesen, oder wäre eine Zeile pro Argument zulässig? 2. Müssen wir die Zeilen mit möglichst wenig Leerzeichen auffüllen?
Dennis,
@ Tennis Sie können es in einer einzigen Zeichenfolge nehmen. Oder eine Zeile pro Argument. msgstr "Sie können diese in beliebiger Reihenfolge nehmen" . Ja, Sie müssen die Zeilen mit möglichst wenig Leerzeichen auffüllen. Ich werde die Spezifikation bearbeiten
Downgoat
@vihan Können Funktionen eine Zeile pro Argument aufnehmen?
Donnerstag,

Antworten:

5

Pyth, 18 Bytes

V.z+*d-eSxRz.zxNzN
orlp
quelle
13

APL (37)

APL ist einfach nicht sehr gut in der Verarbeitung von Saiten (oder ich bin natürlich nicht gut im Golfen).

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

Dabei wird das Zeichen als linkes Argument und die mehrzeilige Zeichenfolge als rechtes Argument verwendet. Es wird davon ausgegangen, dass die mehrzeilige Zeichenfolge in einem Zeilenumbruch endet (z . B. A\nB\nC\nstatt A\nB\nC.). Da ich "jedes gewünschte Format" verwenden kann und dies auch das herkömmliche Format für Textdateien ist, halte ich dies für sinnvoll.

Erläuterung:

  • S←⌽⍵: kehre die Zeichenfolge um und speichere sie in S.
  • R←S⊂⍨S=⊃S: Teilen Sie Sdas erste Zeichen auf und speichern Sie das Array der Zeichenfolgen in R.
  • ⍺⍳¨⌽¨R: Rkehre jeden String um und finde dann den Index von ⍺ (das Zeichen) in jedem String.
  • (⌈/-+): subtrahieren Sie jeden der Indizes vom größten Index und geben Sie die benötigte Menge an Speicherplätzen an
  • ' '/⍨¨: Generieren Sie für jeden dieser Werte so viele Leerzeichen
  • R,¨: füge die Leerzeichen zu jedem String in hinzu R.
  • : Füge alle Saiten zusammen
  • : umkehren (um die ursprüngliche Bestellung zurückzuerhalten)

Beispiel:

      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
Marinus
quelle
9

CJam, 23 22 20 Bytes

Vielen Dank an Dennis für das Speichern von 2 Bytes.

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

Dadurch werden die Zeilen aus Befehlszeilenargumenten und das Zeichen aus STDIN gelesen.

Der Online-Interpreter unterstützt keine Befehlszeilenargumente, aber Sie können hier eine entsprechende Version testen.

Erläuterung

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.
}
Martin Ender
quelle
9

Pip , 22 20 18 + 1 = 19 Bytes

Y_@?qMgsX(MXy)-y.g

Übernimmt Zeichenfolgen als Befehlszeilenargumente und Trennzeichen von STDIN ( Idee aus Martins CJam-Antwort ). Verwendet -nflag, um Ausgabewerte in separaten Zeilen auszudrucken.

                    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)

Und ein Beispiellauf:

C:\Users\dlosc> pip.py -ne Y_@?qMgsX(MXy)-y.g "Programming, Puzzles" "And, Code golf"
,
Programming, Puzzles
        And, Code golf
DLosc
quelle
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`
`

Nicht ganz so kurz wie die bisher geposteten Golfsprachen. Nimmt Eingaben als zwei Funktionsargumente an, z f(',','Programming, Puzzles\nAnd, Code golf'). Das folgende Snippet ist ungolfed und enthält eine einfache Methode zum Testen.

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>

NinjaBearMonkey
quelle
6

Pyth, 27 24 Bytes

V.z+.[deSmxdz.z<NJxNz>NJ

Aktualisiert für den neuesten Pyth .

Live-Demo.

27-Byte-Version

jbm+.[eSmxkz.z<dJxdz\ >dJ.z

Live-Demo.

kirbyfan64sos
quelle
Wann immer Sie jbmzu Beginn Ihrer Antwort sehen, sollten Sie sofort darüber nachdenken V.
Orlp
Oder entfernen Sie einfach dieb
Jakube
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
Alex A.
quelle
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)

Ziemlich einfach. Dadurch wird die Position des Zeichens in der Zeichenfolge zweimal ermittelt: einmal, um das Maximum zu ermitteln (also einmal pro Zeile) und einmal, um den Versatz zu ermitteln. Ich habe versucht, diese zu kombinieren, aber es war länger.

Python 3 wird zum Entpacken der Eingaben verwendet. MY IDLE scheint mehrzeilige Zeichenfolgen als Eingabe zu verwenden.

xnor
quelle
@ DLosc Funktioniert für mich beim IDLE-Einfügen in eine mehrzeilige Zeichenfolge.
Xnor
Hmm. Wenn ich das tue (IDLE 3.3.4, Windows 7), cerhält der Begrenzer und seine leere Liste. Nachfolgende Aufrufe, input()um die verbleibenden Zeilen einzeln zurückzugeben.
DLosc,
@ DLosc Seltsam. Ich kopiere die Zeichenfolge direkt aus meinem Browser in die Eingabeaufforderung Leerlauf. Machst du das selbe IDLE 3.2.2, Windows 7, falls es darauf ankommt.
Donnerstag,
Gleich. Hier ist ein Screenshot ...
DLosc
@ DLosc funktioniert immer noch für mich ( Screenshot ). Obwohl ich nicht verstehe, was los ist, werde ich sagen, dass dies compiler- oder umgebungsspezifisch ist , und ich habe es bearbeitet, um zu versuchen, die relevanten Informationen anzugeben. Die Funktion Version ist 3 Zeichen mehr in Python 2.
xnor
3

Gelee , 12 Bytes

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

Probieren Sie es online!

Fertig und golfed mit caird coinheringaahing in J Elly H yper T raining (JHT) , unsere Jelly Praxis Chat - Raum.

Wie es funktioniert

Das dritte Befehlszeilenargument (erste Eingabe) sollte die mehrzeilige Zeichenfolge sein, und das Zeichen sollte das vierte Befehlszeilenargument (zweite Eingabe) sein.

Ỵ © w € µạṀ⁶ẋż®Y ~ Volles Programm.

Ỵ ~ Teilen Sie die Zeichenfolge durch Zeilenumbrüche.
 © ~ Kopieren Sie das Ergebnis in das Register.
  w € ~ Ermittelt den Index des ersten Vorkommens des Zeichens in jeder Zeile.
      Ṁ ~ Nimm das Maximum.
    µạ ~ Und subtrahiere es von jedem Index und nehme den absoluten Wert.
       ⁶ẋ ~ Wiederhole ein Leerzeichen so oft (vektorisiert).
         ż® ~ Interleave mit dem, was im Register gespeichert war.
           Y ~ Fügen Sie Zeilenumbrüche hinzu und drucken Sie implizit.

Ich bin nicht sicher, ob die Eingabe als Liste von Zeilen zulässig ist, daher wird eine mehrzeilige Zeichenfolge als Eingabe verwendet. Wenn es erlaubt wäre:

10 Bytes

w€µạṀ⁶ẋż³Y

Probieren Sie es online!

Mr. Xcoder
quelle
1
Dann
2

Matlab / Octave, 106 Bytes

Funktion, die drei separate Argumente für Zeichen, Zeichenfolge, Zeichenfolge verwendet; und ergibt 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])

Beispiel in Matlab:

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

Oder versuchen Sie es online mit Octave Interpreter.

Luis Mendo
quelle
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
Glen O
quelle
2

JavaScript (ES6), 105

Unter Verwendung von Vorlagenzeichenfolgen werden die 2 Zeilenumbrüche signifikant und gezählt.

Testen Sie die Ausführung des Snippets in einem EcmaScript 6-kompatiblen Browser (dies ist FireFox. Chrome unterstützt keine Standardparameter).

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>

edc65
quelle
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

So heißt es:

f(',','Programming, Puzzles','And, Code Golf')
Alpha-Zerfall
quelle
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]);}}}

Ungolfed-Version:

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

Es akzeptiert maximal 9999 Zeilen ...

rene
quelle
2

Dyalog APL , 22 20 16 Bytes

-4 danke an ngn.

APL ist eigentlich gar nicht so schlecht bei der String-Verarbeitung, wenn man mit Arrays arbeiten darf. In dieser Herausforderung können wir das am besten geeignete Format auswählen, das für APL einen Vektor von Textvektoren als linkes Argument und den Begrenzer als skalares rechtes Argument bedeutet. Dies behandelt sogar mehrere Begrenzer pro Zeile und richtet das erste jeder Zeile aus.

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

⊣,¨⍨ stellen Sie jeder Zeile ein

' '⍴¨⍨ so viele Räume wie

⌈.⍳ der am weitesten rechts stehende Index des Zeichens zwischen den Zeilen

- Minus

⍳¨ der Index des Zeichens in jeder Zeile

APL online testen! ( hinzugefügt, um die Ausgabe vertikal zu drucken)

Bonus? Funktioniert für eine beliebige Anzahl von Zeichenfolgen und Begrenzern (wird ganz links ausgerichtet).

Adam
quelle
⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨
ngn
Ja natürlich.
Adám
1

C #, 191

Als eine Funktion. Grob eine Portierung meiner JS-Antwort.

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));}
edc65
quelle
1

Ruby, 74 Bytes

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

und nenne es wie

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

R, 68 Bytes

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

Unbenannte Funktion, die 3Eingaben entgegennimmt; cDas auszurichtende Zeichen xist die erste und ydie zweite Zeichenfolge.

In R gibt die Funktion regexprdie Position eines bestimmten Musters in einer Zeichenfolge zurück. Die Lösung besteht darin, regexprauf beide Zeichenfolgen anzuwenden und Leerzeichen in Höhe der Differenz zu wiederholen und anschließend beide Eingaben durch einen Zeilenumbruch getrennt zu drucken.

Billywob
quelle
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

Angerufen mit:

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

Mondschrift, 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)

Dies gibt eine Funktion zurück, die 2 Argumente akzeptiert. Das erste ist die Zeichenfolge, das zweite ist das Zeichen, an dem ausgerichtet werden soll. Diese Argumente sind das implizite Argument @ und n.

Zuerst füge ich der Zeichenfolge eine neue Zeile hinzu, um die Verarbeitung zu vereinfachen.

@='
'..@

Jetzt erstelle ich eine Liste der Positionen jedes Ausrichtungszeichens mit gmatch . Als nächstes ersetze ich die neue Zeile vor jeder Zeile durch die richtige Anzahl von Leerzeichen und schneide dann die neue Zeile ab, die ich am Anfang hinzugefügt habe.

Ryan Russell
quelle
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

Nicht so kurz wie andere Antworten, aber dies ist meine erste: D

Sygmei
quelle
0

Retina , 71 Bytes

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

Probieren Sie es online! Hinweis: Dadurch bleibt das Ausrichtungszeichen in der Ausgabe erhalten. Es kann zu einem Preis von 4 Bytes gelöscht werden. Wenn nur zwei Zeichenfolgen ausgerichtet werden müssen, gilt dies für 52 Byte:

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

Erläuterung:

^(.)¶

Dies entspricht dem Ausrichtungszeichen.

((.)*\1.*¶)

Dies entspricht der ersten Zeile und verfolgt auch, wie viele Zeichen es vor dem Ausrichtungszeichen gab. (.NET speichert in diesem Fall für jede Variable einen Übereinstimmungsstapel $3.)

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

Dies entspricht der zweiten Zeile und versucht, so viele Zeichen zu berücksichtigen, wie wir in der ersten Zeile gefunden haben. ?<-3>Bewirkt, dass die Übereinstimmung den Stapel für jedes Zeichen auffüllt, bis es leer ist. An diesem Punkt schlägt die Übereinstimmung fehl und (.)*die verbleibenden Zeichen vor dem Ausrichtungszeichen werden abgeglichen. Zu diesem Zeitpunkt haben wir die folgenden Variablen:

  • $1 Enthält das Ausrichtungszeichen
  • $2 enthält die erste Zeile
  • $3 enthält einen Stapel, dessen Länge dem ersten Zeilenpräfix minus dem zweiten Zeilenpräfix entspricht
  • $4 enthält die zweite Zeile
  • $5 enthält einen Stapel, dessen Länge dem zweiten Zeilenpräfix minus dem ersten Zeilenpräfix entspricht

$#5$*Dann wird die erforderliche Anzahl von Leerzeichen vorangestellt, damit die erste Zeile an der zweiten ausgerichtet wird, und umgekehrt für $#3$*.

Eine ähnliche Logik gilt für die Hauptantwort, mit der Ausnahme, dass wir hier zwei Linien finden müssen, die nicht ausgerichtet sind, damit wir sie ausrichten können (hier ?(5)kommt das an) und dann die Ausrichtung über alle Linien wiederholen, bis sie alle gleich ausgerichtet sind .

Neil
quelle
0

Common Lisp, 101 Bytes

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

Der erste Parameter ist das Zeichen, der zweite ist eine Liste der auszurichtenden Zeichenfolgen.

Probieren Sie es online!

Renzo
quelle