Hancurkan tab menjadi dua

31

Perang suci telah diperebutkan ruang vs tab. (Dan tentu saja ruang, menjadi superior secara objektif, menang.) - Alex A.

S ome PEO p le masih menolak untuk sebuah ccept yang WHI c h adalah cl e Arly s upreme. Anda baru saja menerima sebuah file dengan menggunakan incor ulang ct, b iklan, dan inf e bentuk rior dari WHI t espace, dan sekarang t dia cont e nts dari file r e tercemar dan hancur.

Anda memutuskan untuk menunjukkan kepada orang yang mengirim file kepada Anda betapa salahnya mereka — dengan kekerasan.

Deskripsi

Seperti judulnya, tantangan Anda adalah mengambil file yang berisi satu tab atau lebih:

this is an evil tab    onoes

dan dengan kejam menghancurkannya menjadi beberapa bagian:

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Perhatikan bahwa perangkat lunak Stack Exchange mengubah tab literal menjadi empat spasi (karena benar), sehingga tab dalam pos ini akan ditampilkan sebagai empat spasi. Input untuk program Anda, bagaimanapun, akan berisi tab yang sebenarnya.

Tantangan

Solusinya harus mengambil string tunggal sebagai input, yang mungkin mengandung ASCII yang dapat dicetak, baris baru, dan tab. Akan selalu ada setidaknya satu tab di input.

Outputnya harus string yang sama, dengan aturan berikut diterapkan:

  • Mulai kursor pada koordinat (0,0) dan dengan arah kanan. Koordinatnya adalah (kolom, baris), indeks-nol, dan arahnya adalah ke mana Anda harus memindahkan kursor setelah mencetak karakter.

  • Untuk setiap karakter dalam string:

    • Jika itu adalah baris baru, pindah ke koordinat (0, n), di mana n adalah jumlah baris baru dalam string sejauh ini (termasuk yang ini), dan reset arah ke kanan.

    • Jika itu tab, output dua spasi, putar arah kursor 90 derajat searah jarum jam , dan output dua spasi lagi, secara efektif "memecah" tab menjadi dua. Berikut adalah contoh visual, di mana tab direpresentasikan sebagai --->dan spasi sebagai ·:

      foo--->bar--->baz
      

      menjadi

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • Jika tidak, cukup keluarkan karakter pada kursor dan gerakkan kursor satu langkah ke arah saat ini.

Karena Anda membaca string dari awal hingga akhir, ada kemungkinan Anda harus menulis "di atas" karakter yang ada — ini tidak apa-apa. Misalnya input

foo--->bar


spaces are superior

harus menghasilkan keluaran dari

foo

     b
spaces are superior
     r

Anda dapat memilih apakah "tab rusak" harus menimpa karakter lain — maksud awalnya adalah tidak ada, tetapi speknya ambigu, jadi ini keputusan Anda.

Selanjutnya, setelah menerapkan aturan-aturan ini, Anda juga bisa

  • menambah atau menghapus spasi tambahan sebanyak yang Anda inginkan.

  • tambahkan maksimum satu baris baru.

Masukan tidak akan pernah mengandung spasi tambahan; itu juga tidak akan mengandung baris baru atau akhir. Anda juga dapat selalu berasumsi bahwa Anda tidak akan pernah perlu menulis ke kolom atau baris kurang dari 0 (yaitu dari layar).

Kasus cobaan

Tab pada test case ini diwakili --->karena jika tidak SE akan melahapnya.

Memasukkan:

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

Keluaran:

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

Animasi mewah:

Aturan

  • Ini adalah , jadi kode terpendek dalam byte akan menang!
Gagang pintu
sumber
Ketika Anda mengatakan kursor harus mulai dari (0,0)maksud Anda, kami perlu menghapus konsol terlebih dahulu, atau Anda hanya maksudkan posisi default kursor dengan itu?
Martin Ender
18
Saya memilih untuk menutup pertanyaan ini sebagai di luar topik karena penuh dengan kebencian dan penistaan.
aditsu
1
Animasi Anda sangat mirip dengan penerjemah> <> yang sekarang ingin saya lihat entri pengubahan-diri> <>.
Sanchises
1
Saya menyukai pesan tersembunyi di paragraf pembuka tetapi saya harus tidak setuju.
wf4
@ MartinBüttner Itu artinya posisi default.
Gagang Pintu

Jawaban:

8

MATLAB, 144 byte

Senjata pilihan untuk berurusan dengan string tentu saja bahasa yang dirancang untuk memanipulasi angka [rujukan?]. Selain itu, hal hebat tentang Matlab adalah tidak peduli jika Anda menetapkan array 'out of bounds': itu hanya akan membuat matriks yang lebih besar. Selanjutnya, elemen matriks default 0,, diberikan sebagai spasi alih-alih anull karakter yang ditentukan oleh spesifikasi ASCII.

Tab hanyalah lompatan dalam koordinat, jadi tidak ada spasi yang dihasilkan untuk 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

Saya mulai dengan 209 byte, tetapi beberapa golf yang lebih hati-hati menyingkirkan sebagian besar itu; ada banyak pengulangan dalam kode ini, jadi saya melakukan beberapa percobaan-dan-kesalahan alternatif mana yang paling berhasil. Saya tidak berpikir ada banyak ruang untuk lebih banyak optimasi dengan kode ini, tapi saya selalu senang terbukti salah. Sunting: Tom Carpenter berhasil membuktikan saya salah; ia berhasil menghemat 9 byte yang saya optimalkan untuk menghemat 29 byte. Bita terakhir disimpan dengan mengasumsikan tidak ada karakter kontrol (ASCII <9) pada input - string MATLAB tidak- nulldimusnahkan.

Sanchises
sumber
Tampaknya tidak berfungsi. Saya mencoba ini q('hello<tab>my name<tab>is tom<tab>c'), tetapi sesuatu di sepanjang garis Attempted to access o(11,-2); on line 7. Meskipun ini mungkin lebih berkaitan dengan masalah dalam pertanyaan - jika kursor mengarah ke belakang dan melampaui kolom pertama apa yang terjadi pada sisa baris.
Tom Carpenter
Yap, sayang sekali saya melewatkan sedikit itu. Saya akan pergi sekarang;)
Tom Carpenter
1
Anda dapat menyimpan 9 karakter lainnya dengan menghapus dvariabel dan sebaliknya memiliki 4 variabel yang untuk loop membuat pola [1 0 -1 0] seperti itu: 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 (jelas di komentar itu menghapus semua baris, jadi Anda harus memiliki memformat ulang seperti milik Anda untuk melihat apa yang saya lakukan)
Tom Carpenter
@ TomCarpenter Itu ... benar-benar jelek. Aku menyukainya.
Sanchises
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='')

The \tharus menjadi karakter tab yang sebenarnya.

Kode bekerja agak seperti jawaban Zach Gates, pertama-tama menghasilkan Mdengan Mkotak di mana Madalah jumlah dari panjang garis. (Itu jumlah berlebih yang sangat besar, tetapi membuat kodenya lebih pendek.) Ia kemudian melewati karakter, menempatkan mereka di tempat yang benar, melacak baris paling bawah yang dikunjungi. Akhirnya, ia mencetak semua garis hingga baris itu.

Outputnya berisi (biasanya sejumlah besar) spasi tambahan dan 1 spasi tambahan.

PurkkaKoodari
sumber
3

Javascript (ES6), 264 245 byte

Mencoba pendekatan "create a grid of space, fill and trim" raksasa, yang berakhir 19 byte lebih pendek dari yang lain.

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

Dengan memodifikasi baris kedua hingga terakhir seperti itu, Anda dapat menghapus sejumlah besar ruang tambahan di setiap baris:

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

Coba di sini:

Penjelasan segera hadir; saran diterima!

Produksi ETH
sumber
3

JavaScript (ES6), 180 183

Menggunakan string template, ada beberapa baris baru yang signifikan dan dihitung.

Itu fungsi mengembalikan output yang diminta (diisi dengan banyak spasi tambahan)

Hanya ada sedikit yang bisa dijelaskan: baris-baris itu dibangun sesuai kebutuhan. Tidak ada variabel arah, hanya 2 offset untuk x dan y, karena dalam rotasi searah jarum jam mereka mudah dikelola:dx <= -dy, dy <= dx

Tes menjalankan cuplikan di bawah ini di 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>

edc65
sumber
Saya berharap semua bahasa memiliki [x, y] = [expr1, expr2] ...
Sanchises
1

Python 2, 370 369 368 byte

Terima kasih kepada @sanchises dan @ edc65 karena telah menyelamatkan saya setiap 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()

Ini menghasilkan grid terbesar yang mungkin dan kemudian loop, karakter demi karakter, beralih arah pada setiap tab.

Zach Gates
sumber
Petunjuk: if !ddanif d>2
Sanchise
!dbukan sintaks yang valid. @sanchises Terima kasih atas d>2tipnya.
Zach Gates
Maaf, saya tidak benar-benar tahu python :) Hanya semacam anggapan itu akan berfungsi seperti itu.
Sanchises
Saya juga tidak mengerti python, tetapi jika d dalam 0 ... 3, d==0->d<1
edc65
Yap, kamu benar. Terima kasih atas bytenya. @ edc65
Zach Gates