แบ่งแท็บครึ่งหนึ่ง


31

สงครามศักดิ์สิทธิ์ได้รับการต่อสู้กับช่องว่างกับแท็บ (และแน่นอนว่าพื้นที่นั้นมีความเหนือกว่าอย่างชนะชนะ) - Alex A.

Sโอม PEO พี le ยังคงปฏิเสธที่จะccept ที่ WHI h คือ CL อี Arly s upreme คุณเพิ่งได้รับ ไฟล์โดยใช้ Incor ใหม่ CT, โฆษณาและ INF อีรูปแบบของ Rior WHI ทีเอสเพซและตอนนี้tเขาต่ออี nts ของไฟล์Rจปนเปื้อนและเจ๊ง

คุณตัดสินใจว่าคุณอาจแสดงให้คนที่ส่งไฟล์ถึงคุณว่าพวกเขาผิดแค่ไหน - อย่างรุนแรง

ลักษณะ

ตามชื่อเรื่องความท้าทายของคุณคือการใช้ไฟล์ที่มีแท็บหนึ่งแท็บขึ้นไป:

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)คุณหมายความว่าเราต้องล้างคอนโซลก่อนหรือคุณแค่หมายถึงตำแหน่งเริ่มต้นของเคอร์เซอร์โดยที่?
Martin Ender

18
ฉันลงคะแนนให้ปิดคำถามนี้เป็นแบบปิดหัวข้อเพราะเต็มไปด้วยความเกลียดชังและการดูหมิ่น
aditsu

1
ภาพเคลื่อนไหวของคุณดูเหมือนล่าม> <> ซึ่งตอนนี้ฉันต้องการเห็นการแก้ไขด้วยตนเอง> <> รายการ
Sanchises

1
ฉันชอบข้อความที่ซ่อนอยู่ในย่อหน้าเปิด แต่ฉันไม่เห็นด้วย
wf4

@ MartinBüttnerนั่นหมายถึงตำแหน่งเริ่มต้น
ลูกบิดประตู

คำตอบ:


8

MATLAB, 144 ไบต์

อาวุธที่เลือกใช้สำหรับจัดการกับสายนั้นเป็นภาษาที่ออกแบบมาเพื่อจัดการกับตัวเลข การล้อเล่นกันสิ่งที่ยอดเยี่ยมเกี่ยวกับ Matlab ก็คือมันไม่สนใจว่าคุณจะกำหนดให้อาร์เรย์ 'ไม่มีขอบเขต' หรือไม่: มันจะทำให้เมทริกซ์มีขนาดใหญ่ขึ้น นอกจากนี้องค์ประกอบเมทริกซ์เริ่มต้น0จะถูกแสดงเป็นช่องว่างแทนnullตัวอักษรที่ ASCII spec กำหนด

แท็บเป็นเพียงการกระโดดในพิกัดดังนั้นจึงไม่มีการเว้นวรรคสำหรับแท็บ

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 ไบต์ แต่การตีกอล์ฟที่ระมัดระวังมากกว่านั้นก็กำจัดได้ มีการทำซ้ำหลายครั้งในรหัสนี้ดังนั้นฉันจึงทำการทดลองและข้อผิดพลาดทางเลือกซึ่งทำงานได้ดีที่สุด ฉันไม่คิดว่าจะมีพื้นที่สำหรับการเพิ่มประสิทธิภาพมากขึ้นด้วยรหัสนี้ แต่ฉันยินดีที่จะพิสูจน์ผิด แก้ไข: Tom Carpenter พยายามพิสูจน์ฉันผิด เขาจัดการเพื่อบันทึก 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กัน แม้ว่าสิ่งนี้อาจเกี่ยวข้องกับปัญหาในคำถามมากกว่านี้ - หากเคอร์เซอร์มุ่งหน้าไปด้านหลังและอยู่นอกเหนือจากคอลัมน์แรกสิ่งที่เกิดขึ้นกับส่วนที่เหลือของบรรทัด
Tom Carpenter

ใช่ฉันไม่ดีฉันพลาดบิตนั้น ฉันจะจากไปแล้ว)
Tom Carpenter

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 นั่นคือ ... น่าเกลียดจริงๆ ฉันรักมัน.
Sanchises

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ควรจะเป็นอักขระแท็บที่เกิดขึ้นจริง

รหัสทำงานคล้ายกับคำตอบของ Zach Gates เริ่มจากการสร้างกริดMโดยผลรวมของความยาวของเส้น (นั่นคือจำนวนมากเกิน แต่ทำให้รหัสสั้นลง) จากนั้นก็วนไปตามตัวละครวางไว้ในจุดที่ถูกต้องติดตามแถวเยี่ยมที่สุด ในที่สุดมันจะพิมพ์ทุกบรรทัดจนถึงแถวนั้นMM

เอาต์พุตประกอบด้วยช่องว่างต่อท้าย (โดยปกติจะมีจำนวนมาก) และขึ้นบรรทัดใหม่ 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

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เคล็ดลับแม้ว่า
Zach Gates

ขออภัยฉันไม่รู้จักงูหลามจริง ๆ :) แค่คิดว่ามันใช้งานได้
Sanchises

ฉันก็ไม่เข้าใจหลาม แต่ถ้าdใน 0 ... 3, d==0->d<1
edc65

ใช่คุณพูดถูก ขอบคุณสำหรับ byte @ edc65
Zach Gates
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.