Вирівнювання ліній!


31

Вирівнювання ліній!

Враховуючи характер і багаторядковий рядок, ваше завдання полягає в прокладці кожного рядка рядка, щоб вони розташовувалися між заданим роздільником.

Приклади

Вхід:

,
Programming, Puzzles
And, Code golf

Вихід:

Programming, Puzzles
        And, Code golf

Вхідні дані

Вхід буде рядком з рядком і символом (який ви будете вирівнювати), ви можете приймати їх у будь-якому бажаному порядку / форматі. Символ з’явиться рівно один раз у рядку. Кожен рядок вводу може бути різним за довжиною.

Введення можна через аргументи функції або STDIN.

Вихідні дані

Вихід повинен бути однаковим по рядку. Вам дозволено одне трейлінг нового рядка і жодне проміжне пробіл.

Вихід повинен бути прокладений мінімальною кількістю пробілів. Ви не можете видалити провідні пробіли у вході (якщо він існує).

Вихід може бути з функції return або STDOUT.


Чи може вхід до повної програми виходити з аргументів командного рядка, або це заборонено?
DLosc

@DLosc Так, звичайно
Downgoat

1. Чи потрібно для аргументів функцій / командного рядка читати один рядок чи допустимий один рядок за аргументом? 2. Чи потрібно прокладати лінії з мінімальною кількістю пробілів?
Денніс

@Dennis Ви можете взяти його в одну струну. Або один рядок на аргумент. "Ви можете прийняти їх у будь-якому бажаному порядку" . Так, вам потрібно проклеїти лінії з мінімальною кількістю пробілів. Я відредагую специфікацію
Downgoat

@vihan Чи можуть функції приймати в одному рядку за аргументом?
xnor

Відповіді:



13

APL (37)

APL просто не дуже добре в обробці струн (або я, звичайно, не в гольфі).

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

Це приймає символ як аргумент зліва, а рядок багаторядкових - як правий аргумент. Передбачається, що багаторядковий рядок закінчується передачею рядків (наприклад, A\nB\nC\nа не A\nB\nC), оскільки я можу використовувати "будь-який формат [я] бажаю", і це також є звичайним форматом для текстових файлів, я вважаю це розумним.

Пояснення:

  • S←⌽⍵: поверніть рядок і збережіть його S.
  • R←S⊂⍨S=⊃S: розділіть Sна перший символ і збережіть масив рядків у R.
  • ⍺⍳¨⌽¨R: Rповерніть кожен рядок у , а потім знайдіть індекс ⍺ (символ) у кожному рядку.
  • (⌈/-+): відняти кожен з індексів від найбільшого індексу, вказавши необхідну кількість пробілів
  • ' '/⍨¨: для кожного з цих значень генеруйте стільки пробілів
  • R,¨: додайте пробіли до кожного рядка в R.
  • : з'єднайте всі рядки разом
  • : відмініть його (щоб повернути оригінальне замовлення)

Приклад:

      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 байт

Завдяки Деннісу за збереження 2-х байт.

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

Це зчитує рядки з аргументів командного рядка та символ із STDIN.

Онлайн-перекладач не підтримує аргументи командного рядка, але ви можете протестувати еквівалентну версію тут.

Пояснення

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

Піп , 22 20 18 + 1 = 19 байт

Y_@?qMgsX(MXy)-y.g

Візьме рядки як аргументи командного рядка та роздільник від STDIN ( ідея запозичена з відповіді Мартіна CJam ). Використовує -nпрапор для друку вихідних значень на окремих рядках.

                    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)

І приклад запуску:

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 байт

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

Не зовсім короткий, як мови для гольфу, розміщені досі. Вводить дані як два аргументи функції, наприклад f(',','Programming, Puzzles\nAnd, Code golf'). Нижче показаний фрагмент не знятий з волів і включає простий метод тестування.

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>


6

Pyth, 27 24 байти

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

Оновлено для останнього Pyth .

Демонстраційна демонстрація.

27-байтна версія

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

Демонстраційна демонстрація.


Щоразу, коли ви побачите jbmна початку своєї відповіді, вам слід негайно почати думати V.
orlp

Або просто видалітьb
Jakube

5

Джулія, 117 байт

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

Безголовки:

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)

Досить прямо. Це знаходить положення символу в рядку двічі: один раз, щоб знайти макс (ну, один раз на рядок), і один раз знайти зміщення. Я спробував комбінувати їх, але це було довше.

Python 3 використовується для розпакування входу. Мій IDLE, здається, приймає багаторядкові рядки як вхідні дані.


@DLosc працює для мене в IDLE, вставляючи в рядок рядок.
xnor

Хм. Коли я це роблю (IDLE 3.3.4, Windows 7), cотримує роздільник і sотримує порожній список. Подальші дзвінки input()повернути решту рядків по черзі.
DLosc

@DLosc Странно. Я копіюю вставку рядка прямо з мого браузера в рядок очікування. Ви робите те саме? IDLE 3.2.2, Windows 7 у випадку, якщо це має значення.
xnor

Те саме. Ось скріншот ...
DLosc

@DLosc все ще працює для мене ( скріншот ). Хоча я не розумію, що відбувається, я хочу сказати, що це поведінка компілятора чи середовища , і я редагував спробу вказати відповідну інформацію. Версія функції на 3 символи довша в Python 2.
xnor

3

Желе , 12 байт

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

Спробуйте в Інтернеті!

Виконаний і гольф із пташиним співучасником у долині J elly H yper T (JHT) , нашій чатовій практиці з желе.

Як це працює

Третій аргумент командного рядка (перший вхід) повинен бути багаторядковою рядком, а символ - четвертим аргументом командного рядка (другий вхід).

Full © w € µạṀ⁶ẋż®Y ~ Повна програма.

Ỵ ~ Розбийте рядок на нові рядки.
 © ~ Скопіюйте результат у реєстр.
  w € ~ Отримайте індекс першого появи символу у кожному рядку.
      Ṁ ~ Візьміть максимум.
    µạ ~ І віднімаємо її від кожного індексу, приймаючи абсолютне значення.
       ⁶ẋ ~ Повторіть пробіл, який багато разів (векторизується).
         ż® ~ Переплутайтеся з тим, що було збережено в реєстрі.
           Y ~ Приєднуйтесь до нових рядків і друкуйте неявно.

Я не впевнений, чи дозволено приймати введення як список рядків, тому для введення цього рядка використовується рядок з рядком. Якби це було дозволено:

10 байт

w€µạṀ⁶ẋż³Y

Спробуйте в Інтернеті!


1
ось тоді, коли ви знаєте, що ви створили успішну кімнату
Ерік Атголфер

2

Матлаб / Октава, 106 байт

Функція, яка використовує три окремі аргументи для символу, рядка, рядка; і дає результат у 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])

Приклад у Matlab:

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

Або спробуйте в Інтернеті з перекладачем Octave.


2

Джулія, 80 байт

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

Безголовки:

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

Використовуючи рядки шаблону, два нових рядки є значущими і підраховуються.

Перевірте запуск фрагмента в будь-якому сумісному веб-переглядачі EcmaScript 6 (тобто FireFox. Chrome не підтримує параметри за замовчуванням)

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 байт

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

Називається так:

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

2

C # 4.0, 329 320 307 байт

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

Безгольова версія:

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

Він приймає максимум 9999 рядків ...


2

Діалог APL , 22 20 16 байт

-4 завдяки ngn.

APL насправді не так вже й поганий при обробці рядків, якщо йому дозволяють працювати з масивами. У цьому виклику ми можемо обрати найбільш підходящий формат, який для APL означає вектор текстових векторів як аргумент зліва, а роздільник як скалярний правий аргумент. Це навіть обробляє кілька роздільників на рядок і вирівнює перший з кожного рядка.

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

⊣,¨⍨ додайте кожен рядок

' '⍴¨⍨ стільки пробілів, скільки

⌈.⍳ крайній правий показник символу серед рядків

- мінус

⍳¨ індекс символу в кожному рядку

Спробуйте APL онлайн! ( додано до друку вертикально)

Бонус? Працює для будь-якої кількості рядків і роздільників (вирівнюється по лівій частині).


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

Так, звісно.
Adám

1

C #, 191

Як функція. Приблизно перенесення моєї відповіді 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

Рубін, 74 байти

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

і називати це так

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

1

R, 68 байт

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

Безіменна функція, яка приймає 3входи; cякий є символом для вирівнювання, xє першим рядком і yдругим рядком.

У R функція regexprповертає положення заданого шаблону в рядку. Рішення працює, застосовуючи regexprобидві рядки та повторюючи пробіли, що дорівнюють різниці, а потім просто надрукувати обидва входи, розділені новою лінією.


0

Пітон 2, 67 66 байт

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

Телефонується з:

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

0

Самопис, 138 байт

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

Це повертає функцію, яка бере 2 аргументи. Перший - це рядок, другий - символ, за яким слід вирівняти. Ці аргументи - неявний аргумент @, і n.

Спочатку я додаю новий рядок до рядка, щоб полегшити обробку.

@='
'..@

Тепер я генерую список позицій кожного символу вирівнювання, використовуючи gmatch. Далі я замінюю новий рядок перед кожним рядком на правильну кількість пробілів, а потім обріжте новий рядок, який я додав на початку.


0

Луа, 169 байт

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

Не такий короткий, як інші відповіді, але це моя перша: D


0

Сітківка , 71 байт

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

Спробуйте в Інтернеті! Примітка. Це залишає символ вирівнювання у висновку; її можна видалити вартістю 4 байти. Якщо потрібно вирівняти лише два рядки, то для 52 байтів:

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

Пояснення:

^(.)¶

Це відповідає символу вирівнювання.

((.)*\1.*¶)

Це відповідає першому рядку, а також відстежує кількість символів до символу вирівнювання. (.NET зберігає стек відповідності для кожної змінної, в цьому випадку $3.)

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

Це відповідає другому рядку, намагаючись врахувати стільки символів, скільки ми знайшли в першому рядку. ?<-3>змушує матч спливати стек для кожного символу, поки він не порожній, в цей момент збіг не вдається, а (.)*потім збігається з іншими символами перед символом вирівнювання. На даний момент у нас є такі змінні:

  • $1 містить символ вирівнювання
  • $2 містить перший рядок
  • $3 містить стек, довжина якого - префікс першого рядка мінус другий префікс рядка
  • $4 містить другий рядок
  • $5 містить стек, довжина якого - префікс другого рядка мінус перший префікс рядка

$#5$*потім префікси необхідної кількості пробілів, щоб перший рядок вирівнювався з другим, і навпаки для $#3$*.

Аналогічна логіка застосовується до основної відповіді, за винятком того, що тут ми повинні знайти два рядки, які не вирівнюються, щоб ми могли їх вирівняти (саме тут ?(5)входить), а потім повторити вирівнювання по всіх рядках, поки всі вони не будуть однаково вирівняні .


0

Лист звичайний, 101 байт

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

Перший параметр - символ, другий - список рядків, які потрібно вирівняти.

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.