ขยายแท็บ (ใช้ขยาย (1))


10

งานของคุณในครั้งนี้คือการใช้ชุดexpand(1)โปรแกรมอรรถประโยชน์POSIX ซึ่งขยายแท็บไปยังช่องว่าง

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

ข้อมูลจำเพาะ Tabstop

ข้อกำหนด TabStopประกอบด้วยทั้งหมายเลขเดียวหรือรายการคั่นด้วยเครื่องหมายจุลภาค tabstops ในกรณีของตัวเลขเดียวมันซ้ำแล้วซ้ำอีกราวกับว่ามันทวีคูณของมันเกิดขึ้นในรายการคั่นด้วยเครื่องหมายจุลภาค (เช่น4ทำหน้าที่เป็น4,8,12,16,20,...) +รายการในรายการคั่นด้วยเครื่องหมายจุลภาคแต่ละเป็นจำนวนเต็มบวกนำหน้าเลือกโดย +คำนำหน้าบ่งบอกถึงความแตกต่างเมื่อเทียบกับค่าก่อนหน้านี้ในรายการคั่นด้วยเครื่องหมายจุลภาค ค่าแรกในรายการต้องเป็นค่าสัมบูรณ์ แท็บระบุคอลัมน์ของอักขระที่ไม่ใช่ช่องว่างถัดไป (ตามหลังแท็บที่ขยาย) โดยคอลัมน์ซ้ายสุดที่ถือเป็นหมายเลข 0 แท็บควรขยายเป็นอย่างน้อยหนึ่งช่องเสมอ

อินพุต / เอาต์พุต

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

แท็บที่ถูกขยายทั้งหมดและอินพุตทั้งหมดจะถือว่ามีความกว้างสูงสุด 80 คอลัมน์ แท็บที่ขยายทั้งหมดจะเพิ่มขึ้นอย่างเคร่งครัด


ตัวอย่าง

ข้อมูลจำเพาะ Tabstop 4,6,+2,+8เทียบเท่ากับ4,6,8,16และมีทั้งอินพุต

ab<Tab>c
<Tab><Tab>d<Tab>e<Tab>f

ถูกขยายเป็น ( หมายถึงช่องว่าง)

ab␣␣c
␣␣␣␣␣␣d␣e␣␣␣␣␣␣␣f

01234567890123456   (Ruler for the above, not part of the output)
          1111111

การให้คะแนนเป็นบริสุทธิ์ รหัสที่สั้นที่สุดชนะ

คำตอบ:


2

GolfScript ( 77 75 ตัวอักษร)

n/(','/{'+'/{~t++}*~:t}%81,{t*}%+:T;{[0\{.9={;T{1$>}?(.)@-' '*}*\)}/;]n+}/;

ฉันค่อนข้างพอใจกับ tabspec ในการแยกวิเคราะห์

# Split on commas
','/
# For each element:
{
    # Split on '+'
    '+'/
    # We now have either ["val"] or ["" "val"]
    # The clever bit: fold
    # Folding a block over a one-element array gives that element, so ["val"] => "val"
    # Folding a block over a two-element array puts both elements on the stack and executes,
    # so ["" "val"]{~t++}* evaluates as
    #     "" "val" ~t++
    # which evaluates val, adds the previous value, and concatenates with that empty string
    {~t++}*
    # Either way we now have a string containing one value. Eval it and assign to t
    ~:t
}%

จากนั้นฉันจะเพิ่มทวีคูณขององค์ประกอบสุดท้ายจนกว่าฉันจะรับประกันว่าจะมีพอถึงจุดสิ้นสุดของคอลัมน์ 80:

81,{t*}%+

สิ่งนี้จะให้พฤติกรรมที่ต้องการเมื่อมีการระบุแท็บสต็อปเพียงอันเดียวและจะเกี่ยวข้องในกรณีที่สเป็คไม่ได้กล่าวถึงเท่านั้น (NB ทำให้รายการของแท็บหยุดจิ้มกลับไปที่ 0 จากนั้นทำซ้ำองค์ประกอบแยกวิเคราะห์ล่าสุด แต่ไม่เกี่ยวข้องเพราะเมื่อมันมาถึงการใช้รายการฉันมองหาองค์ประกอบแรกมากกว่าตำแหน่งปัจจุบัน)

ที่เหลือค่อนข้างตรงไปตรงมา


2

ทับทิม161 145

อ่านข้อมูลจำเพาะ tabstop บนบรรทัดแรกของอินพุต

i=t=[]
gets.scan(/(\+)?(\d+)/){t<<i=$2.to_i+($1?i:0)}
81.times{|j|t<<j*i}
while gets
$_.sub!$&," "*(t.find{|s|s>i=$`.size}-i)while~/\t/
print
end

แก้ไข: เพิ่มสองบรรทัดที่ทำให้ tabstop อ่านล่าสุดซ้ำเพื่อให้ข้อมูลจำเพาะ tabstop ของตัวเลขเดียวยังทำงานอย่างถูกต้อง

iเป็นตัวแปรชั่วคราวสำหรับการถือแท็บแท็บสุดท้ายแยก tคือรายการ tabstobs แยกออกจากgets.scanบรรทัด สำหรับการวัดที่ดีเราได้เพิ่ม 81 แท็บแท็บที่แยกวิเคราะห์ล่าสุด while getsห่วงเก็บไปจนกว่าจะไม่มีการป้อนข้อมูลเพิ่มเติม สำหรับแต่ละบรรทัดของการป้อนข้อมูลเราแทนที่แท็บสำหรับช่องว่างหนึ่งแท็บในเวลานั้นเพราะสตริงย้ายในขณะที่เราเพิ่มช่องว่างและเราจะต้องคำนวณ tabstop ที่ถูกต้อง


ฉันไม่รู้รูบี้จริง ๆ แต่คุณเขียนx+($1?i:0)สั้นลงได้$1?x+i:xไหม?
Timwi

@Timwi Nope! ทับทิมเป็นสิ่งที่แปลกเล็กน้อยกับผู้ประกอบการที่ประกอบไปด้วย โดยปกติแล้วคุณต้องใส่ช่องว่างไว้ที่ใดที่หนึ่งเพราะเครื่องหมายโคลอน ( :) สามารถทำเครื่องหมายจุดเริ่มต้นของสัญลักษณ์ได้ แต่เนื่องจากสัญลักษณ์ไม่สามารถเริ่มต้นด้วยหลักได้:0ก็โอเคโดยไม่มีช่องว่าง หรือบางสิ่งบางอย่าง. มันเป็นเรื่องแปลก. วงเล็บมีความสำคัญเช่นกัน
daniero

การสแกนแบบแท็บนั้นดูบั๊กกี้สำหรับฉัน ในt<<x+($1?i:0);i=xคำสั่งแรกไม่เปลี่ยนแปลงxใช่ไหม ฉันคิดว่าคุณต้องย้อนกลับเป็นi=x+($1?i:0);t<<i
Peter Taylor

1
ในความเป็นจริงคุณสามารถบันทึก 16 โดยแทนที่สองบรรทัดแรกด้วยi=t=[](เนื่องจากiรับประกันว่าไม่จำเป็นต้องใช้ในครั้งแรก) ลดความซับซ้อนของการแยกแท็บหยุด{t<<i=$2.to_i+($1?i:0)}และกำจัดlทั้งหมด ( iเก็บค่านั้นไว้แล้ว) แต่คนดีที่ไม่สนใจเกี่ยวกับแท็บหยุดการเพิ่มขึ้นอย่างเคร่งครัด: ที่ช่วยให้คุณ 4 ตัวอักษรและฉันสามารถยืมเพื่อบันทึก 2
ปีเตอร์เทย์เลอร์

@ PeterTaylor ขอบคุณสำหรับการป้อนข้อมูล! มันไม่ได้บั๊กโดยตรง แต่แน่นอนว่ามีเลือดป่องเล็กน้อย ฉันคิดว่ามันง่ายเกินไปที่จะจ้องมองรหัสตัวเองแบบนี้
daniero

1

C, 228 ตัวอักษร

นี่คือโซลูชัน C เพื่อเริ่มต้นสิ่งต่าง ๆ ยังมีสนามกอล์ฟให้ทำมากมายที่นี่ (ดูที่ifs และfors และputchars ... ) ทดสอบกับตัวอย่างทดสอบเช่นเดียวกับอินพุตเดียวกัน แต่4และ8สำหรับข้อมูลจำเพาะแท็บ

S[99],i;L,C;main(v){for(v=1;v;)v=scanf("+%d",&C),v=v>0?C+=L:scanf("%d",&C),
v&&(S[L=C]=++i,getchar());for(;i==1&&C<80;)S[C+=L]=1;for(C=L=0;C=~getchar();)
if(C+10)putchar(~C),L+=C+11?1:-L;else for(putchar(32);!S[++L];)putchar(32);}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.