Phá vỡ các tab trong một nửa


31

Chiến tranh thánh đã được chiến đấu trên không gian so với các tab. (Và tất nhiên là không gian, vượt trội về mặt khách quan, đã thắng.) - Alex A.

S ome peo p le vẫn từ chối để một ccept rằng whi c h là cl e arly s upreme. Bạn vừa nhận được một tập tin bằng cách sử dụng incor lại ct, b quảng cáo và inf e dạng rior của whi t espace, và bây giờ t ông tiếp e nts của tập tin một r e nhiễm và hủy hoại.

Bạn quyết định bạn cũng có thể chỉ cho người đã gửi tệp cho bạn biết họ đã phạm lỗi dữ dội như thế nào.

Sự miêu tả

Như tiêu đề cho thấy, thách thức của bạn là lấy một tệp chứa một hoặc nhiều tab:

this is an evil tab    onoes

và tàn nhẫn phá vỡ chúng thành từng mảnh:

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Lưu ý rằng phần mềm Stack Exchange biến các tab theo nghĩa đen thành bốn khoảng trắng (vì nó đúng), vì vậy các tab trong bài đăng này sẽ được hiển thị dưới dạng bốn khoảng trắng. Tuy nhiên, đầu vào cho chương trình của bạn sẽ chứa các tab thực tế.

Thử thách

Giải pháp nên lấy một chuỗi đơn làm đầu vào, có thể chứa ASCII, dòng mới và tab có thể in được. Sẽ luôn có ít nhất một tab duy nhất trong đầu vào.

Đầu ra phải là cùng một chuỗi, với các quy tắc sau được áp dụng:

  • Bắt đầu con trỏ ở tọa độ (0,0) và theo hướng phải. Các tọa độ là (cột, hàng), không có chỉ mục và hướng là cách bạn nên di chuyển con trỏ sau khi in một ký tự.

  • Đối với mỗi ký tự trong chuỗi:

    • Nếu đó là một dòng mới, di chuyển đến tọa độ (0, n), trong đó n là số dòng mới trong chuỗi cho đến nay (bao gồm cả dòng này) và đặt lại hướng sang phải.

    • Nếu đó là một tab, hãy xuất hai khoảng trắng, xoay hướng con trỏ 90 độ theo chiều kim đồng hồ và xuất thêm hai khoảng trắng, "phá vỡ" tab một cách hiệu quả. Đây là một ví dụ trực quan, trong đó một tab được biểu diễn dưới dạng --->và khoảng trắng là ·:

      foo--->bar--->baz
      

      trở thành

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • Mặt khác, chỉ cần xuất ký tự tại con trỏ và di chuyển con trỏ một bước theo hướng hiện tại.

Vì bạn đang đọc chuỗi từ đầu đến cuối, có thể bạn sẽ phải viết "trên đầu" các ký tự hiện có. Điều này không sao cả. Ví dụ: đầu vào

foo--->bar


spaces are superior

sẽ dẫn đến một đầu ra của

foo

     b
spaces are superior
     r

Bạn có thể chọn liệu "các tab bị hỏng" có nên ghi đè lên các ký tự khác không, ý định ban đầu là chúng không có, nhưng thông số này không rõ ràng, vì vậy đây là quyết định của bạn.

Hơn nữa, sau khi áp dụng các quy tắc này, bạn cũng có thể

  • thêm hoặc xóa nhiều dấu cách như bạn muốn.

  • thêm tối đa một dòng mới duy nhất.

Đầu vào sẽ không bao giờ chứa dấu cách; nó cũng sẽ không bao giờ chứa các dòng mới hàng đầu hoặc dấu. Bạn cũng có thể luôn cho rằng bạn sẽ không bao giờ cần phải ghi vào một cột hoặc một hàng nhỏ hơn 0 (tức là tắt màn hình).

Trường hợp thử nghiệm

Các tab trong trường hợp thử nghiệm này được thể hiện là --->vì nếu không SE sẽ ngấu nghiến chúng.

Đầu vào:

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

Đầu ra:

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

Hoạt hình lạ mắt:

Quy tắc

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ giành chiến thắng!

Khi bạn nói con trỏ phải bắt đầu, (0,0)bạn có nghĩa là chúng ta cần xóa bàn điều khiển trước, hay bạn chỉ muốn nói vị trí mặc định của con trỏ bằng cách đó?
Martin Ender

18
Tôi đang bỏ phiếu để đóng câu hỏi này ngoài chủ đề vì nó đầy thù hận và báng bổ.
aditsu

1
Hoạt hình của bạn trông rất giống với trình thông dịch> <> mà bây giờ tôi muốn xem mục tự sửa đổi> <>.
Chiếm

1
Tôi thích thông điệp ẩn trong đoạn mở đầu nhưng tôi phải không đồng ý.
wf4

@ MartinBüttner Điều đó chỉ có nghĩa là vị trí mặc định.
Doorknob

Câu trả lời:


8

MATLAB, 144 byte

Vũ khí được lựa chọn để xử lý các chuỗi dĩ nhiên là một ngôn ngữ được thiết kế để thao túng các con số [cần dẫn nguồn]. Bỏ qua một bên, điều tuyệt vời ở Matlab là nó không quan tâm nếu bạn gán cho một mảng 'ngoài giới hạn': nó chỉ đơn giản sẽ tạo ra một ma trận lớn hơn. Hơn nữa, phần tử ma trận mặc định 0, được hiển thị dưới dạng khoảng trắng thay vì nullký tự mà thông số ASCII quy định.

Các tab chỉ đơn giản là một bước nhảy trong tọa độ, vì vậy không có khoảng trắng nào được xuất ra cho một tab.

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

Tôi đã bắt đầu với 209 byte, nhưng một số môn đánh gôn cẩn thận hơn đã loại bỏ hầu hết điều đó; có rất nhiều sự lặp lại trong mã này, vì vậy tôi đã thực hiện một số thử nghiệm và lỗi mà các lựa chọn thay thế hoạt động tốt nhất. Tôi không nghĩ có nhiều không gian để tối ưu hóa hơn với mã này, nhưng tôi luôn vui khi được chứng minh là sai. Chỉnh sửa: Tom Carpenter quản lý để chứng minh tôi sai; anh quản lý để lưu 9 byte mà tôi đã tối ưu hóa để tiết kiệm được 29 byte. Byte cuối cùng được lưu bằng cách giả sử không có ký tự điều khiển (ASCII <9) trong đầu vào - chuỗi MATLAB không bị nullhủy.


Không xuất hiện để làm việc. Tôi đã thử điều này q('hello<tab>my name<tab>is tom<tab>c'), nhưng nó một cái gì đó dọc theo dòng Attempted to access o(11,-2); on line 7. Mặc dù điều này có thể liên quan nhiều hơn đến một vấn đề trong câu hỏi - nếu con trỏ hướng về phía sau và vượt ra ngoài cột đầu tiên, điều gì sẽ xảy ra với phần còn lại của dòng.
Tom Carpenter

Đúng, xấu của tôi, tôi đã bỏ lỡ một chút. Tôi sẽ đi ngay bây giờ;)
Tom Carpenter

1
Bạn có thể lưu thêm 9 ký tự bằng cách xóa dbiến và thay vào đó có 4 biến để tạo vòng lặp [1 0 -1 0] như sau: 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 (rõ ràng là trong các nhận xét, nó đã xóa tất cả các dòng, vì vậy bạn sẽ có để định dạng lại nó giống như của bạn để xem những gì tôi đã làm)
Tom Carpenter

@TomCarpenter Thật là ... xấu xí. Tôi thích nó.
Sanchise

5

Python 3, 272 270 266 262 255 253 244 byte

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='')

Các \tphải là một ký tự tab thực tế.

Mã này hoạt động hơi giống câu trả lời của Zach Gates, đầu tiên tạo ra một lưới Mtheo Mđó Mlà tổng độ dài của các dòng. (Đó là một lượng dư thừa khổng lồ, nhưng làm cho mã ngắn hơn.) Sau đó, nó lặp qua các ký tự, đặt chúng vào đúng vị trí, theo dõi hàng được truy cập cuối cùng. Cuối cùng, nó in tất cả các dòng lên đến hàng đó.

Đầu ra chứa (thường là một lượng lớn) dấu cách và 1 dòng mới.


3

Javascript (ES6), 264 245 byte

Đã thử phương pháp "tạo ra một lưới không gian khổng lồ, lấp đầy và cắt xén", kết thúc ngắn hơn 19 byte so với phương pháp khác.

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

Bằng cách sửa đổi dòng thứ hai đến cuối cùng như vậy, bạn có thể loại bỏ một lượng lớn khoảng trắng ở mỗi dòng:

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

Hãy thử nó ở đây:

Giải thích sắp ra mắt; đề nghị chào mừng!


3

JavaScript (ES6), 180 183

Sử dụng chuỗi mẫu, có một số dòng mới có ý nghĩa và được tính.

Đó là một hàm trả về đầu ra được yêu cầu (được đệm bằng hàng tấn dấu cách)

Có rất ít để giải thích: các hàng được xây dựng như đã được xem. Không có biến hướng, chỉ có 2 offset cho x và y, vì trong xoay theo chiều kim đồng hồ, chúng dễ dàng được quản lý:dx <= -dy, dy <= dx

Kiểm tra chạy đoạn mã dưới đây trong 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>


Tôi muốn tất cả các ngôn ngữ có [x, y] = [expr1, expr2] ...
Sanchises

1

Python 2, 370 369 369 byte

Cảm ơn @sanchises@ edc65 đã tiết kiệm cho tôi mỗi byte.

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

Nó tạo ra lưới lớn nhất có thể và sau đó lặp lại, theo từng ký tự, chuyển hướng ở mỗi tab.


Gợi ý: if !dif d>2
Chiếm

!dkhông phải là cú pháp hợp lệ. @sanchises Cảm ơn các d>2mẹo, mặc dù.
Zach Gates

Xin lỗi, tôi thực sự không biết trăn :) Chỉ cần giả sử nó sẽ hoạt động như vậy.
Sanchise

Tôi cũng không hiểu trăn, nhưng nếu d trong 0 ... 3, d==0->d<1
edc65

Đúng, bạn đúng. Cảm ơn các byte. @ edc65
Zach Gates
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.