Wyrównanie linii!


31

Wyrównanie linii!

Biorąc pod uwagę znak i ciąg wielowierszowy, Twoim zadaniem jest wypełnienie każdej linii ciągu, aby znalazły się w linii między danym ogranicznikiem.

Przykłady

Wkład:

,
Programming, Puzzles
And, Code golf

Wydajność:

Programming, Puzzles
        And, Code golf

Wkład

Dane wejściowe będą ciągiem wieloliniowym i znakiem (do którego zostaną wyrównane), możesz je wziąć w dowolnej kolejności / formacie. Postać pojawi się dokładnie raz na linię. Każda linia wejścia może mieć inną długość.

Dane wejściowe mogą odbywać się za pomocą argumentów funkcji lub STDIN.

Wydajność

Dane wyjściowe powinny być wyśrodkowane na łańcuchach. Dozwolony jest jeden znak nowej linii i brak spacji.

Wyjście powinno być wypełnione minimalną ilością spacji. Nie można usunąć żadnych początkowych białych znaków na wejściu (jeśli istnieje).

Wyjście może pochodzić z funkcji return lub STDOUT.


Czy dane wejściowe do pełnego programu mogą pochodzić z argumentów wiersza poleceń, czy jest to zabronione?
DLosc

@DLosc Tak, oczywiście
Downgoat

1. Czy w przypadku argumentów funkcji / wiersza poleceń powinniśmy czytać pojedynczy ciąg znaków, czy dopuszczalny byłby jeden wiersz na argument? 2. Czy musimy wypełniać linie minimalną ilością spacji?
Dennis,

@Dennis Możesz wziąć to w jednym ciągu. Lub jeden wiersz na argument. „możesz je wziąć w dowolnej kolejności” . Tak, musisz uzupełnić linie minimalną ilością spacji. Zmienię specyfikację
Downgoat

@vihan Czy funkcje mogą przyjmować jeden wiersz na argument?
xnor

Odpowiedzi:



13

APL (37)

APL po prostu nie jest zbyt dobry w przetwarzaniu strun (lub oczywiście nie jestem dobry w golfie).

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

To traktuje znak jako lewy argument, a ciąg multilinii jako prawy argument. Zakłada się, że łańcuch wielowierszowy kończy się na wysunięciu wiersza (np. A\nB\nC\nZamiast A\nB\nC.) Ponieważ mogę użyć „dowolnego formatu, [który] chciałbym”, a jest to również konwencjonalny format dla plików tekstowych, myślę, że jest to uzasadnione.

Wyjaśnienie:

  • S←⌽⍵: odwróć ciąg i zapisz go w S.
  • R←S⊂⍨S=⊃S: podziel Sna pierwszy znak i zapisz tablicę ciągów R.
  • ⍺⍳¨⌽¨R: odwróć każdy ciąg R, a następnie znajdź indeks ⍺ (znak) w każdym ciągu.
  • (⌈/-+): odejmij każdy z indeksów od największego indeksu, podając ilość potrzebnych spacji
  • ' '/⍨¨: dla każdej z tych wartości wygeneruj tyle spacji
  • R,¨: dodaj spacje do każdego ciągu R.
  • : połącz wszystkie ciągi razem
  • : odwróć (aby odzyskać oryginalne zamówienie)

Przykład:

      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 bajtów

Dzięki Dennis za oszczędność 2 bajtów.

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

Odczytuje wiersze z argumentów wiersza poleceń i znak z STDIN.

Interpreter online nie obsługuje argumentów wiersza polecenia, ale tutaj możesz przetestować równoważną wersję.

Wyjaśnienie

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 bajtów

Y_@?qMgsX(MXy)-y.g

Bierze ciągi jako argumenty wiersza poleceń i ogranicznik ze STDIN ( pomysł zapożyczony z odpowiedzi Martina na CJam ). Używa -nflagi do drukowania wartości wyjściowych w osobnych wierszach.

                    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)

I przykładowy bieg:

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 bajtów

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

Nie tak krótkie, jak napisane do tej pory języki gry w golfa. Pobiera dane wejściowe jako dwa argumenty funkcji, np f(',','Programming, Puzzles\nAnd, Code golf'). Poniższy fragment kodu nie jest golfem i zawiera łatwą metodę testowania.

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 bajtów

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

Nie golfowany:

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)

Całkiem proste. Znajduje to pozycję znaku w ciągu dwa razy: raz, aby znaleźć maksimum (cóż, raz na linię), i raz, aby znaleźć przesunięcie. Próbowałem je połączyć, ale było dłużej.

Python 3 służy do rozpakowywania danych wejściowych. MOJE IDLE wydaje się przyjmować ciągi wielowierszowe jako dane wejściowe.


@DLosc Działa dla mnie przy wklejaniu w trybie IDLE w łańcuchu wielowierszowym.
xnor

Hmm Kiedy to zrobię (IDLE 3.3.4, Windows 7), cpobiera separator i spustą listę. Kolejne połączenia, aby input()zwrócić pozostałe linie jeden po drugim.
DLosc

@DLosc Strange. Kopiuję-wklejam ciąg bezpośrednio z mojej przeglądarki do monitu Bezczynności. Robisz to samo? IDLE 3.2.2, Windows 7 w razie potrzeby.
xnor

Podobnie. Oto zrzut ekranu ...
DLosc

@DLosc Nadal dla mnie działa ( zrzut ekranu ). Chociaż nie rozumiem, co się dzieje, powiem, że jest to zachowanie specyficzne dla kompilatora lub środowiska , i zredagowałem, aby spróbować podać odpowiednie informacje. Wersja funkcji jest o 3 znaki dłuższa w Pythonie 2.
xnor

3

Galaretka , 12 bajtów

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

Wypróbuj online!

Wykonane i grało w golfa z Cairnem Coheringaahing w J elly H yper T raining (JHT) , naszym pokoju do ćwiczeń Jelly.

Jak to działa

Trzeci argument wiersza poleceń (pierwsze wejście) powinien być ciągiem zawierającym wiele wierszy, a znak powinien być czwartym argumentem wiersza poleceń (drugie wejście).

Ỵ © w € µạṀ⁶ẋż®Y ~ Pełny program.

Ỵ ~ Podziel ciąg według nowego wiersza.
 © ~ Skopiuj wynik do rejestru.
  w € ~ Pobierz indeks pierwszego wystąpienia znaku w każdej linii.
      Take ~ Weź maksimum.
    µạ ~ I odejmij go od każdego indeksu, przyjmując wartość bezwzględną.
       ⁶ẋ ~ Powtórz spację, która wiele razy (wektoryzuje).
         ż® ~ Przeplataj z tym, co było zapisane w rejestrze.
           Y ~ Dołącz przez nowe linie i drukuj niejawnie.

Nie jestem pewien, czy przyjmowanie danych wejściowych jako listy linii jest dozwolone, więc bierze to wieloliniowy ciąg znaków jako dane wejściowe. Gdyby było dozwolone:

10 bajtów

w€µạṀ⁶ẋż³Y

Wypróbuj online!


1
wtedy wiesz, że stworzyłeś udany pokój
Erik the Outgolfer,

2

Matlab / Octave, 106 bajtów

Funkcja wykorzystująca trzy oddzielne argumenty dla znaku, łańcucha, łańcucha; i daje wynik w standardzie:

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

Przykład w Matlabie:

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

Lub wypróbuj online z tłumaczem Octave.


2

Julia, 80 bajtów

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

Nie golfowany:

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

Za pomocą ciągów szablonów 2 nowe znaki są znaczące i zliczane.

Przetestuj uruchomienie fragmentu w dowolnej przeglądarce zgodnej z EcmaScript 6 (czyli FireFox. Chrome nie obsługuje parametrów domyślnych)

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 bajty

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

Nazywany tak:

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

2

C # 4.0, 329 320 307 bajtów

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

Wersja bez golfa:

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

Akceptuje maksymalnie 9999 linii ...


2

Dyalog APL , 22 20 16 bajtów

-4 dzięki ngn.

APL nie jest tak zły w przetwarzaniu ciągów, jeśli wolno mu pracować z tablicami. W tym wyzwaniu możemy wybrać najbardziej odpowiedni format, który dla APL oznacza wektor wektorów tekstowych jako lewy argument, a separator jako prawy argument skalarny. To nawet obsługuje wiele ograniczników w linii i wyrównuje pierwszą z każdej linii.

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

⊣,¨⍨ wstaw każdą linię za pomocą

' '⍴¨⍨ tyle miejsc, ile

⌈.⍳ najbardziej prawy indeks znaku między wierszami

- minus

⍳¨ indeks znaku w każdej linii

Wypróbuj APL online! ( dodano do wydruku pionowo)

Premia? Działa dla dowolnej liczby ciągów znaków i ograniczników (wyrównuje do lewej).


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

Tak oczywiście.
Adám

1

C #, 191

Jako funkcja. Z grubsza przeniesienie mojej odpowiedzi 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

Rubinowy, 74 bajty

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

i nazwać to tak

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

1

R, 68 bajtów

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

Nienazwana funkcja, która pobiera 3dane wejściowe; cktóry jest znakiem do wyrównania, xto pierwszy ciąg i ydrugi ciąg.

W R funkcja regexprzwraca pozycję danego wzorca w ciągu. Rozwiązanie działa poprzez zastosowanie regexprna obu ciągach znaków i powtarzanie białych spacji stanowiących różnicę, a następnie po prostu wydrukowanie obu danych wejściowych oddzielonych znakiem nowej linii.


0

Python 2, 67 66 bajtów

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

Dzwoni z:

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

0

Moonscript, 138 bajtów

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

Zwraca funkcję, która przyjmuje 2 argumenty. Pierwszy to ciąg znaków, drugi to znak do wyrównania. Argumenty te są domyślnymi argumentami @ i n.

Najpierw dołączam nową linię do łańcucha, aby ułatwić przetwarzanie.

@='
'..@

Teraz generuję listę pozycji każdego znaku wyrównania, używając gmatch. Następnie zastępuję nową linię przed każdą linią prawidłową liczbą spacji, a następnie przycinam nową linię, którą dodałem na początku.


0

Lua, 169 bajtów

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

Nie tak krótkie jak inne odpowiedzi, ale to moja pierwsza: D


0

Retina , 71 bajtów

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

Wypróbuj online! Uwaga: Pozostawia to znak wyrównania na wyjściu; można go usunąć kosztem 4 bajtów. Jeśli tylko dwa ciągi muszą zostać wyrównane, to dla 52 bajtów:

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

Wyjaśnienie:

^(.)¶

To pasuje do znaku wyrównania.

((.)*\1.*¶)

Pasuje do pierwszego wiersza, a także śledzi, ile znaków było przed znakiem wyrównania. (.NET utrzymuje stos dopasowania dla każdej zmiennej, w tym przypadku,. $3)

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

To pasuje do drugiej linii, próbując uwzględnić tyle znaków, ile znaleźliśmy w pierwszej linii. ?<-3>powoduje, że dopasowanie wyskakuje na stosie dla każdego znaku, dopóki nie będzie puste, w którym to momencie dopasowanie kończy się niepowodzeniem, a (.)*następnie dopasowuje pozostałe znaki przed znakiem wyrównania. W tym momencie mamy następujące zmienne:

  • $1 zawiera znak wyrównania
  • $2 zawiera pierwszą linię
  • $3 zawiera stos, którego długość to przedrostek pierwszej linii minus przedrostek drugiej linii
  • $4 zawiera drugą linię
  • $5 zawiera stos, którego długość to prefiks drugiej linii minus prefiks pierwszej linii

$#5$*następnie poprzedza niezbędną liczbę spacji, aby pierwsza linia była wyrównana z drugą, i odwrotnie dla $#3$*.

Podobna logika ma zastosowanie do głównej odpowiedzi, z tym wyjątkiem, że musimy znaleźć dwie linie, które nie są wyrównane, abyśmy mogli je wyrównać (to jest miejsce, w którym się ?(5)pojawia), a następnie powtórzyć wyrównanie na wszystkich liniach, aż wszystkie zostaną równo wyrównane .


0

Common Lisp, 101 bajtów

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

Pierwszy parametr to znak, drugi to lista ciągów do wyrównania.

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.