Ninjas và khỉ và gấu, Oh My!


37

Thử thách này là giải thưởng của NinjaBearMonkey khi giành được Bầy Bot xây dựng khối của tôi ! thách thức với đệ trình Black Knight . Xin chúc mừng NinjaBearMonkey!

Thách thức ở đây khá đơn giản, nhưng có nhiều cách tiếp cận khả thi. Câu chuyện kể rằng trong thế giới của Isometric Illusions , có 6 loại sinh vật khác nhau:

  1. Ninjas, viết tắt N
  2. Gấu, viết tắt B
  3. Khỉ, viết tắt M
  4. NinjaBears, viết tắt NB
  5. BearMonkeys, viết tắt BM
  6. NinjaBearMonkeys, viết tắt NBM

( Tất nhiên, NinjaBearMonkey là loại cuối cùng, mạnh nhất.)

Nhiệm vụ của bạn là điều tra dân số về những sinh vật này khi chúng được xếp cạnh nhau, tức là khi các chuỗi viết tắt của chúng được nối với nhau. Thông báo trước là bạn cần đảm bảo không đếm quá nhiều bộ phận của một số sinh vật như những sinh vật riêng biệt có vẻ giống nhau. Các sinh vật sẽ xếp hàng sao cho:

  • Bất kỳ trường hợp nào NBMlà 1 NinjaBearMonkey và 0 sinh vật khác.
  • Bất kỳ trường hợp nào NBkhông được theo sau Mlà 1 NinjaBear và 0 sinh vật khác.
  • Bất kỳ trường hợp nào BMkhông có trước Nlà 1 BearMonkey và 0 sinh vật khác.
  • Mặt khác, các thể hiện của N, BMlà các Ninja, Gấu và Khỉ tương ứng.

Dòng này được đọc từ trái sang phải.

Vì vậy, ví dụ, trong dòng sinh vật NBMMBNBNBM, có 0 Ninjas, 1 Bear, 1 Monkey, 1 NinjaBear, 0 BearMonkeys và 2 NinjaBearMonkeys.

Thử thách

Viết chương trình hoặc chức năng nhận một chuỗi các ký tự N, BM, và in hoặc trả về số lượng của mỗi loại trong số 6 loại sinh vật có trong đó.

Đầu ra phải có dạng

#N #B #M #NB #BM #NBM

với số lượng sinh vật tương ứng thay thế mỗi #dấu hiệu. Tất cả 6 số phải được hiển thị, cách nhau bởi khoảng trắng, ngay cả khi chúng bằng 0. Tuy nhiên, chúng có thể theo bất kỳ thứ tự nào (ví dụ: #NBMcó thể đến trước).

Cũng thế:

  • Chuỗi đầu vào sẽ chỉ chứa các ký tự N, BM.
  • Nếu chuỗi trống là đầu vào, thì tất cả các số là 0.
  • Đầu ra có thể tùy ý chứa một không gian hàng đầu và / hoặc dấu, và / hoặc một dòng mới duy nhất.

Đệ trình ngắn nhất tính bằng byte thắng.

Ví dụ

Đầu vào: NB
Đầu ra:0N 0B 0M 1NB 0BM 0NBM

Đầu vào: NBM
Đầu ra:0N 0B 0M 0NB 0BM 1NBM

Đầu vào: NBMMBNBNBM(ví dụ từ phía trên)
Đầu ra:0N 1B 1M 1NB 0BM 2NBM

Đầu vào: MBNNBBMNBM
Đầu ra:1N 1B 1M 1NB 1BM 1NBM

Đầu vào: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Đầu ra:17N 6B 14M 5NB 8BM 3NBM


53
Tôi chấp nhận thử thách này.
NinjaBearMonkey

Chỉ cần xác nhận: nếu tất cả những gì bạn có là 2 NinjaBearMonkeys, bạn không thể tạo thành một dòng? Vì họ không thể đứng cạnh nhau?
Alan Campbell

3
@AlanCampbell Số NBMNBMsẽ là đầu vào hoàn toàn hợp lệ. Đọc nó từ trái sang phải rõ ràng có 2 NinjaBearMonkeys.
Sở thích của Calvin

Câu trả lời:


20

Bình thường, 22 byte

 f|pd+/zTT=:zTd_.:"NBM

Cách khá hay để tiết kiệm 1 byte, nhờ @Jakube.


Bình thường, 23 byte

FN_.:"NBM")pd+/zNN=:zNd

Trình diễn.

In theo thứ tự ngược lại, với một không gian dấu và không có dòng mới.

.:"NBM")là tất cả các chuỗi con, _đặt chúng theo đúng thứ tự, /zNđếm số lần xuất hiện và =:zNdthay thế tại chỗ mỗi lần xuất hiện của chuỗi trong câu hỏi với một khoảng trắng.

FN_.:"NBM")pd+/zNN=:zNd
FN                         for N in                            :
  _                                 reversed(                 )
   .:     )                                  substrings(     )
     "NBM"                                              "NBM"
           pd              print, with a space at the end,
              /zN          z.count(N)
             +   N                    + N
                  =:zNd    replace N by ' ' in z.

23

JavaScript ES6, 86 byte

f=s=>'NBM BM NB M B N'.replace(/\S+/g,e=>(i=0,s=s.replace(RegExp(e,'g'),_=>++i))&&i+e)

(Tôi chỉ phải trả lời điều này.) Nó đi qua từng chuỗi con của NBM, bắt đầu với những chuỗi dài hơn, được ưu tiên cao hơn. Nó tìm kiếm cho mỗi lần xuất hiện của chuỗi cụ thể đó và loại bỏ nó (trong trường hợp này thay thế nó bằng số hiện tại để nó không được khớp lại). Cuối cùng, nó thay thế từng chuỗi con bằng số đếm + chuỗi.

Đoạn mã Stack này được viết bằng ES5 tương đương với đoạn mã trên để dễ kiểm tra hơn từ bất kỳ trình duyệt nào. Nó cũng là mã hơi vô căn cứ. Giao diện người dùng cập nhật với mọi tổ hợp phím.

f=function(s){
  return'NBM BM NB M B N'.replace(/\S+/g,function(e){
    i=0
    s=s.replace(RegExp(e,'g'),function(){
      return++i
    })
    return i+e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('input').onkeyup=run;run()
<input type="text" id="input" value="NBMMBNBNBM" /><br /><samp id="output"></samp>


Bạn có thể thay đổi phần regex thành 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', trong đó <newline>s là dòng mới theo nghĩa đen và 's là backticks, tạo thành chuỗi mẫu ES6 không? Lưu hai byte trong regex ( .không khớp với dòng mới).
wchargein

@WChargin Thật không may, không, vì đầu ra phải được phân tách bằng dấu cách.
NinjaBearMonkey

17

Con trăn 2, 78

n=input()
for x in"NBM BM NB M B N".split():n=`n`.split(x);print`len(n)-1`+x,

Một biến thể của câu trả lời của Vioz-'s . Thú vị với biểu diễn chuỗi Python 2!

Đếm số lần xuất hiện của chuỗi con một cách gián tiếp bằng cách tách trên nó, đếm các phần và trừ đi 1. Thay vì thay thế các chuỗi con bằng ký hiệu phụ, thay thế chuỗi bằng danh sách đã splittạo. Sau đó, khi chúng ta lấy biểu diễn chuỗi của nó, các phần được phân tách bằng dấu cách và dấu phẩy.


5
Thật điên rồ! Tuyệt vời điên rồ, nhưng vẫn điên rồ.
Sp3000

Công việc tốt đẹp! Đừng nghĩ về điều đó :)
Kade

14

Ruby, 166 80 72 68 ký tự

f=->s{%w(NBM BM NB M B N).map{|t|c=0;s.gsub!(t){c+=1};c.to_s+t}*' '}

Giải trình:

  • Việc đếm được thực hiện ngược lại. Điều này là do các ninja dài hơn và gấu và khỉ được ưu tiên hơn các ninja ngắn hơn.

  • Đối với NBM, BMNB, các chuỗi nằm gsub!ngoài chuỗi gốc có một khối để đếm xem có bao nhiêu chuỗi này tồn tại (vâng, hàm sửa đổi đối số của nó).

    • Tuy nhiên, họ không thể được thay thế bằng gì cả, vì nếu không thì BNBMMsẽ được tính là NBMBMthay vì B, NBMM(vì khi NBMsẽ được gỡ bỏ, nó sẽ đặt công BMcùng nhau và sẽ không có một cách để phân biệt nó). Ban đầu tôi đã trả về một chuỗi ký tự đơn ( .gsub!('NBM'){c+=1;?|}), nhưng tôi nhận ra rằng tôi chỉ có thể trả về kết quả của +=(đó là một số, vì vậy nó không thể là bất kỳ N B M).
  • Đối với M, BN, tôi có thể chỉ có countbao nhiêu trong số chúng có trong chuỗi (không cần phải loại bỏ chúng qua gsub!). Bây giờ, đó là một vòng lặp (không biết tại sao tôi không nghĩ về điều đó ngay từ đầu), vì vậy những điều này được thực hiện theo cách tương tự.


Giải pháp tương tự trong Đà điểu , 54 51 ký tự :

:s;`NBM BM NB M B N`" /{:t0:n;s\{;n):n}X:s;nt+}%" *

Thật không may, không phải là một giải pháp hợp lệ, vì có một lỗi trong phiên bản Ostrich hiện tại (hiện đã được sửa, nhưng sau khi thử thách này được đăng).


Bạn có thể lưu 3 ký tự bằng cách sử dụng ký hiệu mảng %w(NBM BM NB M B N)và loại bỏ phân tách.
DickieBoy

@DickieBoy Đó thực sự là 4 ký tự; cảm ơn!
Doorknob

À đúng rồi, dấu chấm!
DickieBoy

14

Java, 166 162

void f(String a){String[]q="NBM-NB-BM-N-B-M".split("-");for(int i=0,c;i<6;System.out.print(c+q[i++]+" "))for(c=0;a.contains(q[i]);c++)a=a.replaceFirst(q[i],".");}

Và với một vài ngắt dòng:

void f(String a){
    String[]q="NBM-NB-BM-N-B-M".split("-");
    for(int i=0,c;i<6;System.out.print(c+q[i++]+" "))
        for(c=0;a.contains(q[i]);c++)
            a=a.replaceFirst(q[i],".");
}

Nó hoạt động khá đơn giản. Chỉ cần lặp qua các mã thông báo, thay thế chúng bằng các dấu chấm và đếm miễn là đầu vào có chứa một số. Đếm những người lớn trước, vì vậy những người nhỏ không làm hỏng nó.

Ban đầu tôi đã thử thay thế tất cả cùng một lúc và đếm sự khác biệt về chiều dài, nhưng phải mất thêm một vài ký tự theo cách đó :(


2
Là một nhà phát triển Java, tôi muốn làm điều này ngắn hơn và xem Java giành chiến thắng để thay đổi. Sau khi nhìn chằm chằm vào nó một lúc tôi vẫn chưa tìm được cách làm cho nó ngắn hơn.
DeadChex

1
Vâng, nó chắc chắn sẽ không giành chiến thắng tổng thể. Nhà lãnh đạo hiện tại là 22 byte và không có cách nào để làm bất cứ điều gì có ý nghĩa trong Java ở kích thước đó. printlnChỉ riêng tuyên bố của tôi là lớn hơn thế. Mặc dù vậy, tôi hài lòng với nó: D
Geobits

1
Tôi đến hơi muộn nhưng tôi đã tìm được cách ... đổi String q[]=thànhString[]q=
DeadChex

1
Tốt đẹp! Không thể tin rằng tôi đã bỏ lỡ điều đó, nó nằm trong danh sách những thứ cần xem xét của tôi :)
Geobits

Tôi chỉ phát hiện ra nó sau khi cố gắng vào Code Golf với tư cách là một JavaDev, tôi khá ngạc nhiên về một số thứ bạn có thể làm
DeadChex

11

CJam, 36 32 31 byte

l[ZYX]"NBM"few:+{A/_,(A+S@`}fA;

Cảm ơn @Optimizer vì đã chơi golf 1 byte.

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

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

l                                e# Read a line L from STDIN.
 [ZYX]"NBM"                      e# Push [3 2 1] and "NBM".
           few                   e# Chop "NBM" into slices of length 3 to 1.
              :+                 e# Concatenate the resulting arrays of slices.
                {          }fA   e# For each slice A:
                 A/              e#   Split L at occurrences of A.
                   _,(           e#   Push the numbers of resulting chunks minus 1.
                      A+         e#   Append A.
                        S        e#   Push a space.
                         @`      e#   Push a string representation of the split L.
                              ;  e# Discard L.

N*-> `nên là đủ.
Tối ưu hóa

@Optizes: Điều đó hoạt động tốt. Cảm ơn.
Dennis

7

R, 153 134 118

Điều này đã thực sự lâu hơn rất nhanh, nhưng hy vọng tôi sẽ có thể cạo một ít. Đầu vào là STDIN và đầu ra thành STDOUT.

Chỉnh sửa Thay đổi của chiến thuật. Đã thoát khỏi chuỗi phân chia và đếm các bộ phận. Bây giờ tôi thay thế các phần bằng một chuỗi ngắn hơn một phần. Sự khác biệt giữa độ dài chuỗi được thu thập cho đầu ra.

N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')

Giải trình

N=nchar;
i=scan(,'');                     # Get input from STDIN
for(s in scan(,'',t='NBM BM NB M B N'))  # Loop through patterns
  cat(                           # output
    paste0(                      # Paste together
      N(i) -                     # length of i minus
      N(i<-gsub(                 # length of i with substitution of
        s,                       # s
        strtrim('  ',N(s)-1)     # with a space string 1 shorter than s
        ,i)                      # in i
      ),
      s)                         # split string
  ,'')

Chạy thử nghiệm

> N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')
1: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
2: 
Read 1 item
Read 6 items
3NBM 8BM 5NB 14M 6B 17N 
> N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')
1: NBMMBNBNBM
2: 
Read 1 item
Read 6 items
2NBM 0BM 1NB 1M 1B 0N 
> 

7

Bình thường, 19 byte

jd+Ltl=zc`zd_.:"NBM

Đây là hỗn hợp của giải pháp Pyth của @ isaacg và thủ thuật Python đáng kinh ngạc của @ xnor.

Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Giải trình

jd+Ltl=zc`zd_.:"NBM   implicit: z = input string
             .:"NBM   generate all substrings of "NBM"
            _         invert the order
  +L                  add left to each d in ^ the following:
         `z             convert z to a string
        c  d            split at d
      =z                assign the resulting list to z
    tl                  length - 1
jd                    join by spaces and implicit print

6

Julia, 106 97 byte

b->for s=split("NBM BM NB M B N") print(length(matchall(Regex(s),b)),s," ");b=replace(b,s,".")end

Điều này tạo ra một hàm không tên, lấy một chuỗi làm đầu vào và in kết quả ra STDOUT với một khoảng trắng ở cuối và không có dòng mới. Để gọi nó, đặt tên cho nó, vd f=b->....

Ungolfed + giải thích:

function f(b)
    # Loop over the creatures, biggest first
    for s = split("NBM BM NB M B N")

        # Get the number of creatures as the count of regex matches
        n = length(matchall(Regex(s), b))

        # Print the number, creature, and a space
        print(n, s, " ")

        # Remove the creature from captivity, replacing with .
        b = replace(b, s, ".")
    end
end

Ví dụ:

julia> f("NBMMBNBNBM")
2NBM 0BM 1NB 1M 1B 0N 

julia> f("NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM")
3NBM 8BM 5NB 14M 6B 17N 

4

Python 2, 93 88 89 84 byte

Lấy cách tiếp cận đơn giản.

def f(n):
 for x in"NBM BM NB M B N".split():print`n.count(x)`+x,;n=n.replace(x,"+")

Gọi như vậy:

f("NBMMBNBNBM")

Đầu ra là như vậy:

2NBM 0BM 1NB 1M 1B 0N

Bạn có thể loại bỏ không gian sau in.
isaacg

Trong Python 2, bạn có thể chuyển đổi thành biểu diễn chuỗi với `x`.
xnor

4

SÀI GÒN, 144 142 139 129

data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;

Cách sử dụng (thêm 7 byte cho sysparm):

$ sas -stdio -sysparm NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM << _S
data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;
_S

hoặc là

%macro f(i);i="&i";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1‌​,i);put a+(-1)z@;end;%mend;

Sử dụng:

data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)

Kết quả:

3NBM 5NB 8BM 17N 6B 14M

Bạn có thể lưu một vài byte bằng cách sử dụng cats('s/',z,'/x/')thay thế 's/'||strip(z)||'/x/'.
Alex A.

1
Thật tuyệt, đó là chuyến đi trở lại 139 :)
Fried Egg

1
126 byte:macro a i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%
Alex A.

1
122 : data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;. Vì bạn đã đọc từ đó sysparm, bạn cũng có thể chạy nó như một bước dữ liệu. Và nếu bạn đang chạy theo đợt, bạn không cần run;.
Alex A.

1
Nhưng bạn có thể nhận được 129 bằng cách sử dụng macro kiểu hiện đại không đọc từ đối số dòng lệnh:%macro a(i);i="&i";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%mend;
Alex A.

3

PHP4.1, 92 byte

Không phải là ngắn nhất, nhưng bạn sẽ mong đợi gì nữa từ PHP?

Để sử dụng nó, hãy đặt một khóa trên COOKIE, POST, GET, SESSION ...

<?foreach(split(o,NBMoNBoBMoMoBoN)as$a){echo count($T=split($a,$S))-1,"$a ";$S=join('',$T);}

Các apporach là cơ bản:

  • Tách chuỗi thành tên của các sinh vật
  • Đếm xem có bao nhiêu yếu tố
  • Trừ 1 (một chuỗi rỗng sẽ cho một mảng có 1 phần tử)
  • Xuất số lượng và tên sinh vật
  • Nối tất cả lại với nhau, sử dụng một chuỗi rỗng (sẽ giảm chuỗi và loại bỏ sinh vật cuối cùng)

Dễ chứ nhỉ?


2

JavaScript, 108 116 byte

Chỉ là một cách tiếp cận thẳng, không có gì lạ mắt

o="";r=/NBM|NB|BM|[NMB]/g;g={};for(k in d=(r+prompt()).match(r))g[d[k]]=~-g[d[k]];for(k in g)o+=~g[k]+k+" ";alert(o);

1
Không hoạt động : All 6 counts must be shown, separated by spaces, even when they are 0.. Trường hợp thử nghiệm:N
edc65

@ edc65 Woah. Tôi chỉ bỏ lỡ phần đó. Cảm ơn đã chỉ ra rằng. Đã sửa nó với chi phí 8chars
C5H8NNaO4

2

Perl, 46

#!perl -p
$_="NBM BM NB M B N"=~s/\w+/~~s!$&!x!g.$&/ger

Giải thích về cách thức này hoạt động?
Cain

1

SpecBAS - 164

1 INPUT s$
2 FOR EACH a$ IN ["NBM","BM","NB","M","B","N"]
3 LET n=0
4 IF POS(a$,s$)>0 THEN INC n: LET s$=REPLACE$(s$,a$,"-"): GO TO 4: END IF
5 PRINT n;a$;" ";
6 NEXT a$

Sử dụng phương pháp tương tự như rất nhiều người khác. Dòng 4 tiếp tục lặp qua chuỗi (từ lớn nhất trước), thay thế nó nếu tìm thấy.

SpecBAS có một số điểm thú vị so với ZX / Sinclair BASIC ban đầu (lặp qua các danh sách, tìm các ký tự) mà tôi vẫn đang tìm hiểu.


1

C, 205 186 184 byte

Một cách tiếp cận khác nhau dựa trên máy trạng thái. nơi tlà nhà nước.

a[7],t,i;c(char*s){do{i=0;t=*s==78?i=t,1:*s-66?*s-77?t:t-4?t-2?i=t,3:5:6:t-1?i=t,2:4;i=*s?i:t;a[i]++;}while(*s++);printf("%dN %dB %dM %dNB %dBM %dNBM",a[1],a[2],a[3],a[4],a[5],a[6]);}

Mở rộng

int a[7],t,i;

void c(char *s)
{
    do {
        i = 0;
        if (*s == 'N') {
            i=t; t=1;
        }
        if (*s == 'B') {
            if (t==1) {
                t=4;
            } else {
                i=t;
                t=2;
            }
        }
        if (*s == 'M') {
            if (t==4) {
                t=6;
            } else if (t==2) {
                t=5;
            } else {
                i=t;
                t=3;
            }
        }
        if (!*s)
            i = t;
        a[i]++;
    } while (*s++);
    printf("%dN %dB %dM %dNB %dBM %dNBM",a[1],a[2],a[3],a[4],a[5],a[6]);
}

Chức năng kiểm tra

#include <stdio.h>
#include <stdlib.h>

/*
 * 0 : nothing
 * 1 : N
 * 2 : B
 * 3 : M
 * 4 : NB
 * 5 : BM
 * 6 : NBM
 */
#include "nbm-func.c"

int main(int argc, char **argv)
{
    c(argv[1]);
}

Sẽ không sử dụng for(;;*s++){...}thay vì do{...}while(*s++);lưu một số byte? Ngoài ra, bạn không cần ký tự dòng mới trong printf.
Spikatrix

Tôi nghĩ bạn có ý đó for(;*s;s++). Nhưng tôi cần phải lặp lại với ký tự null cuối cùng đó. Gọi tốt để tiết kiệm \n, mà không cần thiết.
một số người dùng

1

C, 146

f(char*s)
{
  char*p,*q="NBM\0NB\0BM\0N\0B\0M",i=0,a=2;
  for(;i<6;q+=a+2,a=i++<2)
  {
    int n=0;
    for(;p=strstr(s,q);++n)*p=p[a>1]=p[a]=1;
    printf("%d%s ",n,q);
  }
}

// Main function, just for testing
main(c,a)char**a;{
  f(a[1]);
}  

1

Haskell - 177 byte (không nhập)

n s=c$map(\x->(show$length$filter(==x)(words$c$zipWith(:)s([f(a:[b])|(a,b)<-zip s(tail s)]++[" "])))++x++" ")l
f"NB"=""
f"BM"=""
f p=" "
l=["N","B","M","NB","BM","NBM"]
c=concat

(Xin lỗi vì sự cần thiết của internet ở đây.)

Nền tảng Haskell không có tìm kiếm chuỗi mà không nhập, và tôi muốn thể hiện và khai thác thực tế rằng các chuỗi tìm kiếm là tất cả các chuỗi con của một (không lặp lại), do đó có thể thực hiện các nhóm ký tự bằng cách xác định các cặp được phép theo nhau, đó là những gì flàm ở đây.

Tôi vẫn cần danh sách đầy đủ lcuối cùng để kiểm tra sự bình đẳng và hiển thị chính xác theo yêu cầu, nhưng sẽ không, thách thức chỉ là báo cáo số lần xuất hiện có thể wordstheo bất kỳ thứ tự nào.


0

Bash - 101

I=$1
for p in NBM BM NB M B N;{ c=;while [[ $I =~ $p ]];do I=${I/$p/ };c+=1;done;echo -n ${#c}$p\ ;}

Truyền chuỗi như là đối số đầu tiên.

bash nmb.sh MBNNBBMNBM 

Giải thích một chút:

# We have to save the input into a variable since we modify it.
I=$1

# For each pattern (p) in order of precedence
for p in NBM BM NB M B N;do
    # Reset c to an empty string
    c=

    # Regexp search for pattern in string
    while [[ $I =~ $p ]];do
        # Replace first occurance of pattern with a space
        I=${I/$p/ }
        # Append to string c. the 1 is not special it could be any other
        # single character
        c+=1
    done

    # -n Suppress's newlines while echoing
    # ${#c} is the length on the string c
    # Use a backslash escape to put a space in the string.
    # Not using quotes in the golfed version saves a byte.
    echo -n "${#c}$p\ "
done

0

rs , 275 byte

(NBM)|(NB)|(BM)|(N)|(B)|(M)/a\1bc\2de\3fg\4hi\5jk\6l
[A-Z]+/_
#
+(#.*?)a_b/A\1
+(#.*?)c_d/B\1
+(#.*?)e_f/C\1
+(#.*?)g_h/D\1
+(#.*?)i_j/E\1
+(#.*?)k_l/F\1
#.*/
#
#(A*)/(^^\1)NBM #
#(B*)/(^^\1)NB #
#(C*)/(^^\1)BM #
#(D*)/(^^\1)N #
#(E*)/(^^\1)B #
#(F*)/(^^\1)M #
\(\^\^\)/0
 #/

Bản demo và thử nghiệm trực tiếp.

Các hoạt động đơn giản nhưng một chút kỳ lạ:

(NBM)|(NB)|(BM)|(N)|(B)|(M)/a\1bc\2de\3fg\4hi\5jk\6l

Điều này sáng tạo sử dụng các nhóm để biến đầu vào như:

NBMBM

vào

aNBMbcdeBMfghijkl

Dòng tiếp theo:

[A-Z]+/_

Điều này thay thế các chuỗi chữ in hoa bằng dấu gạch dưới.

#

Điều này chỉ đơn giản là chèn một dấu thăng ở đầu dòng.

+(#.*?)a_b/A\1
+(#.*?)c_d/B\1
+(#.*?)e_f/C\1
+(#.*?)g_h/D\1
+(#.*?)i_j/E\1
+(#.*?)k_l/F\1
#.*/

Đây là phần mát mẻ bắt đầu. Về cơ bản, nó lấy các chuỗi chữ cái viết thường và dấu gạch dưới, chuyển đổi chúng thành chữ in hoa, nhóm chúng lại với nhau và đặt chúng trước bảng được chèn. Mục đích của bảng Anh là quản lý các chuỗi đã được xử lý.

#

Bảng Anh được chèn lại ở đầu dòng.

#(A*)/(^^\1)NBM #
#(B*)/(^^\1)NB #
#(C*)/(^^\1)BM #
#(D*)/(^^\1)N #
#(E*)/(^^\1)B #
#(F*)/(^^\1)M #
\(\^\^\)/0
 #/

Các chữ in hoa được thay thế bằng văn bản tương đương của chúng với số lượng liên quan. Do một lỗi trong rs (tôi không muốn mạo hiểm sửa nó và bị loại), các chuỗi trống được chuyển thành (^^), được thay thế bằng 0 trong dòng thứ hai đến cuối cùng. Dòng cuối cùng chỉ đơn giản là loại bỏ bảng Anh.


0

KDB (Q), 76 byte

{" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}

Giải trình

                                                   l:" "vs"NBM NB BM N B M"     / substrings
                        enlist[x]{y vs" "sv x}\l                                / replace previous substring with space and cut
              -1+count@'                                                        / counter occurrence
       string[                                  ],'                             / string the count and join to substrings
{" "sv                                                                     }    / concatenate with space, put in lambda

Kiểm tra

q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}"NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM"
"3NBM 5NB 8BM 17N 6B 14M"
q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}""
"0NBM 0NB 0BM 0N 0B 0M"

0

Haskell: 244 byte

import Data.List
s="NBM"
[]#_=[[]]
a#[]=[]:a#s
l@(a:r)#(b:m)
 |a==b=let(x:y)=r#m in((a:x):y)
 |True=[]:l#m
c?t=length$filter(==t)c
p=["N","B","M","NB","BM","NBM"]
main=getLine>>= \l->putStrLn.intercalate " "$map(\t->show((l#[])?t)++t)p

Một số gợi ý: Bạn đang sử dụng pschỉ một lần, vì vậy không cần đặt tên cho nó (-> a#[]=[]:a#"NBM", tương tự p). BTW: words"N B M NB BM NBM"thay vì danh sách các chuỗi lưu byte bổ sung. Cái importnày chỉ dành cho intercalate, nó ngắn hơn khi thực hiện lại nó: ...putStrLn.tail.((' ':)=<<)$map...và thoát khỏi import. Đặt tất cả các vệ sĩ |theo định nghĩa #trong một dòng và sử dụng 1<2thay vì True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?có thể được định nghĩa ngắn hơn với một sự hiểu biết danh sách : c?t=sum[1|x<-c,x==t]. Một lần nữa, bạn ?chỉ sử dụng một lần, vì vậy hãy sử dụng cơ thể trực tiếp : ...show(sum[1|x<-l#[],x==t]).
nimi
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.