Khoảng trắng đáng kể


55

Chúng tôi xác định khoảng trắng là một trong ba ký tự, tab (0x09), dòng mới (0x0A) hoặc dấu cách (0x20).

Đối với thử thách này, bạn phải viết hai chương trình hoặc chức năng trong cùng một ngôn ngữ lập trình, thực hiện các tác vụ sau:

  1. Đếm các ký tự khoảng trắng trong một chuỗi đã cho. Ví dụ, đầu vào

      123 -_-   abc
    def
    

    sẽ trả về 7 (miễn là không có dòng mới).

  2. Tách một chuỗi nhất định tại các khoảng trắng liên tiếp. Nếu chuỗi bắt đầu hoặc kết thúc bằng khoảng trắng, không có chuỗi trống nào được trả về ở cuối. Chẳng hạn, cùng một đầu vào

      123 -_-   abc
    def
    

    sẽ quay trở lại ["123", "-_-", "abc", "def"].

Trong cả hai trường hợp, bạn có thể nhận đầu vào qua STDIN, đối số dòng lệnh hoặc đối số hàm trả về kết quả hoặc in nó STDOUT. Đối với chương trình thứ hai, nếu bạn chọn in sang STDOUT, vui lòng in từng chuỗi trên dòng riêng của nó, không có dấu ngoặc kép xung quanh.

Đối với cả hai chương trình, bạn có thể giả sử rằng đầu vào chỉ chứa ASCII có thể in (0x20 đến 0x7E) và khoảng trắng.

Bây giờ đây là bắt:

  • Nếu tất cả các khoảng trắng được loại bỏ khỏi cả hai chương trình / hàm, các chuỗi kết quả phải giống hệt nhau. Đó là, hai bài nộp của bạn chỉ có thể khác nhau về số lượng và vị trí của các ký tự khoảng trắng.
  • Cả chương trình / chức năng đều không thể chứa bất kỳ chuỗi ký tự hoặc biểu thức chính quy nào (nghĩa đen của ký tự là tốt, miễn là ngôn ngữ của bạn có loại ký tự được chỉ định).
  • Không chương trình / chức năng có thể chứa bất kỳ ý kiến.
  • Bạn không được đọc mã nguồn của chương trình, trực tiếp hoặc gián tiếp.

Đây là mã golf. Điểm của bạn là tổng kích thước của cả hai giải pháp (tính bằng byte). Điểm số thấp nhất chiến thắng.

Bảng xếp hạng

Đoạn trích sau đây tạo ra cả bảng xếp hạng thông thường và tổng quan về người chiến thắng theo ngôn ngữ. Vì vậy, ngay cả khi ngôn ngữ bạn chọn không cho phép bạn chiến thắng toàn bộ thử thách, tại sao bạn không thử giành một vị trí trong danh sách thứ hai? Tôi rất muốn xem mọi người giải quyết thách thức này bằng nhiều ngôn ngữ như thế nào!

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

# Language Name, N bytes

nơi Ntổng kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Bạn cũng có thể bao gồm số lượng cá nhân trước khi tổng số, ví dụ:

# Python 2, 35 + 41 = 76 bytes

Số cuối cùng không bị đánh xuyên qua sẽ được đoạn trích sử dụng.

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 42253;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


26
Bảng xếp hạng đó thật tuyệt!
Chấn thương kỹ thuật số

5
Âm thanh giống như bất kỳ câu trả lời Whitespace nào sẽ tuân thủ quy tắc 1 .;)
nyuszika7h

1
@ nyuszika7h Thật vậy, nhưng nó sẽ không đặc biệt ngắn.
Martin Ender


Câu trả lời:


15

Pyth, 16 + 15 = 31 byte

Hãy thử nó ở đây .

Quầy tính tiền:

L@,cb)sm!cd)b1 0

Bộ chia:

L@,cb)sm!cd)b10

Mỗi cái này xác định một hàm, ylấy một chuỗi đầu vào để giải quyết tác vụ mong muốn.

Cảm ơn @FryAmTheEggman về ý tưởng sử dụng tính năng lập chỉ mục mô-đun của Pyth vào danh sách để cạo một ký tự.

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

L@,cb)sm!cd)b1 0y++"abc def"b"gh ij k"
L@,cb)sm!cd)b10y++"abc def"b"gh ij k"

Giải trình:

L                  define a function, y, which takes one input, b.
 @                 Index into
  ,                2-tuple of
   cb)             b.split()                          (solution to splitter)
   s               sum over                           (solution to counter)
    m              map, with input d, to
     !cd)          logical negation of d.split()      (empty list is falsy)
     b             over b.
                   Index is either:
   10
   1
                   Indexing is modulo the length of the list in Pyth.
 0                 In one case, a 0 with a leading space is outside the function.
                   Leading space suppresses print, so the 0 is invisible.

52

Python, 54 + 56 = 110 byte

Quầy tính tiền:

m=lambda x:sum(y.isspace()for y in x)
+1
0<9or x.split()

Bộ chia:

m=lambda x:sum(y.isspace()for y in x)+10<9or x.split()

Đối với bộ đếm, chúng tôi sử dụng thực tế là Python vẫn ổn khi chỉ có một biểu thức trên một dòng. Cần phải tách ra +10<9or x.split()ngăn NameErrorkhông cho ném, vì 0<9bị Truengăn không x.split()được đánh giá do chập điện.

Đối với bộ chia, vì số lượng khoảng trắng luôn là không âm, sum(y.isspace()for y in x)+10<9luôn luôn Falsevà hàm chia tách hoạt động.


Thay thế 1, 59 + 60 = 119 byte

Quầy tính tiền:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][min([1])]

Bộ chia:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][m in([1])]

Kết quả của cả đếm và tách được lưu trữ trong một danh sách hai yếu tố. Danh sách được lập chỉ mục bởi một trong hai min([1]), trả về mức tối thiểu của danh sách một thành phần có chứa 1, hoặc m in([1]), trả về False(tương đương 0) như mkhông có trong [1].


Thay thế 2, 67 + 69 = 136 byte

Quầy tính tiền:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not s or ted]

Bộ chia:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not sorted]

Giống như trên, kết quả của cả đếm và tách được lưu trữ trong một danh sách hai yếu tố. sortedlà một hàm dựng sẵn là một giá trị trung thực, do đó not sortedtrả về False(tương đương 0). Vì not s or ted, vì slà một chức năng và cũng là sự thật, not sđược Falseted = 1được trả lại.


Thay thế 3, 59 + 60 = 119 byte

Quầy tính tiền:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a1

Bộ chia:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a
1

Đây là một hàm trong đó kết quả của bộ chia được lưu trữ trong biến avà kết quả của bộ đếm được lưu trữ trong biến đó a1. Giống như trước đây, Python vẫn ổn khi chỉ có một biểu thức trên một dòng, trong trường hợp này 1. Chia tách a1xác định những gì để trở về từ chức năng.


22
Tôi sẽ +1 lần nữa cho not sorted.
Martin Ender

Là dòng mới giữa +10<9or x.split()cần thiết?
isaacg

1
@isaacg Nếu bạn quan tâm đến ngoại lệ, thì có
Sp3000

Bạn có thể tắt 3 byte bằng m=lambda x:sum(y.isspace()for y in x)+00and x.split()m=lambda x:sum(y.isspace()for y in x)+0;0and x.split()(biến dấu chấm phẩy đó thành một dòng mới)
cjfaure

@cjfaure Tôi không nghĩ cái đầu tiên hoạt động như một bộ chia nếu không có khoảng trắng
Sp3000

16

Java 8, 239 + 240 = 479

Đếm khoảng trắng (trả về Integer)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;intx=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Tách trên khoảng trắng (trả về Luồng <Chuỗi>)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;int x=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Giải trình:

Object f(String s){
    String r=new String(new char[]{92,'s'}),e=new String();  // init regex'es

    int intx=0;     // critical variable

    intx=1;         // change intx to 1
              OR
    int x=1;        // new, unused variable

    return intx>0 ? // test variable to decide what to do
      s.chars().filter(c->c==9|c==10|c==32).count() :
      java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);
}

Đối với tôi, điều này có vẻ rực rỡ. +1
Rodolfo Dias

Khá tốt, vì Java phải là ngôn ngữ tồi tệ nhất để chơi gôn.
tbodt

13

Khoảng trắng, 75 + 153 = 228

Dấu cách, tab và dòng mới được thay thế bằng STL, tương ứng và được gấp lại cho mức độ dễ đọc. Chuyển đổi thành một tập tin Whitespace thích hợp với tr -d \\n | sed 'y/STL/ \t\n/'.

Quầy tính tiền

SSSLLSSLSSSTSSSSSLSLSSLSTLTSTTTSLSLTSSLTSSTLTTLSSSTLTSSSLSLLLSSSLS
LLSLLTLST

Bộ chia

SSSTLSSSLTTSLSSTLSSSLSLSTLTSTTTSLSSLSLTSLSSSTSSSSTLTSSTLTTTTLSSSTL
SLSTTSLSLSLLSSTTLSSSTSTSLSSSTLTTTLTSTSLTLSSSSSTLSSSLTTSLSSTSLLSLTL
LSSSLTLSSLSLTLLSSLLLL

2
Tôi đã tự hỏi sẽ mất bao lâu ...;)
Martin Ender

4
Với khoảng trắng, điều này trở thành hai thử thách chơi gôn mã riêng biệt.
tbodt

13

Đáng tin, 103 + 92 = 195

Quầy tính tiền:

@0      @200@1@3
]]&1]]3W
  \\!!?001
        &0  >W@1
>W    @2/\  /\@3+A
00&0      &1
          Dp
@0//

Bộ chia:

@0  @200@1    @3
]]&1]]  3W    \\
  !!    ?001&0
>W@1>W@2
/\  /\@3+A00&0
          &1Dp@0
//

Kiểm tra các chương trình này ở đây. Các bảng hình trụ, bao gồm các thư viện và không gian cho các ô trống đều phải được kiểm tra.

Đầu vào và đầu ra thông qua STDIN / STDOUT.

Giải trình

Quầy tính tiền:

Nguồn truy cập

Đường dẫn màu xanh nhận đầu vào. Nếu ký tự là một ký tự khoảng trắng (giá trị ascii nhỏ hơn 0x21), đường dẫn màu đen được thực hiện, đồng bộ hóa với đường dẫn màu tím.

Đường dẫn màu tím chỉ đơn giản là tăng một viên bi được lưu trữ trong &1bộ đồng bộ hóa mỗi khi đường dẫn màu đen được thực hiện.

Khi không còn đầu vào, đường dẫn màu đỏ được thực hiện, in số lượng ký tự khoảng trắng và thoát.

Bộ chia:

Bộ chia nguồn

Chương trình bắt đầu với đường dẫn màu xanh, vòng lặp cho đến khi tìm thấy một ký tự không phải khoảng trắng.

Khi một ký tự không phải khoảng trắng được lấy ra, đường dẫn màu đen được lấy, nó in ra ký tự này và di chuyển thực thi sang đường dẫn màu xanh lá cây, vòng lặp và in cho đến khi nhận được ký tự khoảng trắng. Thực thi sau đó tiếp tục đến đường dẫn màu tím, có chứa 3Whoặc bộ chia ba chiều.

Nhánh bên trái di chuyển thực thi đến đường dẫn màu xanh (và khoảng trắng được loại bỏ cho đến khi tìm thấy một ký tự không phải khoảng trắng).

Nhánh giữa đặt bản sao của đầu vào thành 0 với ?0(tạo một số ngẫu nhiên giữa 00) và thêm 10 ( 0x0A= dòng mới), sau đó được xuất ra.

Con đường đúng được loại bỏ.


Có vẻ như bộ chia không chấm dứt nếu có khoảng trắng ở cuối.
Martin Ender

12

CJam, 26 + 27 = 53 59 61 73 77 byte

Quầy tính tiền

'!q_,\SN9c++SerS%:Qs,-QN*?

Bộ chia

' !q_,\SN9c++SerS%:Qs,-QN*?

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

Ý tưởng rất đơn giản, tính toán cả số lượng khoảng trắng và chia chuỗi trên các lần chạy liên tiếp của khoảng trắng. Sau đó chọn một trong số chúng dựa trên thực tế sau đây ' !có nghĩa not of space characterlà giả, trong khi đó '!!nhân vật, đó là sự thật.

Mã mở rộng:

'! / ' !                              "Get truthy or falsy value";
        q_                            "Read the input, make a copy";
          ,\                          "Take the length of the copy and swap";
            SN9c++                    "Get a string comprised of all Whitespaces";
                  Ser                 "Replace any occurrence of any character of"
                                      "the above string with space";
                     S%               "Split on one or more runs of space";
                       :Qs,           "Store this in Q, flatten to a string and take length";
                           -          "Subtract from total length to get count";
                            QN*       "Put the splitted array on stack and join newline";
                               ?      "Base on the truthy or falsy value, pick one to print";

Đầu vào là từ STDIN và đầu ra là STDOUT

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


10

Toán học, 44 + 43 = 87 97 byte

Tôi nghĩ tôi sẽ thêm một ngôn ngữ khác vào hỗn hợp.

Quầy tính tiền:

StringCount[#,Whitespace]+0 1StringSpli t@#&

Bộ chia:

String Count[#,Whitespace]+01StringSplit@#&

Điều này sử dụng tính năng của Mathicala rằng phân tách không gian giống như phép nhân. Và việc nhân một cái gì đó với 0 luôn là 0 và thêm 0 vào một cái gì đó luôn luôn là idempotent.

Đối với bộ đếm, trước tiên chúng ta đếm khoảng trắng và chúng ta thêm vào 0*1*StringSpli*t@#. StringSplitkhông được xác định, nhưng Mathicala sử dụng tính toán tượng trưng, ​​do đó, nó chỉ coi chúng là một biến và hàm không xác định. Là 1*idempotent (giống như 0+), 0*biến nó thành số không. Cần phải phân tách StringSplitthành hai biến, bởi vì 0lần một danh sách được coi là phép nhân vectơ vô hướng dẫn đến một vectơ (danh sách) các số 0.

Đối với bộ chia, tôi đang sử dụng thực tế Countcũng tồn tại nhưng không nhìn vào chuỗi. Nó cố gắng đếm tất cả các biểu thức phụ phù hợp với mẫu, nhưng Whitespacelà một mẫu chỉ áp dụng cho nội dung chuỗi. Vì vậy, Countsẽ luôn luôn trở lại 0, mà làm cho Stringbiến mất. Phép nhân của mảng phân tách 01 = 1lại là idempotent.


10

Ruby, 107 91 byte

Bộ chia (46 byte)

p
p=gets(p).split
puts p||$_.size-pp.join.size

Bộ đếm (45 byte)

pp=gets(p).split
puts p||$_.size-pp.join.size

plà một phương thức được xác định trước mà không có đối số, chỉ trả về nil. Chúng tôi sử dụng điều này theo nhiều cách. Trong bộ chia, ban đầu pkhông làm gì cả. gets(p)đọc mọi thứ từ đầu vào tiêu chuẩn, vì dấu phân cách là null. Chúng tôi gọi phương thức phân tách tích hợp sẵn trên đó và gán kết quả chop , vì vậy bây giờ khi không đưa ra các đối số, nó sẽ được phân tích cú pháp như một biến. puts p||...ngắn mạch và in từng phần tử của pbiến thành dòng riêng của nó.

Trong bộ đếm, chúng tôi xóa dòng mới đầu tiên để ppthay vào đó là mảng phân chia . Vì chúng tôi chưa được chỉ định p, nên đây vẫn là phương thức hoàn trả nên phần thứ hai ||được đánh giá và chuyển qua puts. $_là một biến ma thuật chứa kết quả của gets, vì vậy tổng số khoảng trắng là kích thước của nó trừ đi các ký tự không phải khoảng trắng, là những gì ppchứa. Tôi cảm thấy nên có một cách ngắn hơn để thực hiện việc đếm, nhưng tôi không thể tìm thấy một cách nào, và bằng mọi giá sử dụng mảng phân chia trong quầy rất thú vị.


7

Con trăn, 169

Thật dễ dàng để làm điều này trong Python!

Quầy tính tiền:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
  return s.split()
 return y(s)

Bộ chia:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
 return s.split()
 return y(s)

Chúng chỉ khác nhau ở một không gian và tôi không thực hiện bất kỳ mánh khóe nào như tách một số hoặc một tên biến thành một nửa :)


6

C, 138 + 136 = 274

Trong mỗi trường hợp, mã là một chương trình chấp nhận chính xác một đối số dòng lệnh và in kết quả ra thiết bị xuất chuẩn. \tnên được thay thế bằng một ký tự tab. Nếu bạn muốn vượt qua một đối số có chứa các tab và dòng mới, công việc của bạn là tìm ra cách thức;).

Đếm

#define strtok strpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=- -c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

Tách

#define strtokstrpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=--c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

6

JavaScript, 95 + 96 = 191 byte

Quầy tính tiền:

c=(a,v)=>{v
v=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>j)}

Bộ chia:

s=(a,v)=>{vv=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>!!j)}

Ung dung:

s=(a,v)=>{

    v  // this `v` is ignored, or combined with the next line to make `vv`

    // split array and store it in `a` and `v` (or alternatively `vv`)
    v = a = a.split(RegExp(String.fromCharCode(92,115)));

    return v?
            a.length-1        // return number of whitespace chars
            :
            a.filter(j=>j)    // return array without empty strings
    }

Các RegExp(String.fromCharCode(92,115)dòng tạo ra regex khoảng trắng phù hợp /\s/mà không regex hoặc chuỗi literals.

Trong mỗi chương trình, chúng tôi sử dụng biến vhoặc vv. Chúng tôi lưu trữ mảng phân tách vào biến đó ( vhoặc vv), và sau đó phân nhánh hành vi của chúng tôi theo giá trị của v(trong khi đó, vvbị bỏ qua). Trong quầy, vcó một giá trị trung thực; trong bộ chia nó có giá trị giả (vì vvcó giá trị thay thế).


Thay thế: JavaScript, 250 byte

Tôi có một giải pháp khác không giành được bất kỳ giải thưởng nào cho sự ngắn gọn, nhưng tôi nghĩ rằng đó là một thách thức thú vị để lạm dụng hành vi chèn dấu chấm phẩy tự động của JavaScript.

Quầy tính tiền:

c=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break x}return o}

Bộ chia:

s=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break
x}return o}

Quầy phản đối:

s=a=>{
    a = a.split(
            RegExp(String.fromCharCode(92,115))   // split input on whitespace regex /\s/
        );  
    x:                             // x is a label for the outer loop
    for(i=2;i--;)                  // run this outer loop twice
        for(o=i?                   // if this is the first outer loop pass, 
               a.length-1          //    set `o` to number of whitespaces
               :                   // else, on second outer loop pass,
               a.filter(j=>j);     //    set `o` to split input (w/o empty strings)
            1;                     // 1 is truthy; run inner loop forever
            ) {
                break x;           // break out of outer loop
            }
    return o;                      // return `o`
}

Bộ chia hoàn toàn giống nhau, ngoại trừ dòng:

break x;

Hiện tại là

break
x;

Chèn dấu chấm phẩy tự động JavaScript của thường không chấm dứt lệnh đa dòng đầu nếu họ có thể được hiểu mà không có một ngắt dòng, nhưng nó không chịu đựng được ngắt dòng sau return, continuehoặc break. Do đó, dòng được đọc đơn giản là break, chỉ thoát ra khỏi vòng lặp bên trong, thay vì thoát ra khỏi vòng lặp bên ngoài. Hành vi "vượt qua thứ hai" o = a.filter(j=>j)sau đó được thực hiện (so với bị bỏ qua trong bộ đếm), bởi vì vòng lặp bên ngoài được cung cấp một lần thứ hai.


!!xkhác nhau để tự động Boolchuyển đổi?
l4m2

@ l4m2 Không phải vậy! Tôi đã loại bỏ nó, vì filterauto-bool trả lại cuộc gọi lại theo cùng quy tắc như !!. Cảm ơn!
apsillers

5

Python, 228 198 182 166 146 145 byte

Bộ đếm ( 72 byte ):

ior1=0
w=lambda i:i.split()if ior1 else sum(ord(c)in(9,10,32)for c in i)

Bộ chia ( 73 byte ):

ior1=0
w=lambda i:i.split()if i or 1else sum(ord(c)in(9,10,32)for c in i)

ior1là một biến falsey, nhưng i or 1là sự thật. Đó là mẹo chính.


Điều này không bị phá vỡ nếu ilà chuỗi trống cho bộ chia? Có thể được sửa bằng cách thay đổi iorbthành ior1, điều này cũng cho phép bạn lưu ký tự giữa 1else.
isaacg

@isaacg Tôi hoàn toàn quên rằng bạn có thể có số trong tên biến! Cảm ơn bạn <3
ngầmmonorail

5

Befunge 98, 61 + 59 = 120

Quầy tính tiền:

~:'!-0`#v_ >$1+#@ #. #
 @#,#$ #<_v#`0-!':~ # .#
  ,#$ #+55<v

Bộ chia:

~:'!-0`#v_ >$1+#@ #.#
 @#, #$#<_v#`0-!':~ #.#
  , #$#+55<v

4

Bash, 75 + 79 = 154 byte

Điều này phụ thuộc vào bash có thể tiếp tục thực thi ngay cả khi một số dòng hoặc một phần của một dòng script bị sai (trong một số trường hợp). Khoảng trắng được sử dụng để hủy kích hoạt thoát cho một số dấu ngoặc gần và để phá vỡ một đường ống bằng cách đặt nó trên một dòng mới.

Bộ chia:

echo $((`echo $1|wc -w`+${#1}-$(\)\)\)
for a in $1;do echo $a;done|wc -c)))

Quầy tính tiền:

echo $((`echo $1|wc -w`+${#1}-$(\ )\ )\ )
for a in $1;do echo $a;done
|wc -c)))

Đầu vào là thông qua đối số dòng lệnh, đầu ra là thông qua thiết bị xuất chuẩn.

Bởi vì điều này phụ thuộc vào hành vi lỗi bash, người dùng sẽ bỏ qua thiết bị lỗi chuẩn.

Chạy ví dụ (hiển thị đầu vào với một dòng mới và nhiều khoảng trắng liền kề):

# bash counter.sh "abc def
gh   ij k" 2>/dev/null
6
# bash splitter.sh "abc def
gh   ij k" 2>/dev/null
abc
def
gh
ij
k

4

Ruby, 114 + 116 107 + 109 = 216 byte

Điều này không thể cạnh tranh với giải pháp ruby ​​của histocrat, nhưng tôi nghĩ dù sao nó cũng đáng để đưa lên.

Tôi đã sử dụng $zcho nilnil.to_schoString.new

Ký tự khoảng trắng bổ sung mà tôi thêm vào cuối đầu vào là buộc từ cuối cùng được thêm vào mảng ( r) - một từ chỉ được thêm vào cuối mảng khi ký tự khoảng trắng theo ký tự không phải khoảng trắng. Sự thay thế là thêm một cái khác r<<w if wsau each_bytekhối.

Đếm

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$zorr ?r:n}

Tách

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$z or r ?r:n}

Ah, tôi không chắc về phán quyết về điều đó. Tôi đã thay đổi nó để sử dụng if-other thay vì toán tử ternary - không còn chuỗi ký tự.
alexanderbird

3

Haskell , 53 + 55 = 108 36 + 38 = 74 byte

Quầy tính tiền

f=do
 pure(length.filter(<'!'))words

Bộ chia

f=do
 pure(length.filter(<'!'))
 words

Giải pháp này sử dụng thực tế là trong các hàm Haskell là một thể hiện của lớp loại Monad và do đó có thể được sử dụng như các hành động đơn âm trong ký hiệu.

Trong trường hợp đầu tiên, hàm kết quả của khối do là đối số đầu tiên của pure(về cơ bản là constcho loại hàm), làm cho bộ đếm kết quả cuối cùng và bộ tách bị loại bỏ.

Trong trường hợp thứ hai purechỉ được áp dụng cho một đối số duy nhất, làm cho nó trở thành một hàm trả về một hàm khác (bộ đếm). Tuy nhiên, kết quả không bao giờ được sử dụng và do đó bị loại bỏ. Kết quả cuối cùng là dòng thứ hai của khối do, bộ chia.


Cách tiếp cận tốt đẹp! [' ','\t','\n']có thể rút ngắn thành " \t\n".
Laikoni

@Laikoni Mô tả chỉ cho phép ký tự bằng chữ, không có chuỗi ký tự hoặc biểu thức chính quy
siracusa

2
Vì thử thách không yêu cầu bạn xử lý hầu hết các ký tự điều khiển, bạn có thể rút ngắn điều này bằng cách sử dụng (<'!')để kiểm tra khoảng trắng.
Ørjan Johansen

2

Java 8, 187 + 188 = 375

Trước hết, tôi muốn nói rằng câu trả lời này chủ yếu dựa trên @ Ypnypn. Về cơ bản, tôi đã thay thế một số phần bằng các phần ngắn hơn (bao gồm cả phần phụ thuộc vào khoảng trắng, IMO là phần quan trọng nhất trong thử thách này), nhưng mã chức năng hầu hết giống nhau.

Đếm khoảng trắng , 187 (trả về int):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a--+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

Tách trên khoảng trắng , 188 (trả về Stream<String>):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a- -+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

2

J, 48 + 49 = 97 char

Hai hàm lấy và trả về một đối số duy nhất. Đã sử dụng cách điên rồ nhất mà tôi có thể nghĩ ra để đánh bại quy tắc tương tự nhưng khoảng trắng, vì vậy có thể có các nhân vật được lưu bằng cách tìm ra một tuyến đường thông minh hơn xung quanh đó.

(aa[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))      NB. count
(a a[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))     NB. split

Chúng tôi định nghĩa động từ acó hai hành động khác nhau, tùy thuộc vào việc nó được sử dụng với một đối số hay với hai đối số. Với một đối số, đó là (e.u:)&9 10 32, kiểm tra xem mỗi ký tự có khoảng trắng hay không. Với hai đối số, đó là a:-.~(<;._1~1,}.), lấy một vectơ boolean ở bên phải và cắt đối số bên trái tại các vị trí đó, loại bỏ bất kỳ vết cắt trống nào với a:-.~.

Sau đó, chúng tôi xác định aalà số lượng giá trị True trong kết quả a, chỉ có ý nghĩa với một đối số. Cuối cùng, chúng tôi sử dụng aahoặc a atùy thuộc vào việc chúng tôi muốn đếm hoặc phân chia khoảng trắng của chuỗi.aahoạt động như mong đợi.

Lý do a ahoạt động là bởi vì khi J nhìn thấy (f g)y, nó xem xét (f g)một cái móc và đánh giá nó như thế nào y f (g y). Trong trường hợp này, flà dyadic aở trên thực hiện việc cắt, và ga[aa, tính toán tổng từ aa, ném nó ra và tính toán lại (đơn âm) a.

Tại REPL:

   (aa[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))   '  123',TAB,'-_-   abc',LF,'def'
7
   (a a[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))  '  123',TAB,'-_-   abc',LF,'def'
+---+---+---+---+
|123|-_-|abc|def|
+---+---+---+---+

2

Bash, 54 + 50 = 104 byte

Quầy tính tiền

a=$IFS
IFS=
cat()(tr -cd $a|wc -c)
printf %s \\n$1|cat

Bộ chia

a=$IFSIFS=ca
t()(tr-cd$a|wc-c)
printf %s\\n $1|cat

1

Perl, 37 + 38 = 75

Số lượt truy cập :

sub f{($_)=@_;(y/   - //,[split])[0.1]}

Bộ chia :

sub f{($_)=@_;(y/   - //,[split])[0 .1]}

1

Perl 6, 31 + 32 = 63 byte

Quầy tính tiền

{?^1??.words!!+grep 33>*,.ords}

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

?^1được phân tích cú pháp như ?^ 1áp dụng toán tử phủ định Boolean cho 1, dẫn đến False.

Bộ chia

{? ^1??.words!!+grep 33>*,.ords}

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

? ^1chuyển đổi phạm vi 0..0 thành Bool, dẫn đến True.


0

Con trăn 2, 98

Tách (49)

Trả về các mã thông báo trong danh sách.

f=lambda s:[sum(map(str.isspace,s))]and s.split()

Đếm (49)

Trả về một danh sách độ dài chứa một số ký tự khoảng trắng. Nó rất có thể sẽ gây ra lỗi thời gian chạy, nhưng chức năng fcó thể được sử dụng sau khi thực thi mã.

f=lambda s:[sum(map(str.isspace,s))]
ands.split()

0

C (gcc) , 88 + 89 = 177 byte

Bộ chia

i,n,x,c;f(char*s){x=n=i=0;for(x+++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Bộ chia

Quầy tính tiền

i,n,x,c;f(char*s){x=n=i=0;for(x+ ++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Quầy tính tiền

Chạy xuống

Đưa đầu vào như một đối số chức năng. Hàm đếm trả về số lượng khoảng trắng. Hàm chia tách sử dụng STDOUT cho đầu ra của nó (nhưng cũng trả về số lượng khoảng trắng trừ đi một khoảng trống).

i,                      Flag signalling whether we are inside a word.
n,                      Number of whitespace encountered.
x,                      Flag signalling whether or not we should output the words.
c;                      Current character.
f(char*s){              Take input string as an argument.
x=n=i=0;for(            Initialise everything and start loop.
x+++n;                  SPLITTER ONLY: Interpreted as x++ +n, meaning x is set to 1 and n stays 0.
x+ ++n;                 COUNTER ONLY: Inverse of the above. Sets n to 1, and x stays 0.
c=*s++;                 Sets c to current char and increment string pointer, end loop if end of string.
c*x&&putchar(c))        Only output c if x is 1 and c is non-zero, which only happens if we left a word.
i=c<33?                 Since input contains only printable ASCII or whitespace, anything below 33 is whitespace.
       n++,             ...if that is the case, increment the whitespace counter (n)
           c=i*10,      ...and set c to newline (10), but only if we just left a word (if i is 1)
                  0:    ...and set i to 0.
                    1;  If not a whitespace, set i to 1, signalling we are inside a word.
x=n-1;}                 Implicitly returns n-1, which is the number of whitespaces if we are in the counter function.

0

Zsh , 35 + 35 = 70 byte

  • Không chương trình / hàm nào có thể chứa bất kỳ chuỗi hoặc regex nào

Tôi không chắc chắn liệu có [^$IFS]đủ điều kiện hay không , vì nó được sử dụng trong khớp mẫu. Đây là một giải pháp 45 + 45 trong trường hợp nó bị cấm.


Tách:

:<<<${#1//[^$IFS]} 
:
<<<${(F)${=1}}

Đếm:

:
<<<${#1//[^$IFS]}
:<<<${(F)${=1}}

Nội dung :tương đương vớitrue , chúng tôi sử dụng nó như một cái gì đó giữa một bình luận và / dev / null (vì các bình luận không được phép) bằng cách chuyển sự mở rộng không mong muốn sang nó.

Zsh có tích hợp để phân tách trên khoảng trắng, đó là ${=var}. Điều này khiến cho khó có thể thực hiện bất kỳ loại kết hợp logic nào ngoài việc chỉ thực hiện cả hai và loại bỏ cái mà chúng ta không muốn.

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

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.