ดีมันครอบคลุมในแท็บ!


26

ผู้ใช้เยื้องพื้นที่รวมกัน ! เราต้องต่อสู้กับผู้ใช้แท็บที่ต่ำต้อย !

ภารกิจของคุณ (คุณควรเลือกที่จะยอมรับ) คือการเขียนโปรแกรมหรือฟังก์ชั่นที่มีสองข้อโต้แย้ง:

  • สตริง: นี่คืออินพุต
  • จำนวนเต็มบวก: จำนวนช่องว่างต่อแท็บนี้

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

โปรดทราบว่าบรรทัดเช่น\t \tabcมีพฤติกรรมที่ไม่ได้กำหนด พวกเขาถูกแทรกโดยผู้ใช้แท็บชั่วร้ายเพื่อทำให้โปรแกรมของคุณซับซ้อน

ตามที่ Tabs Must Die Society โปรแกรมของคุณจะต้องสั้นที่สุดเพื่อหลีกเลี่ยงการตรวจจับโดยผู้ใช้แท็บที่ชั่วร้าย

ตัวอย่าง

\t ใช้เพื่อแสดงแท็บที่นี่

สตริงอินพุต:

a
\t\tb\tc
d

หมายเลขอินพุต:

4

เอาท์พุท:

a
        b c
d

เส้นกลางถูกเยื้องด้วยช่องว่าง 8 ช่อง 4 ต่อแท็บ (เนื่องจากจำนวนที่กำหนดคือ 4)

สตริงอินพุต:

\ta\t\tb

หมายเลขอินพุต:

4

เอาท์พุท:

    a  b

หมายเหตุ:นี่คือไม่ซ้ำกันของความท้าทายการขยายตัวแท็บ ; มันต้องการรูปแบบอินพุตที่แตกต่างกันมากและข้อกำหนดที่แตกต่างกันเล็กน้อย


1
ใช่ตราบใดที่คำถามไม่ได้ขอเลขทศนิยมอย่างชัดเจน (ซึ่งไม่ใช่)
Martin Ender

2
อาจเป็นไปได้ซ้ำกับแท็บขยาย (นำไปใช้ขยาย (1))
Ismael Miguel

1
เราสามารถสมมติว่าอินพุตมีเพียง ASCII แท็บและการขึ้นบรรทัดใหม่ที่พิมพ์ได้หรือไม่
Dennis

2
กรณีทดสอบที่เสนอ: \ta\t\tb, 4(การแก้ไขก่อนหน้านี้ของฉันล้มเหลวในกรณีนั้น)
Dennis

2
เราต้องการคำตอบในช่องว่าง
Kaz Wolfe

คำตอบ:


7

CJam, 30 24 23 ไบต์

q{_9=NA=Seasi*' ?@?:N}/

ฉันมักจะปฏิเสธที่จะโพสต์รหัสที่เป็นอันตรายบนอินเทอร์เน็ต ...

นี่เป็นโปรแกรมเต็มรูปแบบที่อ่านสตริงจาก STDIN และตัวเลขเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

ลองใช้ออนไลน์ในล่าม CJamล่าม

มันทำงานอย่างไร

q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.

อะไรNA=:

  • สำหรับตัวอักษรตัวแรกNจะมีค่าเริ่มต้นเช่นสตริง"\n"จะมีค่าเริ่มต้นคือสตริง

    สำหรับอักขระที่ตามมาทั้งหมดNจะมีผลลัพธ์ของการวนซ้ำล่าสุดเช่นอักขระสุดท้ายจากอินพุตอักขระเว้นวรรคหรือสตริงของช่องว่างตั้งแต่หนึ่งช่องขึ้นไป

  • ถ้าNเป็นสตริงNA=เลือกองค์ประกอบที่ดัชนี 10 ของ N (ล้อมรอบ) ผลลัพธ์จะเป็นช่องว่างหรืออักขระป้อนบรรทัด ทั้งคู่เป็นความจริง

    ถ้า N เป็นตัวอักษรให้NA=กด 1 เพื่อป้อนบรรทัดและ 0 มิฉะนั้น

  • เนื่องจากด้านบนNA=จะส่งค่าความจริงสำหรับอักขระตัวแรกอักขระที่นำหน้าด้วย linefeed หรืออักขระนำหน้าด้วยสตริงช่องว่าง (เยื้องที่ถูกแทนที่แล้ว)

    ในกรณีอื่น ๆ ทั้งหมด (รวมถึง tabulator ที่ถูกแทนที่ด้วยอักขระเว้นวรรค) NA=จะส่งค่าเท็จ


6
สิ่งที่ดีที่คุณทำกับบริการอินเทอร์เน็ตโดยลบแท็บที่เป็นอันตราย ;)
Alex A.

19

K5, 53 45 ไบต์

{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}

ในการดำเนินการ:

  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")

ฉันแค่ต้องการให้บันทึกแสดงให้เห็นว่าคำถามนี้เป็นสิ่งที่เลวทรามทางศีลธรรม


11
-21346106841 สำหรับ... this question is morally reprehensible.
TheNumberOne

3
สิ่งนี้จะต้องจบลงด้วยคำตอบที่ได้รับการโหวตสูงสุดดังนั้นผู้คนจะเห็นเชิงอรรถ
Geobits

คุณสามารถส่งคืนผลลัพธ์แทนการพิมพ์ได้ 3 ไบต์
kirbyfan64sos

1
@ kirbyfan64sos: ฉันกำลังพิมพ์ผลลัพธ์เพื่อหลีกเลี่ยงความต้องการที่จะเข้าร่วมบรรทัด ถ้าฉันสามารถยอมรับและส่งกลับผลลัพธ์เป็นรายการของสตริงหนึ่งรายการสำหรับแต่ละบรรทัดฉันสามารถบันทึก`0:และ `" \ n "\ '
JohnE

@ JohnE ฉันไม่ได้มีกฎบอกว่าคุณทำไม่ได้ดังนั้นฉันเดาว่าคุณทำได้ :)
kirbyfan64sos

8

Perl, 23 ไบต์

22 ไบต์รหัส + 1 ไบต์บรรทัดคำสั่ง

หวังว่าจะไม่หน้าด้านเกินไปที่จะสมมติว่าอินพุตตัวเลขสามารถได้รับผ่านพารามิเตอร์ -i! ตรวจสอบให้แน่ใจว่าได้แทนที่ \ t ในโค้ดด้านล่างด้วยอักขระแท็บจริง

s/\G\t/$"x$^I/ge;y/\t/ /

ตัวอย่างการใช้งาน:

printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4

หรือเพื่อความสะดวก:

printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4

คำอธิบาย:

ใช้ -pอาร์กิวเมนต์จะเรียกใช้งานโปรแกรมสำหรับทุกบรรทัดในอินพุตจากนั้นพิมพ์ผลลัพธ์ในตอนท้าย

ในตัวอย่างข้างต้นการทดแทน regex แทนที่\G\tด้วย" "x4(เว้นวรรคซ้ำสี่ครั้ง) \Gเป็นโครงสร้าง regex ที่รู้จักกันน้อยซึ่งตรงกับตำแหน่งของการจับคู่ครั้งแรกหากการทำซ้ำครั้งแรกหรือจากตำแหน่งของการแข่งขันก่อนหน้านี้หากไม่ใช่การทำซ้ำครั้งแรกหมายความว่ามันจะแทนที่แท็บทั้งหมดที่จุดเริ่มต้นของสตริงเท่านั้น ทำแบบหนึ่งต่อหนึ่ง y/\t/ /เพียงแทนที่แท็บที่เหลืออยู่ทั้งหมดที่มีช่องว่าง


2

จูเลีย69 69ไบต์

f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")

Ungolfed:

function f(s::String, n::Int)
    # Replace the leading indentation tabs
    r1 = replace(s, r"^\t*"m, i -> " "^endof(i)n)

    # Replace any remaining tabs between words
    r2 = replace(r1, r"\t", " ")

    # Return
    r2
end

บันทึก 10 ไบต์และแก้ไขปัญหาต้องขอบคุณ Glen O!


มีประโยชน์ในการแทนที่แท็บเยื้องชั้นนำแยกกันหรือไม่ ดูเหมือนว่าฉันควรได้รับการจัดการโดยตรงโดยส่วน "แท็บที่เหลือ" นอกจากนี้คุณ "เปลี่ยนแท็บระหว่างข้อความ" เพียงส่วนหนึ่งจะตรงกับแท็บเดียวสิ่งที่ถ้าคุณมี"hello\t\t1"?
เกลน O

หากเราถือว่าการเยื้องทั้งหมดกระทำโดยใช้แท็บ (ไม่มี"\t \t"สถานการณ์) คุณสามารถทำสิ่งนี้ได้: f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")ซึ่งใช้ฟังก์ชันการแทนที่และจะจับแท็บการเยื้องทั้งหมดในครั้งเดียว
เกลน O

@GlenO ว้าวนั่นเป็นอัจฉริยะจริงๆ ขอบคุณมาก!
Alex A.

ฉันสังเกตว่าคำตอบของฉันถูกลดระดับลง มีอะไรฉันทำผิดหรือเปล่า? ฉันยินดีที่จะแก้ไขปัญหาใด ๆ
Alex A.

ฉันไม่เห็นปัญหาใด ๆ อาจเป็นเพียงหนึ่งในประเภทพยาบาทที่ downvote เพราะพวกเขาไม่ชอบภาษาหรือสิ่งเช่นนั้น? ฉันไม่เห็นข้อบกพร่องใด ๆ
เกลน O


2

Mathematica, 42 37 ไบต์

ขอบคุณ @ LegionMammal978 สำหรับคำแนะนำในการประหยัดรหัสหลายข้อ พารามิเตอร์แรกใช้#สำหรับข้อความอินพุตพารามิเตอร์ที่สอง#2สำหรับจำนวนช่องว่างต่อแท็บ

StringReplace[#,"\t"->" "~Table~{#2}]&

นอกจากนี้คุณยังสามารถเปลี่ยนTable[" ",{#2}]ไป" "~Table~{#2}เพื่อประหยัดไบต์ ทำไมคุณStringJoinถึงฝังสตริงว่างไว้?
LegionMammal978


1

JavaScript (ES6), 70

การใช้สตริงแม่แบบขึ้นบรรทัดใหม่มีความสำคัญและนับ

(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

ทดสอบการเรียกใช้ตัวอย่างข้อมูลด้านล่างใน Firefox

F=(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

// TEST
out=x=>O.innerHTML+=x+'\n\n'

out('Input: "A\\n\\t\\tB\\tC\\nD" 4\nOutput:\n'+F('A\n\t\tB\tC\nD',4))

out('Input: "\\tA\\t\\tB" 4\nOutput:\n'+F('\tA\t\tB', 4))
<pre id=O></pre>


1
ว้าว downvote หนึ่ง! อาจเป็นคนที่ไม่สามารถอ่านหรือเข้าใจ 'ทดสอบใน Firefox' ได้ไหม
edc65

ฉันสงสัยว่าภาษามีอคติ Julia และ CJam ก็ลงคะแนนเช่นกัน
เดนนิส

1

CoffeeScript ขนาด 72 ไบต์

(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "

(พยายามที่จะตีมันอย่างน้อยอีก 2 กัดดังนั้นมันจะชนะ ES6 ทางออก ... ช่วยชื่นชม: D)

การใช้งาน:

f=(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
str="""
My nice\tString
\tIndent <--
\t\tDouble
""" #\t is recognized as tab by CS
alert(f(str,4))

1

เรติน่า 42 ไบต์

สิ่งที่เกิดขึ้นทั้งหมด.เป็นช่องว่างทั้งหมด\tเป็นแท็บตัวอักษร (1 ไบต์) และ<empty>แสดงถึงไฟล์เปล่า มันเป็นเพียงสำหรับการอ่าน ฉันก็ไม่แน่ใจเหมือนกันว่าฉันทำถูกต้องแล้ว แต่ละบรรทัดควรอยู่ในไฟล์ของตัวเอง ฉันได้เพิ่ม 1 ไบต์สำหรับแต่ละไฟล์เพิ่มเติม

อินพุตถูกสมมติว่าเป็น Unary บนบรรทัดของมันเองที่ส่วนท้ายของอินพุต

(1*)$
_$1
m+`(?<!^|\t)\t
.
(`1$
<empty>
)`\t
\t.
\t|_
<empty>

คำอธิบาย

ฉันเพิ่ม_ก่อนหน้าอินพุต Unary เพื่อกำหนดเขตข้อมูลในระหว่างการแทนที่ดังนั้นฉันจะไม่ลบสิ่งที่ต่อท้ายออกจากสตริงอินพุต จากนั้นฉันจะแทนที่แท็บทั้งหมดที่ไม่ใช่จุดเริ่มต้นของบรรทัดด้วยช่องว่างเดียว จากนั้นฉันวนซ้ำลบหนึ่ง1และเพิ่มช่องว่างเดียวหลังจากแต่ละแท็บจนกว่าฉันจะหมดอินพุต ในที่สุดฉันก็ทำความสะอาดโดยลบแท็บและขีดล่าง


1

Python ขนาด72 68 ไบต์

แท็บคือแท็บตัวอักษร (1 ไบต์) ดังนั้นจึงr'...'ไม่จำเป็น แต่น่าเสียดายที่งูใหญ่ต้องใช้ "ความกว้างคงที่" มองดุ๊กดิ๊ก / มอง Aheads (?<!^|\t)ดังนั้นผมจึงไม่สามารถใช้ ใช้วิธีการเดียวกับโซลูชัน Retina ของฉัน

import re
lambda s,n:re.sub('\t',' '*n,re.sub('(?<!^)(?<!\t)\t',' ',s))




0

Haskell , 75 ไบต์

s#m|let('\t':r)#n=(' '<$[1..n])++r#n;(x:r)#n=x:r#(m^sum[1|x<' ']);e#_=e=s#m

ลองออนไลน์!สิ่งนี้ถือว่าอินพุตมีเฉพาะอักขระที่พิมพ์ได้รวมถึงแท็บและบรรทัดใหม่ตามที่ OP อนุญาตในข้อคิดเห็น

คำอธิบาย:

#ฟังก์ชั่นด้านนอกใช้สตริงsและตัวเลขmและเรียกใช้#ฟังก์ชั่นภายในที่กำหนดไว้ในท้องถิ่นที่มีข้อโต้แย้งที่เหมือนกัน สิ่งนี้ทำเพื่อติดตามmค่าดั้งเดิมเมื่อ#ฟังก์ชันด้านในเปลี่ยนจำนวน

  • ('\t':r)#n=(' '<$[1..n])++r#nหากคุณพบแท็บแทนที่ด้วยnช่องว่างและออกnไม่เปลี่ยนแปลง
  • (x:r)#n=x:r#(m^sum[1|x<' '])หากมีบางxแท็บที่ไม่พบแท็บให้คงเดิม แต่ตั้งค่าnเป็นหมายเลขเดิมmหากxเป็นบรรทัดใหม่และเป็น1อย่างอื่น นี้จะกระทำโดยm^sum[1|x<' ']: mจะนำไปพลังของsum[1|x<' ']ซึ่งประเมิน1เมื่อxมีขนาดเล็กกว่าพื้นที่ (เช่นการขึ้นบรรทัดใหม่) m^1 = mดังนั้นเราได้รับ มิฉะนั้นมันและเรามี0m^0 = 1

0

Java 11, 134 ไบต์

n->s->{var r="";for(var p:s.split("\n")){for(;p.charAt(0)==9;p=p.substring(1))r+=" ".repeat(n);r+=p+"\n";}return r.replace('\t',' ');}

ลองออนไลน์
หมายเหตุ: Java 11 ยังไม่ได้อยู่ใน TIO ดังนั้นจึง" ".repeat(n)ถูกจำลองเป็นrepeat(" ",n)แทน (ด้วยจำนวนไบต์เดียวกัน)

คำอธิบาย:

n->s->{                 // Method with integer & String parameters and String return-type
  var r="";             //  Result-String, starting empty
  for(var p:s.split("\n")){
                        //  Loop over the rows (split by new-lines)
    for(;p.charAt(0)==9;//   Inner loop as long as the current row starts with a tab
       p=p.substring(1))//     After every iteration: remove the first character (tab)
      r+=" ".repeat(n); //    Append `n` amount of spaces to the result-String
    r+=p+"\n";}         //   Append the rest of the row with a newline to the result
  return r.replace('\t',' ');} 
                        //   Replace any remaining tabs with a space, and return the result
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.