Trời ơi, nó được bao phủ trong các tab!


26

Không gian thụt lề người dùng, đoàn kết ! Chúng tôi phải chiến đấu chống lại tất cả người dùng tab thấp !

Nhiệm vụ của bạn (nếu bạn chọn chấp nhận nó) là viết một chương trình hoặc hàm có hai đối số:

  • Một chuỗi: Đây là đầu vào.
  • Một số nguyên dương: Đây là số lượng khoảng trắng trên mỗi tab.

Bạn phải đi qua từng dòng của chuỗi và thay thế mọi tab được sử dụng để thụt lề bằng số khoảng trắng đã cho và mọi tab không được sử dụng để thụt lề (ví dụ ở giữa một dòng) bằng một khoảng trắng.

Lưu ý rằng các dòng như là \t \tabchành vi không xác định; chúng được chèn bởi những người dùng tab ác để làm phức tạp các chương trình của bạn.

Theo Hiệp hội Tab Must Die, chương trình của bạn phải càng ngắn càng tốt để tránh bị người dùng tab ác phát hiện.

Thí dụ

\t được sử dụng để đại diện cho các tab ở đây.

Chuỗi đầu vào:

a
\t\tb\tc
d

Số đầu vào:

4

Đầu ra:

a
        b c
d

Đường giữa được thụt vào bởi 8 khoảng trắng, 4 khoảng trên mỗi tab (vì số đã cho là 4).

Chuỗi đầu vào:

\ta\t\tb

Số đầu vào:

4

Đầu ra:

    a  b

LƯU Ý: Đây không phải là bản sao của thử thách mở rộng tab ; nó đòi hỏi một định dạng đầu vào rất khác nhau và các yêu cầu hơi khác nhau.


1
, miễn là câu hỏi không yêu cầu rõ ràng về số thập phân (mà nó không có).
Martin Ender


1
Chúng ta có thể giả sử rằng đầu vào chỉ chứa ASCII, tab và dòng mới có thể in được không?
Dennis

2
Trường hợp thử nghiệm được đề xuất : \ta\t\tb, 4(bản sửa đổi trước đây của tôi đã thất bại trong trường hợp đó)
Dennis

2
Chúng ta cần một câu trả lời trong khoảng trắng.
Kaz Wolfe

Câu trả lời:


7

CJam, 30 24 23 byte

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

Tôi thường từ chối đăng mã độc trên mạng Internet

Đây là một chương trình đầy đủ đọc chuỗi từ STDIN và số dưới dạng đối số dòng lệnh.

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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.

Có gì NA=không:

  • Đối với ký tự đầu tiên, Nsẽ chứa giá trị mặc định của nó, tức là chuỗi "\n".

    Đối với tất cả các ký tự tiếp theo, Nsẽ chứa kết quả của lần lặp cuối cùng, nghĩa là ký tự cuối cùng từ đầu vào, ký tự khoảng trắng hoặc một chuỗi gồm một hoặc nhiều khoảng trắng.

  • Nếu Nlà một chuỗi, NA=chọn phần tử ở chỉ số 10 của N (bao quanh). Kết quả sẽ là một khoảng trắng hoặc một ký tự linefeed. Cả hai đều là sự thật.

    Nếu N là một ký tự, NA=đẩy 1 cho dòng cấp và 0 nếu không.

  • Vì những điều trên, NA=sẽ đẩy một giá trị trung thực cho ký tự đầu tiên, một ký tự đứng trước một nguồn cấp dữ liệu hoặc một ký tự đứng trước một chuỗi khoảng trắng (thụt đầu dòng đã được thay thế).

    Trong tất cả các trường hợp khác (bao gồm một trình lập bảng đã được thay thế bằng ký tự khoảng NA=trắng ), sẽ đẩy giá trị giả.


6
Điều tốt là bạn đang thực hiện dịch vụ Internet bằng cách xóa các tab độc hại. ;)
Alex A.

19

K5, 53 45 byte

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

Trong hành động:

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

Tôi chỉ muốn hồ sơ cho thấy rằng câu hỏi này là đáng trách về mặt đạo đức.


11
-21346106841 cho... this question is morally reprehensible.
TheNumberOne

3
Điều này cần kết thúc câu trả lời được bình chọn hàng đầu, đơn giản vì vậy mọi người sẽ thấy chú thích.
Geobits

Bạn có thể trả về kết quả thay vì in nó trong 3 byte.
kirbyfan64sos

1
@ kirbyfan64sos: Tôi đang in kết quả để tránh phải tham gia các dòng. Nếu tôi có thể chấp nhận và trả về kết quả dưới dạng danh sách các chuỗi, mỗi chuỗi cho mỗi dòng, tôi có thể lưu `0:và `" \ n "\`.
JohnE

@ John Tôi đã không đặt một quy tắc nói rằng bạn không thể, vì vậy tôi đoán bạn có thể. :)
kirbyfan64sos

8

Perl, 23 byte

22 byte mã + 1 byte dòng lệnh

Hy vọng không quá táo tợn khi cho rằng đầu vào số có thể được cung cấp thông qua tham số -i! Đảm bảo thay thế \ t trong mã bên dưới bằng ký tự tab thực tế.

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

Ví dụ sử dụng:

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

Hoặc để thuận tiện:

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

Giải trình:

Sử dụng -pđối số sẽ thực thi chương trình cho mọi dòng trong đầu vào, sau đó in kết quả ở cuối.

Trong ví dụ trên, sự thay thế regex thay thế \G\tbằng " "x4(một khoảng trắng được lặp lại bốn lần). \Glà một cấu trúc regex ít được biết đến khớp với vị trí của trận đấu đầu tiên nếu lần lặp đầu tiên hoặc từ vị trí của trận đấu trước nếu không phải là lần lặp đầu tiên, nghĩa là nó sẽ chỉ thay thế tất cả các tab ở đầu chuỗi và sẽ làm như vậy từng cái một Đơn y/\t/ /giản chỉ cần thay thế tất cả các tab còn lại bằng dấu cách.


2

Julia, 69 59 byte

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

Ung dung:

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

Đã lưu 10 byte và khắc phục sự cố nhờ Glen O!


Có bất kỳ lợi ích để thay thế các tab thụt đầu hàng đầu một cách riêng biệt? Dường như với tôi rằng nó nên được xử lý trực tiếp bởi phần "các tab còn lại". Ngoài ra, phần "thay thế các tab giữa văn bản" của bạn sẽ chỉ khớp với một tab duy nhất, nếu bạn có "hello\t\t1"thì sao?
Glen O

Nếu chúng tôi giả sử tất cả các vết lõm được thực hiện bằng các tab (không có "\t \t"tình huống nào ), bạn có thể làm điều này : f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," "), sử dụng chức năng thay thế và sẽ bắt tất cả các tab thụt trong một lần nhấn.
Glen O

@GlenO Wow, đó thực sự là thiên tài. Cám ơn rất nhiều!
Alex A.

Tôi nhận thấy câu trả lời của tôi đã bị hạ thấp. Có điều gì tôi đã làm sai? Tôi rất vui lòng giải quyết mọi vấn đề.
Alex A.

Tôi không thấy bất kỳ vấn đề. Có lẽ đó chỉ là một trong những kiểu thù hận mà hạ thấp vì họ không thích một ngôn ngữ, hoặc những thứ như vậy? Tôi không thể thấy bất kỳ sai sót.
Glen O


2

Toán học, 42 37 byte

Cảm ơn @ LegionMammal978 vì nhiều đề xuất tiết kiệm mã. Tham số đầu tiên, #dành cho văn bản đầu vào, tham số thứ hai #2, cho số lượng khoảng trắng trên mỗi tab.

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

Ngoài ra, bạn có thể thay đổi Table[" ",{#2}]để " "~Table~{#2}tiết kiệm một byte. Tại sao bạn StringJoining chuỗi rỗng vào nó?
LegionMammal978


1

JavaScript (ES6), 70

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

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

Kiểm tra chạy đoạn mã dưới đây trong 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
Wow một downvote! Có thể là người không thể đọc hoặc hiểu 'Kiểm tra trong Firefox'?
edc65

Tôi nghi ngờ thiên vị ngôn ngữ. Julia và CJam cũng bị hạ bệ.
Dennis

1

CoffeeScript, 72 byte

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

(Cố gắng đánh gôn ít nhất 2 lần nữa, vì vậy nó sẽ đánh bại giải pháp ES6 ... Giúp đánh giá cao: D)

Sử dụng:

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

Võng mạc, 42 byte

Tất cả các lần xuất hiện .là khoảng trắng, tất cả \tđều là các tab bằng chữ (1 byte) và <empty>thể hiện một tệp trống. Nó chỉ để đọc. Tôi cũng không hoàn toàn chắc chắn rằng tôi đang thực hiện đúng vòng lặp, nhưng tôi nghĩ vậy. Mỗi dòng nên được đặt trong tập tin riêng của mình. Tôi đã thêm 1 byte cho mỗi tệp bổ sung.

Đầu vào được coi là trong Unary trên chính dòng của nó ở cuối đầu vào.

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

Giải trình

Tôi thêm một _trước đầu vào Unary để phân định nó trong khi thay thế, để tôi không xóa bất kỳ cái nào ra khỏi chuỗi đầu vào. Sau đó, tôi thay thế tất cả các tab không ở đầu một dòng bằng một khoảng trắng. Sau đó, tôi lặp lại, xóa một đơn 1và thêm một khoảng trắng sau mỗi tab, cho đến khi tôi hết đầu vào. Cuối cùng, tôi dọn dẹp bằng cách loại bỏ các tab và gạch dưới.


1

Python, 72 68 byte

Tab là các tab theo nghĩa đen (1 byte), vì vậy r'...'không cần thiết. Thật không may, Python yêu cầu các giao diện / chiều rộng cố định "chiều rộng cố định", vì vậy tôi không thể sử dụng (?<!^|\t). Sử dụng khá nhiều phương pháp tương tự như giải pháp Retina của tôi.

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




0

Haskell , 75 byte

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

Hãy thử trực tuyến! Điều này giả định đầu vào chỉ chứa các ký tự có thể in cũng như các tab và dòng mới, như được OP cho phép trong các bình luận.

Giải trình:

Hàm ngoài #lấy một chuỗi svà một số mvà gọi hàm bên trong được xác định cục bộ #với cùng các đối số. Điều này được thực hiện để theo dõi mgiá trị ban đầu , vì #hàm bên trong thay đổi số:

  • ('\t':r)#n=(' '<$[1..n])++r#nNếu bạn gặp một tab, thay thế nó bằng ndấu cách và nkhông thay đổi.
  • (x:r)#n=x:r#(m^sum[1|x<' '])Nếu một số xkhông phải là một tab gặp phải, giữ nguyên như vậy nhưng được đặt thành nsố ban đầu mnếu xlà một dòng mới và 1ngược lại. Điều này được thực hiện bởi m^sum[1|x<' ']: mđược đưa đến sức mạnh sum[1|x<' ']để đánh giá 1khi nào xnhỏ hơn một khoảng trắng (tức là một dòng mới), vì vậy chúng tôi nhận được m^1 = m. Nếu không thì nó 0và chúng ta có m^0 = 1.

0

Java 11, 134 byte

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',' ');}

Hãy thử trực tuyến.
LƯU Ý: Java 11 chưa có trên TIO, do đó, " ".repeat(n)đã được mô phỏng repeat(" ",n)thay thế (với cùng số byte).

Giải trình:

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
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.