Xóa các không gian hàng đầu phổ biến


19

Khi mã hóa bằng Python, đôi khi bạn muốn có một chuỗi nhiều dòng trong một hàm, ví dụ:

def f():
    s = """\
    Line 1
    Line 2
    Line 3"""

(Dấu gạch chéo ngược là để xóa một dòng mới hàng đầu)

sTuy nhiên, nếu bạn cố gắng thực sự in ra , bạn sẽ nhận được

    Line 1
    Line 2
    Line 3

Đó không phải là những gì chúng ta muốn! Có quá nhiều khoảng trắng hàng đầu!

Các thách thức

Đưa ra một chuỗi nhiều dòng chỉ bao gồm các ký tự chữ và số, dấu cách và dòng mới, loại bỏ tất cả các khoảng trắng chung từ đầu mỗi dòng. Mỗi dòng được đảm bảo có ít nhất một ký tự không phải khoảng trắng và sẽ không có dấu cách. Đầu ra có thể không có khoảng trắng bên ngoài, cho dù đó là trước hoặc sau toàn bộ đầu ra hoặc một dòng riêng lẻ (ngoại trừ một dòng mới theo dõi tùy chọn duy nhất).

Đầu vào có thể thông qua STDIN hoặc đối số chức năng và đầu ra có thể thông qua STDOUT hoặc giá trị trả về của hàm. Bạn không thể sử dụng bất kỳ nội dung nào được thiết kế để trích xuất các chuỗi đa dòng hoặc thực hiện tác vụ chính xác này, ví dụ: Python textwrap.dedent.

Đây là , vì vậy giải pháp trong vài byte nhất sẽ thắng. Tiêu chuẩn áp dụng.

Các trường hợp thử nghiệm

"a"                                  ->   "a"
"   abc"                             ->   "abc"
"   abc\n def\n  ghi"                ->   "  abc\ndef\n ghi"
"    a\n    b\n    c"                ->   "a\nb\nc"
"    a\n    b\n    c\nd"             ->   "    a\n    b\n    c\nd"
"   a   b\n     c     d\n    e f"    ->   "a   b\n  c     d\n e f"

Ví dụ, trường hợp thử nghiệm cuối cùng là

   a   b
     c     d
    e f

và sẽ trông như thế này sau khi tước bỏ không gian hàng đầu:

a   b
  c     d
 e f

Có thể đầu ra có khoảng trắng dấu?
orlp 16/07/2015

@orlp Không nó có thể không, sẽ làm rõ.
Sp3000

Câu trả lời:


12

CJam, 20 14 byte

qN/_z{S-}#f>N*

Thuật toán :

  • Trước tiên chúng tôi phân chia đầu vào trên dòng mới và lấy một bản sao ( qN/_)
  • Sau đó, cột nhỏ nhất có ký tự không gian được tính bằng cách hoán chuyển mảng được phân tách dòng mới và sau đó chỉ cần tìm chỉ mục của hàng không phải là tất cả không gian đầu tiên ( z{S-}#)
  • Sau đó, chúng tôi chỉ cần xóa nhiều ký tự khỏi mỗi dòng ( f>)
  • Cuối cùng, chúng tôi tham gia bằng dòng mới một lần nữa ( N*)

Mở rộng mã

qN/               e# Read the entire input and split it on newline
   _z             e# Take a copy and transpose rows with columns.
                  e# Now we would have a bunch of all space rows. These rows are the ones
                  e# we want to remove (in form of columns) 
     {  }#        e# Get the index of the first item from the transposed array that returns
                  e# true for this block
      S-          e# From each part, remove spaces. If the part is all-space, it will return
                  e# an empty string, which is false in CJam. We finally will get the index
                  e# of the first non-all-space row (or column)
          f>      e# We take that index and remove that many characters from starting of each
                  e# row of the initial newline separated input
            N*    e# Join the array back using newlines and automatically print the result

Dùng thử trực tuyến tại đây


8

Pyth, 19 18 17 14 byte

jbu>R!rhCG6G.z

Việc thực hiện là khá mát mẻ.

  1. u .zlấy tất cả các dòng stdin trong một mảng, đặt nó vào G. Sau đó, nó đánh giá cơ thể bên trong, đưa kết quả vào Gvà tiếp tục làm điều này cho đến khi nó không còn thay đổi (điểm cố định).

  2. !rhCG6hoán vị G, lấy phần tử đầu tiên của mảng được chuyển (cột đầu tiên), loại bỏ phần tử của bất kỳ khoảng trắng nào và kiểm tra xem có còn ký tự không khoảng trắng nào không.

  3. Giá trị từ 2 là boolean, có thể được xem là int 0 hoặc 1. >R Glấy số này và cắt bỏ nhiều ký tự bên trái của mỗi dòng G. Bước 1, 2 và 3 kết hợp về cơ bản có nghĩa là nó sẽ tiếp tục tước bỏ các cột của khoảng trắng cho đến khi không còn cột trắng nào.

  4. jb nối các mảng của dòng bằng dòng mới và in nó.


2
Bạn có thể vui lòng cho một lời giải thích nhỏ cho điều này? Điều này rất kỳ lạ với tôi!
bobbel 16/07/2015

2
@bobbel Giải thích thêm.
orlp 16/07/2015

Thực sự tuyệt vời, cảm ơn! Chưa bao giờ nghe về nó! Để thử trực tuyến này, tôi đã tìm thấy: pyth.herokuapp.com/ từ
bobbel 16/07/2015

8

sed - 26 byte

:;/(^|\n)\S/q;s/^ //mg;b

chạy với -rz

Khá đơn giản:

  /(^|\n)\S/q;           - quit if there is a line that starts with non-space
              s/^ //mg;  - remove exactly one space in each line
:;                     b - repeat

-rtùy chọn bật regexps mở rộng, -zđọc toàn bộ đầu vào dưới dạng một chuỗi (thực sự sử dụng NUL-byte làm dấu phân cách dòng)


Bạn không cần :;N;$!bhoặc tương tự để bắt đầu, để tập hợp các dòng đầu vào vào một không gian mẫu duy nhất? Chỉnh sửa: không bạn không; đó là những gì -zlá cờ dành cho.
Toby Speight

Bạn có thể chơi golf này :;/^\S/M!s/^ //mg;t, bây giờ không cần-r
Kritixi Lithos

7

SWI-Prolog, 233 223 217 byte

a(A):-b(A,0,0,0,N),w(A,N,0).
b([A|T],P,K,M,N):-P=1,(A=10,b(T,0,0,M,N);b(T,1,0,M,N));A\=32,(M=0;K<M),b(T,1,0,K,N);I=K+1,b(T,0,I,M,N).
b(_,_,_,N,N).
w([A|T],N,P):-P<N,A=32,Q=P+1,w(T,N,Q);put(A),A=10,w(T,N,0);w(T,N,P);!.

Chỉnh sửa : Hoàn toàn thay đổi câu trả lời của tôi. Bây giờ nó sử dụng mã ký tự thay vì chuỗi.

Một ví dụ về cách gọi này sẽ là a(` a b\n c d\n e f`)., với backquote. Bạn có thể cần phải sử dụng dấu ngoặc kép "thay thế nếu bạn có một bản phân phối SWI-Prolog cũ.


5

Julia, 93 92 81 byte

Đã lưu 10 byte nhờ Glen O.

s->for i=(p=split(s,"\n")) println(i[min([search(j,r"\S")[1]for j=p]...):end])end

Điều này tạo ra một hàm không tên chấp nhận một chuỗi và in ra thiết bị xuất chuẩn.

Ungolfed + giải thích:

function f(s)
    # Split s into an array on newlines
    p = split(s, "\n")

    # Get the smallest amount of leading space by finding the
    # position of the first non-space character on each line
    # and taking the minimum
    m = min([search(j, r"\S")[1] for j in p]...)

    # Print each line starting after m
    for i in p
        println(i[m:end])
    end
end

Bạn có thể tiết kiệm một số không gian bằng cách tìm kiếm không gian đầu tiên, thay vì đếm số lượng không gian. Thay vì minimum([length(search(j, r"^ +")) for j in p])+1sử dụng minimum([search(j,r"[^ ]")[1]for j=p]). Vì thách thức nói rằng tất cả các dòng sẽ có văn bản không phải không gian, nên nó an toàn và tiết kiệm cho bạn 9 byte (bao gồm cả 3 được lưu bằng cách sử dụng =thay vì `trong ). Still looking to see if more can be saved. (I wish I could drop the [1]`, nhưng tìm kiếm tạo ra một mảng liệt kê loại Any, trong khi yêu cầu tối thiểu một loại Int)
Glen O

Xin lỗi ở trên - rõ ràng, tôi đã sử dụng hết các chỉnh sửa của mình - đó không phải là 9 byte, mà là 6, vì tôi không lưu ý rằng bạn đã sử dụng = ở dạng chơi gôn. Dù sao, tôi có thể lưu thêm hai ký tự bằng cách xác định p khi bắt đầu vòng lặp for:s->for i=(p=split(s,"\n")) println(i[minimum([search(j,r"[^ ]")[1]for j=p]):end])end
Glen O

OK, đây là một cái khác để cạo thêm một chút - thay vì sử dụng minimum(x)khi nào xlà một mảng, hãy sử dụng min(x...), cho một byte được lưu thêm (Tôi sẽ thêm cái này vào danh sách các mẹo chơi golf của Julia).
Glen O

@GlenO Nice, cảm ơn những lời đề nghị. Ngoài ra, vì Julia sử dụng PCRE, các ký tự không phải khoảng trắng có thể được khớp với \Sthay vì [^ ], giúp tiết kiệm một byte.
Alex A.

Xin chào, cảm ơn vì đã đề cập đến điều đó - Tôi không tốt với regex, nhưng hóa ra nó \Scũng hữu ích cho giải pháp của tôi.
Glen O

4

Java, 159

Bởi vì thiếu Java dễ thấy ...

void f(String...a){int s=1<<30,b;a=a[0].split("\n");for(String x:a)s=(b=x.length()-x.trim().length())<s?b:s;for(String x:a)System.out.println(x.substring(s));}

Nó chỉ là các vòng so sánh chiều dài với chiều dài được cắt, sau đó phun ra các chuỗi con. Không có gì quá lạ mắt. Đối với thanh cuộn bị suy yếu:

void f(String...a){
    int s=1<<30,b;
    a=a[0].split("\n");
    for(String x:a)
        s=(b=x.length()-x.trim().length())<s?b:s;       
    for(String x:a)
        System.out.println(x.substring(s));
}

4

Perl, 47 33

Cảm ơn @ ThisSuitIsBlackNot đã gợi ý sử dụng vòng lặp ẩn của Perl

#!/usr/bin/perl -00p
/^( +).*(\n\1.*)*$/&&s/^$1//mg

Ở trên được ghi là 30 byte cho dòng mã + 3 cho 00pcờ.

Phiên bản gốc, là một chức năng:

sub f{$_=@_[0];/^( +).*(\n\1.*)*$/&&s/^$1//mgr}

Điều này đặt đối số vào $_, sau đó cố gắng khớp một cách tham lam khoảng trắng có trên tất cả các dòng với /^( +).*(\n\1.*)*$/- nếu thành công, $1bây giờ chứa tiền tố chung dài nhất và chúng tôi thực hiện thay thế s/^$1//mgrđể xóa nó từ đầu mỗi dòng và trả về chuỗi kết quả.

Kiểm tra

$ cat 53219.data
   a   b
     c     d
    e f
$ ./53219.pl <53219.data 
a   b
  c     d
 e f

Rất tuyệt. Bạn có thể tắt một số byte bằng cách chạy trên dòng lệnh: perl -00pe '/^( +).*(\n\1.*)*$/&&s/^$1//mg'(30 byte + 3 cho 00p).
ThisSuitIsBlackNot

/međứng đầu để nhìn lên -00p; cảm ơn @ ThisSuit
Toby Speight

3

Python 2, 86 79 75 byte

Điều này gần như chắc chắn có thể được rút ngắn thêm một số, nhưng ngay bây giờ nó không phải là xấu.

Cảm ơn xnor vì đã tiết kiệm 4 byte!

s=input().split('\n')
for k in s:print k[min(x.find(x.strip())for x in s):]

1
Một cách ngắn hơn một chút để đếm không gian hàng đầu là x.find(x.strip()).
xnor 16/07/2015

@xnor gọi tốt, cảm ơn! Tôi đã chờ đợi một giải pháp 60 byte từ bạn cả ngày; P
Kade

input()trong Python 2 sẽ làm nghẹt dữ liệu này.
Steven Rumbalski

@StevenRumbalski, tôi giả sử rằng đầu vào được bao quanh bởi dấu ngoặc kép. Tôi đã từng thêm 2 vào số byte để tính đến điều này, nhưng nhiều người đã nói rằng tôi không cần phải làm vậy.
Kade

1
Chương trình này thật đáng buồn:):
HyperNeutrino

3

Ruby: 77 73 70 66 65 58 57 40 ký tự

f=->t{t.gsub /^#{t.scan(/^ */).min}/,""}

Chạy mẫu:

irb(main):001:0> f=->t{t.gsub /^#{t.scan(/^ */).min}/,""}
=> #<Proc:0x00000001855948@(irb):1 (lambda)>

irb(main):002:0> puts f["   a   b\n     c     d\n    e f"]
a   b
  c     d
 e f
=> nil

irb(main):003:0> f["   a   b\n     c     d\n    e f"] == "a   b\n  c     d\n e f"
=> true

2
Thế còn f=->t{t.gsub /^#{t.scan(/^ */).min}/,""}?
Ventero 16/07/2015

Thật tuyệt, @Ventero. Cảm ơn bạn.
manatwork

2

C #, 18 + 145 = 163 byte

Yêu cầu (18 byte):

using System.Linq;

Phương thức (145 byte):

string R(string s){var l=s.Split('\n');return string.Join("\n",l.Select(x=>string.Concat(x.Skip(l.Select(z=>z.Length-z.Trim().Length).Min()))));}

Phương thức tính toán lượng không gian hàng đầu thấp nhất trên các dòng và tạo ra một chuỗi mới được xây dựng cho tất cả các dòng, với N ký tự được bỏ qua (trong đó N là số được tính trước đó).


1

C #, tổng cộng 149 byte

Thực tế là giải pháp tương tự như của ProgramFOX, mặc dù số lượng ký tự cần cắt được tính thủ công.

using System.Linq;

Và chính chức năng:

string D(string s){var l=s.Split('\n');int i=0;while(l.All(a=>a[i]==' '))i++;return string.Join("\n",l.Select(b=>b.Substring(i)));}

@ProgramFOX Tôi đã không thấy giải pháp của bạn cho đến khi tôi làm mới trang btw: o)
Sok

1

Trăn 3, 100

def f(s):t=s.split("\n");return"\n".join([c[min([len(c)-len(c.lstrip(" "))for c in t]):]for c in t])

1

JavaScript, ES6, 89 86 byte

Điều này là hoàn toàn sử dụng chỉ phù hợp và thay thế RegEx.

f=x=>eval(`x.replace(/(^|\\n) {${--`
${x}`.match(/\n */g).sort()[0].length}}/g,"$1")`)

// Snippet related stuff
B.onclick=x=>P.innerHTML=f(T.value)
<textarea id=T></textarea><br>
<button id=B>Trim</button>
<pre id=P></pre>

Như mọi khi, chỉ có Firefox, kể từ ES6. Sẽ thêm phiên bản ES5 sau.


1
Có vẻ như sẽ ngắn hơn khi viết một biểu thức thông thường theo nghĩa đen dưới dạng một chuỗi và sau đó đánh giá nó
Downgoat 16/07/2015

@ vihan1086 bạn có thể đúng. Hãy để tôi thử.
Trình tối ưu hóa

1

K, 31 byte

{`0:(&/{(0;#*=x)@*x}'" "=x)_'x}

Đưa vào danh sách các chuỗi và in kết quả ra thiết bị xuất chuẩn.


1

Haskell, 52 byte

unlines.until(any(/=' ').map head)(map tail).lines

Ví dụ sử dụng: unlines.until(any(/=' ').map head)(map tail).lines $ " abc\n def\n ghi"->" abc\ndef\n ghi\n"

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

                                           lines    -- split the input at newlines into a list of lines
        until                                       -- repeat the 2nd argument, i.e.
                                 map tails          -- cut off the heads of all lines
                                                    -- until the the first argument returns "True", i.e.
             any(/=' ').map head                    -- the list of heads contains at least one non-space
unlines                                             -- transform back to a single string with newlines in-between

1

Con trăn, 94/95

lambda (94 byte):

f=lambda s:'\n'.join(l[min(l.find(l.strip()) for l in s.split('\n')):] for l in s.split('\n'))

def (95 byte)

def f(s):l=s.split('\n');m=min(i.find(i.strip())for i in l);return '\n'.join(i[m:] for i in l);

1

bash + sed + coreutils, 74 , 56 , 55

Dữ liệu kiểm tra

s="\
   a   b
     c     d
    e f"

Câu trả lời

cut -c$[`grep -o '^ *'<<<"$s"|sort|line|wc -c`]-<<<"$s"

Đầu ra

a   b
  c     d
 e f

2
Một vài thay đổi golf đơn giản làm giảm số điểm này xuống 56 trong số của tôi:cut -c$[`grep -o '^ *'<<<"$s"|sort|sed q|wc -c`]-<<<"$s"
Chấn thương kỹ thuật số

1
@DigitalTrauma: Hay đấy, tôi quên mất $[]số học. Sử dụng cutđể lựa chọn cột là tốt hơn nhiều. Tôi chưa bao giờ thấy sed qnhư là một thay thế head -n1, đó là một mẹo chơi golf tốt. Cảm ơn!
Thor

2
Về head -n1vs sed q, có một linecông cụ trong gói linux-linux.
manatwork

@manatwork: Điều đó tiết kiệm một ký tự, tôi sẽ sử dụng nó. Lưu ý rằng nó không được dùng nữa và có thể biến mất trong tương lai, đây là từ deprecated.txt trong cây nguồn của linux-linux: "Tại sao: vô dụng, không ai sử dụng lệnh này, head (1) là tốt hơn".
Thor

1

R 118 111 byte

Sử dụng các hàm chuỗi tuyệt vời của R :) Điều này tương tự / giống với các giải pháp khác đã được đăng. Đầu vào là thông qua STDIN và mèo đến STDOUT.

cat(substring(a<-scan(,'',sep='|'),Reduce(min,lapply(strsplit(a,' '),function(x)min(which(x>''))-1))),sep='\n')

Kiểm tra và giải thích

> cat(substring(a<-scan(,'',sep='|'),Reduce(min,lapply(strsplit(a,' '),function(x)min(which(x>''))-1))),sep='\n')
1:                  a<-scan(,'',sep='|') # get the input lines
2:                                                         strsplit(a,' ') # split lines on spaces
3:                                                  lapply(                ,function(x)min(which(x>''))-1) # get min index - 1 for non space of each line
4:                                      ,Reduce(min,                                                      ) # get the min of those
5:        substring(                                                                                       ) # trim it off
6:    cat(                                                                                                  ,sep='\n') # output each line
7:
Read 6 items
              a<-scan(,'',sep='|') # get the input lines
                                                     strsplit(a,' ') # split lines on spaces
                                              lapply(                ,function(x)min(which(x>''))-1) # get min index - 1 for non space of each line
                                  ,Reduce(min,                                                      ) # get the min of those
    substring(                                                                                       ) # trim it off
cat(                                                                                                  ,sep='\n') # output each line
> 

Này, chúc mừng đại diện 3k!
Alex A.

@AlexA. Chúc mừng, tôi không nghĩ nó quan trọng với tôi ... nhưng :)
MickyT

Bạn có nghĩa là cuộc sống của bạn không xoay quanh các điểm Internet giả? : P
Alex A.

@AlexA. Hy vọng là không :) chúc mừng 6k
MickyT

1

Julia, 72 62 61 57 54 49 byte

g=s->ismatch(r"^\S"m,s)?s:g(replace(s,r"^ "m,""))

Ung dung:

g(s)=
if ismatch(r"^\S"m,s)       # Determines if there's a newline followed by something other than a space
                            # Note: the m in r"^ "m says to work in multiline mode.
    s                       # If there is, return the string as the final result.
else                        # otherwise...
    m=replace(s,r"^ "m,"")  # Remove first space after each newline, and space at start of string.
    g(m)                    # Feed back into the function for recursion
end

Giải pháp cũ hơn (57 byte):

g(s)=ismatch(r"
\S","
"s)?s:g(replace(s,"
 ","
")[2:end])

Giải pháp gốc (72 byte):

g(s)=all([i[1]<33for i=split(s,"\n")])?g(replace(s,"\n ","\n")[2:end]):s

1

k (24 byte)

Lấy một chuỗi làm đối số và trả về một chuỗi (có dòng mới).

{`/:(&//&:'~^s)_'s:`\:x}

Thí dụ:

k) f:{`/:(&//&:'~^s)_'s:`\:x};
k) f"   a   b\n     c     d\n    e f"
"a   b\n  c     d\n e f\n

1

05AB1E , 10 byte

|©ζ®gð*Ûζ»

Hãy thử trực tuyến!


Đợi đã, *lặp lại chuỗi b một số lần? .. Không biết về tính năng đó của *. Tôi thường làm s∍(hoán đổi và kéo dài) khi tôi muốn lặp lại một nhân vật nào đó.
Kevin Cruijssen

Vâng, thực sự, điều đó làm việc cho các chuỗi, chủ yếu là do vector hóa không hoàn toàn có ý nghĩa trong trường hợp chuỗi và иmang lại một danh sách các ký tự.
Ông Xcoder

0

Gawk, 101 100

{match($0,/^( +)/,t);if(t[1]<s||s==""){s=t[1]};z[NR]=$0;}END{for(r in z){sub(s,"",z[r]);print z[r]}}

Ví dụ...

cat input.txt | gawk '{match($0,/^( +)/,t);if(t[1]<s||s==""){s=t[1]};z[NR]=$0;}END{for(r in z){sub(s,"",z[r]);print z[r]}}'

Đầu ra ...

a   b
  c     d
 e f

Chỉ cần gợi ý thử nghiệm: không nắm bắt /^( +)//^ +/(sau đó bạn sẽ có giá trị cần thiết t[0]thay vì t[1]); thay đổi s==""!s; loại bỏ {}xung quanh mã sau if; loại bỏ ;trước }; sử dụng chức năng dành riêng cho Gawk để có thể xóa {}xung quanh mã sau for: {sub(s,"",z[r]);print z[r]}print gensub(s,"",1,z[r]).
manatwork

Rất tiếc phải nói, nhưng cả mã gốc của bạn và mã tối ưu hóa kích thước của tôi đều thất bại ở đầu vào với một dòng không được cấp phép, ngoại trừ mã cuối cùng. (Ví dụ: "␠one \ nzero \ n␠one \ n␠␠two".)
thao tác

0

C GCC, 74 byte

main(_,z){z=1;while(-~(_=getchar()))putchar(_==32&&z?0:(z=_==10?1:0,_));}

Chỉ xóa tất cả các khoảng trắng, không liên quan đến các dòng trước đó, yêu cầu trợ giúp để kết thúc. CSONG, xét về các khoảng trắng thông thường, OP có nghĩa là dòng nào có ít khoảng trắng hàng đầu nhất, đó là số lượng khoảng trắng sẽ bị xóa khỏi mỗi dòng?


Có, sử dụng dòng có ít khoảng trắng hàng đầu là chính xác.
Sp3000

0

Xếp chồng , không biên dịch, 43 byte

:lines'^ +'match$#'"!MIN' '*0# '^'\+''mrepl

Hãy thử trực tuyến!

Điều này hoạt động bằng cách tìm số lượng khoảng trắng ở đầu mỗi dòng ( '^ +'match$#'"!), lấy mức tối thiểu, lặp lại một khoảng trắng nhiều lần và thay thế khoảng trống đó bằng không có gì trên mỗi dòng.




-1

CoffeeScript, 112 bytes

f=(x)->(a=x.split "\n").map((v)->v[Math.min.apply(null,a.map((v)->(r=/^ +/.exec v)&&r[0].length))...]).join "\n"

-1

JavaScript (ES6), 106 98 bytes

The newlines are necessary and are counted as 1 byte each:

f=x=>(a=x.split`
`).map(v=>v.slice(Math.min(...a.map(v=>(r=/^ +/.exec(v))&&r[0].length)))).join`
`

Demo

As with other ES6 answers, they only work in Firefox at the moment.

f=x=>(a=x.split`
`).map(v=>v.slice(Math.min(...a.map(v=>(r=/^ +/.exec(v))&&r[0].length)))).join`
`

// For demonstration purposes
console.log = x => X.innerHTML += x + `\n<hr>`;

console.log(f("a"));
console.log(f("   abc"));
console.log(f("   abc\n def\n  ghi"));
console.log(f("    a\n    b\n    c"));
console.log(f("    a\n    b\n    c\nd"));
console.log(f("   a   b\n     c     d\n    e f"));
<pre id=X></pre>


11
It would be great if the downvoter could explain…
rink.attendant.6

-1

JavaScript ES6, 85 bytes

s=>s.split`
`.map(z=>z.slice(Math.min(...s.match(/^ */gm).map(l=>l.length)))).join`
`

The new lines are significant

ES5 Demo:

function t(s) {
  return s.split("\n").map(function(z) {
    return z.slice(Math.min.apply(0, s.match(/^ */gm).map(function(l) {
      return l.length;
    })));
  }).join('');
}

// Demo
document.getElementById('go').onclick = function() {
  document.getElementById('r').innerHTML = t(document.getElementById('t').value)
};
Input:
<br>
<textarea id="t"></textarea>
<br>
<button id="go">Run</button>
<br>Output:
<br>
<pre style="background-color:#DDD;" id="r"></pre>


-1

JavaScript (ES6) 56

Recursive, trying to remove one space at a time from each row until a non-space is found.

Test running the snippet below - being ES6, Firefox only

f=s=>(r=s.replace(/^./gm,x=>(k|=x>' ',''),k=0),k?s:f(r))

// Test
test=
[[ "a", "a" ]
,["   abc", "abc" ]
,["   abc\n def\n  ghi", "  abc\ndef\n ghi" ]
,["    a\n    b\n    c", "a\nb\nc" ]
,["    a\n    b\n    c\nd", "    a\n    b\n    c\nd" ]
,["   a   b\n     c     d\n    e f","a   b\n  c     d\n e f" ]]

var tb=''
test.forEach(t=>{
  t[2]=f(t[0])
  t[3]=t[2]==t[1]?'OK':'FAIL'
  tb+='<tr><td>'+t.join('</td><td>')+'</td></tr>'
})
B.innerHTML=tb
td { white-space: pre; font-family: monospace; border: 1px solid#444; vertical-align:top}
#I,#O { height:100px; width: 200px }
<b>Your test:</b>
<table><tr><td><textarea id=I></textarea></td>
<th><button onclick='O.innerHTML=f(I.value)'>-></button></th>
<td id=O></td></tr></table>
<b>Test cases:</b><br>
<table ><tr><th>Input</th><th>Expected</th><th>Output</th><th>Result</th></tr>
<tbody id=B></tbody></table>

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.