Розбийте вкладки навпіл


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
Санчіз

!dнедійсний синтаксис. @sanchises Хочу спасибі за d>2підказку.
Zach Gates

Вибачте, я насправді не знаю python :) Просто припустив, що це буде працювати так.
Санчіз

Я теж не розумію python, але якщо d в 0 ... 3, d==0->d<1
edc65

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