Разбить вкладки пополам


31

Священные войны велись из-за пробелов против табов. (И конечно пробелы, будучи объективно превосходящими, выиграли.) - Алекс А.

S Ом ЕГО р ля до сих пор отказывается , чтобы в ccept , что бея с ч сл е арли евым upreme. Вы только что получили в файл , используя Инкор ре кт, б объявление и инф е RIOR форму беи т Espace, и теперь т ситеме прода й нТ файла р е испорченный и разоренным.

Вы решаете, что с таким же успехом можете показать человеку, приславшему вам файл, насколько они неправы - насильственно.

Описание

Как видно из заголовка, ваша задача - взять файл, содержащий одну или несколько вкладок:

this is an evil tab    onoes

и безжалостно разбивают их на куски

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Обратите внимание, что программное обеспечение Stack Exchange превращает буквенные вкладки в четыре пробела (потому что это правильно), поэтому вкладки в этом посте будут отображаться в виде четырех пробелов. Однако вход в вашу программу будет содержать реальные вкладки.

Вызов

Решение должно принимать в качестве входных данных одну строку, которая может содержать печатный ASCII, символы новой строки и вкладки. На входе всегда будет хотя бы одна вкладка.

Вывод должен быть такой же строкой, с применением следующих правил:

  • Начать курсор с координат (0,0) и с направлением вправо. Координаты (столбец, строка), с нулевым индексом, и направление, в котором вы должны перемещать курсор после печати символа.

  • Для каждого символа в строке:

    • Если это новая строка, перейдите к координатам (0, n), где n - количество новых строк в строке (включая эту), и сбросьте направление вправо.

    • Если это вкладка, выведите два пробела, поверните курсор на 90 градусов по часовой стрелке и выведите еще два пробела, эффективно «разбивая» вкладку пополам. Вот наглядный пример, где вкладка представлена ​​как --->и пробелы как ·:

      foo--->bar--->baz
      

      становится

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • В противном случае просто выведите символ на курсор и переместите курсор на один шаг в текущем направлении.

Поскольку вы читаете строку от начала до конца, возможно, вам придется писать «поверх» существующих символов - это нормально. Например, вход

foo--->bar


spaces are superior

должен привести к выводу

foo

     b
spaces are superior
     r

Вы можете выбрать, должны ли «сломанные вкладки» перезаписывать другие символы - изначально предполагалось, что они этого не делают, но спецификация была неоднозначной, поэтому это ваше решение.

Кроме того, после применения этих правил вы также можете

  • добавьте или удалите столько пробелов, сколько хотите.

  • добавить максимум одного завершающего символа новой строки.

Вход никогда не будет содержать завершающие пробелы; он также никогда не будет содержать начальных или конечных символов новой строки. Вы также можете всегда предполагать, что вам никогда не потребуется записывать в столбец или строку меньше 0 (т.е. за пределы экрана).

Прецедент

Вкладки в этом тестовом примере представлены так, --->потому что в противном случае SE поглощает их.

Входные данные:

Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah

Выход:

Test case. Here's a tab
blah
blah                     t
blah blah blah blah blah blah
                        blaablah
                         r     b
                         e     l  b
                      h  'h    a  l
                      a  sa    a  a
                      l   l    h  h
       this is some mobe tbxt

                         haalhalb
     b                   a
     a                   b
     t

        bat a erehwyreve

Необычная анимация:

правила

  • Это , поэтому выиграет самый короткий код в байтах!

Когда вы говорите, что курсор должен начинаться с (0,0), вы имеете в виду, что мы должны сначала очистить консоль, или вы просто подразумеваете положение курсора по умолчанию?
Мартин Эндер

18
Я голосую, чтобы закрыть этот вопрос как не по теме, потому что он полон ненависти и богохульства.
aditsu

1
Ваша анимация выглядит так же, как интерпретатор> <>, и теперь я хочу увидеть самоизменяющуюся запись> <>.
Санчиз

1
Мне понравилось скрытое сообщение в первом абзаце, но я должен не согласиться.
wf4

@ MartinBüttner Это просто означает положение по умолчанию.
Ручка двери

Ответы:


8

MATLAB, 144 байта

Оружие выбора для работы со строками - это, конечно, язык, предназначенный для манипулирования числами. Шутка в сторону, самое замечательное в Matlab состоит в том, что ему все равно, если вы присваиваете массив «вне границ»: он просто создаст матрицу большего размера. Кроме того, матричный элемент по умолчанию 0отображается в виде пробела, а не nullсимвола, который предписывает спецификация ASCII.

Вкладки - это просто переход координат, поэтому для вкладки не выводятся пробелы.

function o=q(t)
u=2;v=0;x=1;y=1;n=1;for s=t
if s==9 x=x+u-v;y=y+v+u;a=v;v=u;u=-a;elseif s<11
n=n+1;x=1;y=n;else
o(y,x)=s;x=x+u/2;y=y+v/2;end
end

Я начал с 209 байтов, но некоторые более осторожные игры в гольф избавили от большей части этого; в этом коде много повторений, поэтому я сделал несколько проб и ошибок, альтернативы сработали лучше всего. Я не думаю, что есть много места для большей оптимизации с этим кодом, но я всегда рад быть ошибочным. Редактировать: Том Карпентер сумел доказать, что я не прав; ему удалось сохранить 9 байтов, которые я оптимизировал, чтобы сохранить колоссальные 29 байтов. Последний байт сохранен, если предположить, что во входных данных нет управляющих символов (ASCII <9) - строки MATLAB не определены null.


Не похоже на работу. Я пытался это q('hello<tab>my name<tab>is tom<tab>c'), но это что-то вроде Attempted to access o(11,-2); on line 7. Хотя это может быть больше связано с проблемой в вопросе - если курсор движется назад и выходит за пределы первого столбца, что происходит с остальной частью строки.
Том Карпентер

Да, мой плохой, я пропустил этот бит. Я уйду сейчас;)
Том Карпентер

1
Вы можете сохранить еще 9 символов, удалив dпеременную и вместо этого имея 4 переменные, которые для цикла создают шаблон [1 0 -1 0] как таковой: function o=q(t) u=1;v=0;w=-1;z=0;x=0;y=1;n=1;for s=t if s==9 x=x+2*u-2*v;y=y+2*v+2*u;a=z;z=w;w=v;v=u;u=a;elseif s==10 n=n+1;x=0;y=n;else x=x+u;y=y+v;o(y,x)=s;end end (очевидно, что в комментариях он удалил все строки, так что вы получите переформатировать его, как твой, чтобы увидеть, что я сделал)
Том Карпентер

@ TomCarpenter Это ... действительно ужасно. Я люблю это.
Санчиз

5

Python 3, 272 270 266 262 255 253 244 байта

I=[]
try:
 while 1:I+=[input()]
except:r=m=0
M=sum(map(len,I))
O=[M*[' ']for _ in[0]*M]
for l in I:
 x=b=0;y=r;a=1;r+=1
 for c in l:
  if'\t'==c:a,b=-b,a;x+=a+2*b;y+=b-2*a
  else:O[y][x]=c
  x+=a;y+=b;m=max(m,y)
for l in O[:m+1]:print(*l,sep='')

\tДолжна быть актуальной символ табуляции.

Код работает несколько , как ответ Зака Гейтса, первым генерируя Mпо Mсетке , где Mесть сумма длин линий. (Это избыточное количество, но код становится короче.) Затем он перебирает символы, размещая их в правильных местах, отслеживая самую нижнюю посещаемую строку. Наконец, он печатает все строки до этой строки.

Вывод содержит (обычно огромное количество) завершающие пробелы и 1 завершающий перевод строки.


3

Javascript (ES6), 264 245 байт

Пробовал подход «создать гигантскую сетку пространств, заполнить и обрезать», который в итоге оказался на 19 байт короче, чем другой.

a=t=>(o=`${' '.repeat(l=t.length)}
`.repeat(l).split`
`.map(q=>q.split``),d=x=y=z=0,s=c=>o[d>2?y--:d==1?y++:y][d?d==2?x--:x:x++]=c,[...t].map(c=>c=='\t'?(s` `,s` `,++d,d%=4,s` `,s` `):c==`
`?(x=d=0,y=++z):s(c)),o.map(p=>p.join``).join`
`.trim())

Изменив вторую строку до последней, как показано ниже, вы можете удалить большое количество пробелов в каждой строке:

...o.map(p=>p.join``.trimRight())...

Попробуйте это здесь:

Объяснение в ближайшее время; предложения приветствуются!


3

JavaScript (ES6), 180 183

Используя строки шаблона, есть некоторые новые строки, которые являются значительными и учитываются.

Это функция, возвращающая запрошенный вывод (дополненный тоннами конечных пробелов)

Мало что можно объяснить: ряды построены так, как нужно. Здесь нет переменной направления, только смещение 2 для x и y, так как при вращении по часовой стрелке ими легко управлять:dx <= -dy, dy <= dx

Попробуйте запустить фрагмент ниже в Firefox

f=s=>[...s].map(c=>c<`
`?(x+=2*(d-e),y+=2*(e+d),[d,e]=[-e,d]):c<' '?(y=++r,e=x=0,d=1):(t=[...(o[y]||'')+' '.repeat(x)],t[x]=c,o[y]=t.join``,x+=d,y+=e),o=[r=x=y=e=0],d=1)&&o.join`
`

// TEST  

// Avoid evil tabs even in this source 
O.innerHTML = f(`Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah`
 .replace(/--->/g,'\t'))
<pre id=O></pre>


Я хотел бы, чтобы все языки имели [x, y] = [expr1, expr2] ...
Sanchises

1

Python 2, 370 369 368 байт

Спасибо @sanchises и @ edc65 за то, что они сохранили мне каждый байт.

J=''.join
u=raw_input().replace('\t','  \t  ')
w=u[:]
G=range(len(u))
d,r=0,[[' 'for _ in G]for _ in G]
u=u.split('\n')
for t in G:
 x,y=0,0+t
 for c in u[t]:
  if c=='\t':d=(d+1)%4
  if c!='\t':
   if c.strip():r[y][x]=c
   if d<1:x+=1
   if d==1:y+=1
   if d==2:x-=1
   if d>2:y-=1
r=r[:max(i for i,n in enumerate(r)if J(n).strip())+1]
for i in r:print J(i).rstrip()

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


Подсказка: if !dиif d>2
Sanchises

!dневерный синтаксис @sanchises Спасибо за d>2совет, хотя.
Зак Гейтс

Извините, я на самом деле не знаю Python :) Просто предположил, что это будет работать так.
Санчиз

Я тоже не понимаю Python, но если d в 0 ... 3, d==0->d<1
edc65

Да, ты прав. Спасибо за байт. @ edc65
Зак Гейтс,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.