[Question]
  [
*This challenge is [NinjaBearMonkey](https://codegolf.stackexchange.com/users/29750/ninjabearmonkey)'s prize for winning my [Block Building Bot Flocks!](https://codegolf.stackexchange.com/questions/50690/block-building-bot-flocks) challenge with the [Black Knight](https://codegolf.stackexchange.com/a/50763/26997) submission. Congratulations NinjaBearMonkey!*
The challenge here is fairly simple, but has a variety of possible approaches. The story goes that in the world of [Isometric Illusions](https://i.stack.imgur.com/6X4J9.jpg?s=328&g=1), there are 6 different types of creatures:
1. Ninjas, abbreviated `N`
2. Bears, abbreviated `B`
3. Monkeys, abbreviated `M`
4. NinjaBears, abbreviated `NB`
5. BearMonkeys, abbreviated `BM`
6. NinjaBearMonkeys, abbreviated `NBM`
([NinjaBearMonkey](https://codegolf.stackexchange.com/users/29750/ninjabearmonkey) is, of course, the last, most powerful type.)
Your task is to take a [census](https://en.wikipedia.org/?title=Census) of these creatures when they are lined up side-by-side, i.e. when their abbreviation strings are concatenated. The caveat is that you need to make sure not to over-count the parts of some creatures as separate creatures that happen to look similar. The creatures will line up such that:
* Any instance of `NBM` is 1 NinjaBearMonkey and 0 other creatures.
* Any instance of `NB` not followed by `M` is 1 NinjaBear and 0 other creatures.
* Any instance of `BM` not preceded by `N` is 1 BearMonkey and 0 other creatures.
* Otherwise, instances of `N`, `B`, and `M` are single Ninjas, Bears, and Monkeys respectively.
The line is read from left to right.
So, for example, in the line of creatures `NBMMBNBNBM`, there are 0 Ninjas, 1 Bear, 1 Monkey, 1 NinjaBear, 0 BearMonkeys, and 2 NinjaBearMonkeys.
# Challenge
Write a program or function that takes in a string of the characters `N`, `B`, and `M`, and prints or returns how many of each of the 6 types of creatures are present in it.
The output should have the form
```
#N #B #M #NB #BM #NBM
```
with the respective creature count replacing each `#` sign. All 6 counts must be shown, separated by spaces, even when they are 0. However, they may be in any order (e.g. `#NBM` could come first).
Also:
* The input string will only contain the characters `N`, `B`, and `M`.
* If the empty string is input, then all the counts are 0.
* The output may optionally contain a single leading and/or trailing space, and/or a single trailing newline.
**The shortest submission in bytes wins.**
# Examples
Input: `NB`  
Output: `0N 0B 0M 1NB 0BM 0NBM`
Input: `NBM`  
Output: `0N 0B 0M 0NB 0BM 1NBM`
Input: `NBMMBNBNBM` (example from above)  
Output: `0N 1B 1M 1NB 0BM 2NBM`
Input: `MBNNBBMNBM`  
Output: `1N 1B 1M 1NB 1BM 1NBM`
Input: `NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM`  
Output: `17N 6B 14M 5NB 8BM 3NBM`
  
[Answer]
# JavaScript ES6, 86 bytes
```
f=s=>'NBM BM NB M B N'.replace(/\S+/g,e=>(i=0,s=s.replace(RegExp(e,'g'),_=>++i))&&i+e)
```
(I just had to answer this.) It goes through each substring of `NBM`, starting with the longer ones, which take higher priority. It searches for each occurrence of that particular string and removes it (in this case replacing it with the current count so it won't be matched again). It finally replaces each substring with the count + the string.
This Stack Snippet is written in the ES5 equivalent of the above code to make it easier to test from any browser. It is also slightly ungolfed code. The UI updates with every keystroke.
```
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>
```
[Answer]
# Pyth, 22 bytes
```
 f|pd+/zTT=:zTd_.:"NBM
```
Quite hackish way to save 1 byte, thanks to @Jakube.
---
# Pyth, 23 bytes
```
FN_.:"NBM")pd+/zNN=:zNd
```
[Demonstration.](https://pyth.herokuapp.com/?code=FN_.%3A%22NBM%22)pd%2B%2FzNN%3D%3AzNd&input=NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM&debug=0)
Prints in reverse order, with a trailing space and no trailing newline.
`.:"NBM")` is all the substrings, `_` puts them in the right order, `/zN` counts occurences, and `=:zNd` in-place substitutes each occurence of the string in question with a space.
```
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.
```
[Answer]
## Python 2, 78
```
n=input()
for x in"NBM BM NB M B N".split():n=`n`.split(x);print`len(n)-1`+x,
```
A variant of [Vioz-'s answer](https://codegolf.stackexchange.com/a/51821/20260). Fun with Python 2 string representations!
Counts occurrences of the substring indirectly by splitting on it, counting the parts, and subtracting 1. Instead of replacing the substrings by a filler symbol, replaces the string by the list that `split` produced. Then, when we take its string representation, the parts are separated by spaces and commas.
[Answer]
# Ruby, ~~166~~ ~~80~~ ~~72~~ 68 characters
```
f=->s{%w(NBM BM NB M B N).map{|t|c=0;s.gsub!(t){c+=1};c.to_s+t}*' '}
```
Explanation:
* The counting is done in reverse. This is because the longer ninjas and bears and monkeys take precedence over the shorter ones.
* For `NBM`, `BM`, and `NB`, the sequences are `gsub!`'d out of the original string with a block to count how many of these sequences exist (yes, the function modifies its argument).
	+ However, they can't be replaced with nothing, since otherwise `BNBMM` would be counted as `NBM` and `BM` instead of `B`, `NBM`, and `M` (because when the `NBM` would be removed, it would put the `B` and `M` together and there wouldn't be a way to distinguish it). Originally I returned a single character string (`.gsub!('NBM'){c+=1;?|}`), but I realized I could just return the result of the `+=` (which is a number, so it can't be any of `N` `B` `M`).
* ~~For `M`, `B`, and `N`, I can just `count` how many of them there are in the string (no need to remove them via `gsub!`).~~ Now it's a loop (don't know why I didn't think of that in the first place), so these are done the same way.
---
Similar solution in **[Ostrich](https://github.com/KeyboardFire/ostrich-lang), ~~54~~ 51 chars**:
```
:s;`NBM BM NB M B N`" /{:t0:n;s\{;n):n}X:s;nt+}%" *
```
Unfortunately not a valid solution, as there is a bug in the current Ostrich version (that is now fixed, but after this challenge was posted).
[Answer]
# 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],".");}
```
And with a few line breaks:
```
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],".");
}
```
It works pretty simply. Just loop over the tokens, replacing them with dots and counting as long as the input contains some. Counts the big ones first, so the little ones don't mess it up.
I originally tried replacing all at once and counting the difference in length, but it took a few more characters that way :(
[Answer]
# CJam, ~~36~~ ~~32~~ 31 bytes
```
l[ZYX]"NBM"few:+{A/_,(A+S@`}fA;
```
*Thanks to @Optimizer for golfing off 1 byte.*
Try it online in the [CJam interpreter](http://cjam.aditsu.net/#code=l%5BZYX%5D%22NBM%22few%3A%2B%7BA%2F_%2C(A%2BS%40%60%7DfA%3B&input=NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM).
### How it works
```
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.
```
[Answer]
# [Taxi](https://bigzaphod.github.io/Taxi/), 6284 bytes
```
Go to Post Office:W 1 L 1 R 1 L.Pickup a passenger going to Chop Suey.Go to Chop Suey:N 1 R 1 L 4 R 1 L.[A]Switch to plan N if no one is waiting.Pickup a passenger going to Cyclone.N is waiting at Writer's Depot.Go to Zoom Zoom:N 1 L 3 R.Go to Writer's Depot:W.Pickup a passenger going to Crime Lab.Go to Cyclone:N.Pickup a passenger going to Cyclone.Go to Cyclone:N 1 R 1 R 1 R.Pickup a passenger going to Cyclone.Pickup a passenger going to Cyclone.Go to Cyclone:N 1 R 1 R 1 R.Pickup a passenger going to Tom's Trims.Pickup a passenger going to Tom's Trims.Go to Tom's Trims:S 1 L 2 R 1 L.Go to Cyclone:S 1 R 1 L 2 R.Pickup a passenger going to Crime Lab.Pickup a passenger going to Tom's Trims.Go to Tom's Trims:S 1 L 2 R 1 L.Go to Crime Lab:S 1 L 1 L.Switch to plan F if no one is waiting.Pickup a passenger going to Auctioneer School.Go to Rob's Rest:S 1 R 1 L 1 L 1 R 1 R.Switch to plan D if no one is waiting.Go to Bird's Bench:S.Switch to plan B if no one is waiting.Go to Rob's Rest:N.Pickup a passenger going to KonKat's.Go to Bird's Bench:S.Pickup a passenger going to KonKat's.Go to KonKat's:N 1 R 1 L 2 R 1 R 2 R.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:N 1 L 2 L 1 L.Go to Auctioneer School:S.Pickup a passenger going to Rob's Rest.Go to Rob's Rest:N 2 L 1 R.Go to Cyclone:S 1 L 1 L 2 L.Switch to plan C.[B]Go to Auctioneer School:N 1 R 1 R.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:N.Go to Cyclone:N 1 L.[C]Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:N 2 R.Go to Chop Suey:E 2 R.Switch to plan A.[D]Go to Bird's Bench:S.Switch to plan E if no one is waiting.Pickup a passenger going to Sunny Skies Park.[E]Go to Auctioneer School:N 1 R 1 R.Pickup a passenger going to Rob's Rest.Go to Rob's Rest:N 2 L 1 R.Go to Sunny Skies Park:S 1 L 1 L.Go to Cyclone:N 1 L.Switch to plan C.[F]B is waiting at Writer's Depot.Go to Writer's Depot:S 1 R 1 L 2 L.Pickup a passenger going to Crime Lab.Go to Cyclone:N.Pickup a passenger going to Cyclone.Go to Cyclone:N 1 R 1 R 1 R.Pickup a passenger going to Crime Lab.Go to Crime Lab:S 1 L 2 R 2 L.Switch to plan J if no one is waiting.Pickup a passenger going to Auctioneer School.Go to Bird's Bench:S 1 R 1 L 1 L 1 R 1 L.Switch to plan I if no one is waiting.Go to Rob's Rest:N.Switch to plan G if no one is waiting.Pickup a passenger going to KonKat's.[G]Go to Bird's Bench:S.Pickup a passenger going to KonKat's.Go to KonKat's:N 1 R 1 L 2 R 1 R 2 R.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:N 1 L 2 L 1 L.Go to Auctioneer School:S.[H]Pickup a passenger going to Bird's Bench.Go to Bird's Bench:N 2 L 1 L.Go to Cyclone:N 1 R 1 L 2 L.Switch to plan C.[I]Go to Auctioneer School:N 1 R 1 R.Switch to plan H.[J]Go to Bird's Bench:S 1 R 1 L 1 L 1 R 1 L.Switch to plan L if no one is waiting.Go to Rob's Rest:N.Switch to plan K if no one is waiting.Pickup a passenger going to KonKat's.[K]Go to Bird's Bench:S.Pickup a passenger going to KonKat's.[L]Go to Cyclone:N 1 R 1 L 2 L.Pickup a passenger going to KonKat's.Go to KonKat's:N 2 R 2 R.Pickup a passenger going to Sunny Skies Park.Go to Rob's Rest:S 4 R 1 L 1 L 1 R 1 R.Switch to plan M if no one is waiting.Pickup a passenger going to Sunny Skies Park.[M]Go to Sunny Skies Park:S 1 L 1 L.Go to Chop Suey:N 1 R 1 R 3 R.Switch to plan A.[N]Go to Rob's Rest:N 1 L 3 L 1 L 2 R 1 R.Switch to plan O if no one is waiting.Pickup a passenger going to KonKat's.[O]Go to Bird's Bench:S.Switch to plan P if no one is waiting.Pickup a passenger going to KonKat's.[P]Go to KonKat's:N 1 R 1 L 2 R 1 R 2 R.Switch to plan Q if no one is waiting.Pickup a passenger going to Sunny Skies Park.[Q]Go to Sunny Skies Park:N 1 L 2 L 1 L.N is waiting at Writer's Depot.B is waiting at Writer's Depot.M is waiting at Writer's Depot.NB is waiting at Writer's Depot.BM is waiting at Writer's Depot.NBM is waiting at Writer's Depot.Go to Writer's Depot:N 1 L.Pickup a passenger going to Joyless Park.Pickup a passenger going to Joyless Park.Pickup a passenger going to Joyless Park.Go to Joyless Park:N 3 R 2 R 2 L.Go to Writer's Depot:W 1 R 2 L 2 L.Pickup a passenger going to Joyless Park.Pickup a passenger going to Joyless Park.Pickup a passenger going to Joyless Park.Go to Joyless Park:N 3 R 2 R 2 L.[R]Switch to plan Y if no one is waiting.Pickup a passenger going to Cyclone.0 is waiting at Starchild Numerology.Go to Starchild Numerology:W 1 L 2 R 1 L 1 L 2 L.Pickup a passenger going to Addition Alley.Go to Cyclone:W 1 R 4 L.[S]Pickup a passenger going to Auctioneer School.Go to Zoom Zoom:N.Go to Auctioneer School:W 2 L.Go to Sunny Skies Park:N.Switch to plan V if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:N 1 L.Pickup a passenger going to Crime Lab.Pickup a passenger going to Crime Lab.Go to Crime Lab:S 1 L 2 R 2 L.Switch to plan T if no one is waiting.Pickup a passenger going to Tom's Trims.Go to Tom's Trims:N 1 L 1 L.1 is waiting at Starchild Numerology.Go to Starchild Numerology:S 1 R 1 L 1 L 2 L.Pickup a passenger going to Addition Alley.Go to Addition Alley:W 1 R 3 R 1 R 1 R.Pickup a passenger going to Addition Alley.Go to Cyclone:N 1 L 1 L.Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:N 2 R.Go to Auctioneer School:W 2 L 1 L.Switch to plan U.[T]Go to Cyclone:N 4 L 2 L.Pickup a passenger going to Narrow Path Park.Go to Narrow Path Park:N 2 R 1 L 1 R.Go to Auctioneer School:W 1 L 1 R 2 L 1 L.[U]Pickup a passenger going to Cyclone.Go to Cyclone:N 4 L.Switch to plan S.[V]Go to Addition Alley:N 1 R 1 R 1 R.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:N 1 R 1 R.Pickup a passenger going to Post Office.Go to Cyclone:N 1 L 1 L 2 R.Pickup a passenger going to Post Office." " is waiting at Writer's Depot.Go to Writer's Depot:S.Pickup a passenger going to Post Office.Go to Post Office:N 1 R 2 R 1 L.Go to Auctioneer School:S 1 R 1 L 1 L.Pickup a passenger going to Tom's Trims.Go to Narrow Path Park:N 3 R 1 R 1 L 1 R.[W]Switch to plan X if no one is waiting.Pickup a passenger going to Sunny Skies Park.Go to Sunny Skies Park:W 1 L 1 R 2 L 1 L.Go to Zoom Zoom:N 1 R.Go to Narrow Path Park:W 1 L 1 L 1 R.Switch to plan W.[X]Go to Tom's Trims:E 1 R 4 R 1 L.Go to Joyless Park:N 1 R 1 L 3 R.Switch to plan R.[Y]
```
[Try it online!](https://tio.run/##3Vhbc6IwFP4rmb70jdlan3yT1t7U1IKt7TJ5oBglUyQOYF1/vRsgaAyRm@7szs54DTk5t@/cEtm/yHZ7T0FEwYiGEXiezYiDOxNwBQbsbcTf2og4X6slsMHSDkPsz3EA5pT485jqxqVLYK7wRktP2f3vwIwetPk5VheZaxI5brxx6dk@gIDMgE8B9TEgIVjbJGLnFjPcOB7brkGBANgRmAQkwsFlCG7xkkZcmp@ULpKPRJoBuAYGf3K4vTMp5hmQBQYD@zNTMpWhAytJKtFwsyTvSvR/kseYLpgNxky/sPK@lJew0jET47a4mw9lMXcwaJXpu7PymSXJzuVP4ycSDu/q47C7ciLC9rM103Ep9Tg3g34yaQwcRoLq@2gyZNa3atbpYToJpuw0HfuO2zFlUr2IVJCjGKZ96vft6DJUs6xBmf0VIr/FYVjmenPl@xtgfhEcgpEdfPET5WUexS3uxHRTzhElUu8No7AUP9tQgHiQ8ZbdcKNZOjomC6wUhpX1VwQ6y6s3qFBh8o2Db4LXQA/IdJ4lC3k5Ud7IpfFesiqp3NWsW1QFor36gZWzhdU70bp1PJ4z@T5nqEyfh8Id0qtUJqn@iFly8C/WIpmrlFNbSZDn7PF0vrx6iDNFZs0xf6ycHiXC@/pS71KhdY/@ozxqPRRmFlFHlZugxELG3bF0@lgh4CWqB816Qk2RMmiKlP4pSOmfgBRrgIpM2gxtreYIO@h62uVdz/AcdWGIqubs3FBiJKNAvqpBpKgQ6eQwECNRJn0@BQjPlUrp6BQWI1Qpt0gsX87hpRdUKQmVzHMlRXVY/BiWkOul9MMGRR2WTs9PdOPhkFvq/BtTqcQlJtN16uskT6hnYQ6H8lTyt8W3DPlC4aP5hcIPycNmZAeOS7wpgKsFDqhH59klh@oRvzNpCbmvzHzd6ZTE9Q10PW9/gcITeuqFdqyliZo0TMLdx9EKPxFQoBg2JOO@NTeuqnc@/S6gYVc6rq9H8a0D3NWbqxNBdNiuNALQ4SLH0XXFPr8Qkns1zz1uHkGmqld71axxrvdpVzAWtIOArhm0I1dML/Iy74OuDqZClXxZd5PJab2iJpHQzqvI@u43pHRmjYs9FwPd/sTejIQuDjJXyssVJ2jhbvgYJko7R/GMC3DRZEiuKaN4ow2zHqd44hHDr2ZCUABpH3UpmKyJXK/ez9BhHUnfeYSq7sSNY9JPxBZeRuhEs95RPg/2eM0SjSyV78wcivab2ecDbbcQwiHrt4bpK/4ZL0CoJ2@dvWC8qid7dLZHZ79h/D2Mt7GfKelv "Taxi – Try It Online")
This ain't winning me any Code Golf competitions, but this was a nice reminder for me not to write any more complex programs in Taxi. *(Sooo many special cases, and sooo much gas management...)*
A more commented version can be found [here](https://tio.run/##1VlLb@M2EL77VxC@5BIEjZOTT43axWK7jhrYCwSo4QMt0xZrWXQpOln/@nQoURJFUaYkK0AL@EkNh8OZbx4cCvyTfnx8ZUgw9MISgf7cbmlApq/oHs3gPZffd6MXGuxPR4TREScJiXeEox2j8U5O@y1kR7Q4kfPdKONTDEz9nAN6zDmNlkdOjpwFJEkkg4ix42q0/LWYtBot3qkIQsnpGOEYjUm8QfVJY0S3KGaIxQTRBL1jKuCRQ9RzEAH93cjXpiAs0CungvCbBP1OjkzkG/mLsUP6kW5khh7QPH9UnTB9dazL6YGgGV4XKsoEmfpSIYnAUYS2jKMDjIECWm3BYKQ0nb5bKuFzl/nBDqCeH7DzpANhtpw2NF2kqp/k@KnKsygANnFuu7TB4NLkrNVjBXSAcchOAomQoNTGsMQt/APoSfSFOHsEuN5xfEDv7BRtJLT3KKJ7Ak7RDVKGEFLGCQiyGtUcClaPmUA@jf/GTW40WsK/lCL1zpz5ZXA@nQJBgROMLYKQsSgXbs7WoMI5SYRmsjLCgOlMGdOlkZJUSdUsa0GtxqTM5ZorJYVH@QaGPBIH4XRxYc08MqzBeh7BXMnhWh9DoMrJNUH0ZVd1hfiXAfmdxd@xuCnQaG6iy9z8vxaYJ8qfnf6zOMXxGS32lCToBfN9ztMcV7FykvtBRlVDhkv0UkEWDPmK/dwWD2b5@nUDc5iMubBkE7TlEOsVm7ENUiYYmixb36nfLmC2V7AtKsNuly23d9mH5/SN8DdK3pHH6WZXpABzPDXCvJ7zv2TDpuotCbyiZc3Nr3Fe3QW7RQ6NWjd13czdbGiLDcZeB0VRN7@pYUtLYFaMXeNRetoxkorXqh4zii49@c/6F2CfXG21zdNNWVqC5mKSlgRD5Oiqg1mytEXGTq7WKzU2rai7qu7DjuWlG7qKhXYZtbafmijt4tj/OH87E05t1mXl6qqxotI3xTIdcoC8P1SQ7ipDjZkeMy0@PozThuc1ZHO3z2Z0/Vy2kmJdCxbE5Yp9fNOy5pDuWIXJZeU0YLSn30@u8fXKMeyxzTGsvs1qCO0U@JuY9IjDtkKrg6x2LLSohmqtrXnWFWpZ7tpbWUb/y1K2Zd2nmR7x62uC7iOyFQzq9EQWUSWHPr0yHezNnPvV6iY/nX5oWasuaXdRV169JH8feW3o1XlKOXOZVi3ztKul6Sqxnx3PfRcDz83huU@Z77tb0H@wcwT@pHT5GZSZZPoYyPWQ4SOL5/a@sMJQi5j/X9jDaBmwUyyKoKTT2vvyJf1V/fhfDGAsoFQKQhpB9D4dCGcR2xXXC7Zn6r5ioqU0p8KfNhsqKy70FEXa5YXK1pnlHjOtkFiuhAUpw3WbVkrjUUu7WGgusF91XNmaQDZ7VCW9yibW8/8AHfb@J@JEcOABUZ2TNJmTf044ai47dPKUtMMp2XEN4JeFwf210K1W7T1hWx1V6H1o26S47AraZodvHDbg3n5y2UgjB@xwxNKySBl4bBq7wIb1yFRu67GNvn3MOXsHpxNhJY6a46o2v6822GzbywvuSXlVZN9Y60DT6LOPNi0aMSKvS@tBzgw6KzvYulwKhgR5eE2iLU1CwguomeNtu53alXUjat3HpQqXMRr3akZ2FlS/bvfzWtPRc9FDRed7TAtiywihUCt7OhELdBSY0@yFQGXaMDVxQ@azOJDtun7euO1X/dhra9ToO8m9o4Va6mniiyoiKmY1CrBc/dZjpFZe5YJcqtBGy2/qGnnH0BoHe8lJ3jH/wD8p@oo53pHbtE@5JgE@JaS4jQ7YhsCkaHuLBAnCmAY4is7oG4LIdAPHafwGtGz18eH7/jMU8s/ZS/6UA77vpW8PXr4c9VIaD2g8@O3L72dJBj@zqR//Ag "Taxi – Try It Online"), if you dare.
[Answer]
# R, ~~153~~ ~~134~~ 118
This got longer really quickly, but hopefully I'll be able to shave a few. Input is STDIN and output to STDOUT.
**Edit** Change of tack. Got rid of the split string and counting parts. Now I replace the parts with a string one shorter than the part. The difference between the string lengths is collected for output.
```
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),'')
```
Explanation
```
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
  ,'')
```
Test run
```
> 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 
> 
```
[Answer]
# Pyth, 19 bytes
```
jd+Ltl=zc`zd_.:"NBM
```
This is a mixture of @isaacg's Pyth solution and @xnor's incredible Python trick. 
Try it online: [Demonstration](https://pyth.herokuapp.com/?code=jd%2BLtl%3Dzc%60zd_.%3A%22NBM&input=NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM&debug=0) or [Test harness](https://pyth.herokuapp.com/?code=zFz.zs%5Bz%22%20%3D%3E%20%22%0Ajd%2BLtl%3Dzc%60zd_.%3A%22NBM&input=Test-cases%3A%0ANB%0ANBM%0ANBMMBNBNBM%0AMBNNBBMNBM%0ANNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM&debug=0)
### Explanation
```
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
```
[Answer]
# Julia, ~~106~~ 97 bytes
```
b->for s=split("NBM BM NB M B N") print(length(matchall(Regex(s),b)),s," ");b=replace(b,s,".")end
```
This creates an unnamed function that takes a string as input and prints the result to STDOUT with a single trailing space and no trailing newline. To call it, give it a name, e.g. `f=b->...`.
Ungolfed + explanation:
```
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
```
Examples:
```
julia> f("NBMMBNBNBM")
2NBM 0BM 1NB 1M 1B 0N 
julia> f("NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM")
3NBM 8BM 5NB 14M 6B 17N 
```
[Answer]
# Python 2, ~~93~~ ~~88~~ ~~89~~ 84 Bytes
Taking the straightforward approach.
```
def f(n):
 for x in"NBM BM NB M B N".split():print`n.count(x)`+x,;n=n.replace(x,"+")
```
Call like so:
```
f("NBMMBNBNBM")
```
Output is like so:
```
2NBM 0BM 1NB 1M 1B 0N
```
[Answer]
# SAS, 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;
```
Usage (7 bytes added for 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
```
or 
```
%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;
```
Usage:
```
data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)
```
Result:
```
3NBM 5NB 8BM 17N 6B 14M
```
[Answer]
# PHP4.1, 92 bytes
Not the shortest one, but what else would you expect from PHP?
To use it, set a key on a COOKIE, POST, GET, SESSION...
```
<?foreach(split(o,NBMoNBoBMoMoBoN)as$a){echo count($T=split($a,$S))-1,"$a ";$S=join('',$T);}
```
The apporach is basic:
* Split the string into the names of the creatures
* Count how many elements there are
* Subtract 1 (an empty string would give an array with 1 element)
* Output the count and the creature name
* Join it all together, using an empty string (which will reduce the string and remove the last creature)
Easy, right?
[Answer]
# Perl, 46
```
#!perl -p
$_="NBM BM NB M B N"=~s/\w+/~~s!$&!x!g.$&/ger
```
[Answer]
# JavaScript, ~~108~~ 116 bytes
Just a straight forward approach, nothing fancy
```
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);
```
[Answer]
# 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$
```
Uses the same approach as a lot of others. Line 4 keeps looping over the string (from largest first), replaces it if found.
SpecBAS has some nice touches over original ZX/Sinclair BASIC (looping through lists, finding characters) which I'm still finding out.
[Answer]
# C, 205 186 184 bytes
A little different approach based on state machine. where `t` is the state.
```
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]);}
```
Expanded
```
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]);
}
```
Test function
```
#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]);
}
```
[Answer]
# 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]);
}  
```
[Answer]
# Haskell - 177 bytes (without imports)
```
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
```
(Sorry for the internet necromancy here.)
The Haskell Platform doesn't have string search without imports, and I wanted to show off and exploit the fact that the searched strings are all substrings of one (without repetitions), so that grouping characters can be done by identifying pairs that are allowed to follow each other, which is what `f` does here.
I still need the full list `l` in the end to check for equality and display exactly as required, but would not, had the challenge only been to report the number of occurrences of the possible `words` in any order.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 18 bytes
```
`NBM`KṘ(n/₅‹n+¨…_∑
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=%60NBM%60K%E1%B9%98%28n%2F%E2%82%85%E2%80%B9n%2B%C2%A8%E2%80%A6_%E2%88%91&inputs=NBMN&header=&footer=)
```
`NBM`              # 'NBM'
     K             # Substrings
      Ṙ(           # Iterate over
        n/         # Split current string by current substring of NBM
          ₅‹       # Duplicate and decrement length
            np¨…_  # Prepend current substring of NBM and output with a trailing space
                 ∑ # Concatenate for next iteration
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 27 bytes
```
;zS`+ös←Lx₁GoΣ`x⁰₁
↔ÖLQ"NBM
```
[Try it online!](https://tio.run/##yygtzv7/37oqOEH78LbiR20TfCoeNTW6559bnFDxqHEDkM31qG3K4Wk@gUp@Tr7////38/PzBbJ8IQjEBAn4@TmBsRMQ@YFEncBqnIBqnIBsPxDtC1IGZEK0AgA "Husk – Try It Online")
uses the splitting technique from the Vyxal answer.
# [Husk](https://github.com/barbuz/Husk), 28 bytes
```
m§+osL←k€₁Ẋ`-U¡Ṡ-(→n₁ḣ
Q"NBM
```
[Try it online!](https://tio.run/##yygtzv7/P/fQcu38Yp9HbROyHzWtedTU@HBXV4Ju6KGFD3cu0NV41DYpDyS2YzFXoJKfk@/////9/Px8gSxfCAIxQQJ@fk5g7AREfiBRJ7AaJ6AaJyDbD0T7gpQBmRCtAA "Husk – Try It Online")
Funny set intersection based idea.
[Answer]
# [Japt](https://github.com/ETHproductions/japt) [`-S`](https://codegolf.meta.stackexchange.com/a/14339/), 18 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
Outputs in reverse order.
```
"NBM"ã ÔËiUèDU=rDS
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&flags=LVM&code=Ik5CTSLjINTLaVXoRFU9ckRT&footer=dw&input=Ik5OTk1OQk1NQk1NQk1NTU5CTU5OTU5OTkJOTk5CTkJCTkJOTU1OQkJOQk1NQkJNQk1CQkJOTk1CTUJNTU5OTk5OTU1CTU1CTSI) (footer reverses the output)
```
"NBM"ã ÔËiUèDU=rDS     :Implicit input of string U
"NBM"ã                 :Substrings of "NBM"
       Ô               :Reverse
        Ë              :Map each D
         i             :  Prepend
          UèD          :    Count of D in U
             U=        :    Reassign to U*
               rD      :      Replace D with
                 S     :      Space
                       :Implicit output joined with spaces
```
\*This is done within the second argument of the `è` method but as that only expects 1 argument, it's result is ignored within the mapping & prepending.
[Answer]
# Excel, ~~149~~ 145 bytes
Saved 4 bytes by realizing I can directly use `LEN(a)` after I rewrote the function from my first - never submitted - draft.
```
=LET(a,SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"NBM",1),"BM",2),"NB",3),LEN(a)-LEN(SUBSTITUTE(a,{"N","B","M",3,2,1},))&{"N","B","M","NB","BM","NBM"})
```
Start by replacing NBM with 1 then BM with 2 and NB with 3. Now we have a string that is as many characters long as they are creatures. One by one, we check the difference between that string's length and it's length with one of the creatures removed. Output is an array of cells.
[![Screenshot](https://i.stack.imgur.com/alWHz.png)](https://i.stack.imgur.com/alWHz.png)
[Answer]
# 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\ ;}
```
Pass the string as the first argument.
```
bash nmb.sh MBNNBBMNBM 
```
Explained a bit:
```
# 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
```
[Answer]
# [rs](https://github/kirbyfan64/rs), 275 bytes
```
(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
 #/
```
[Live demo and tests.](http://kirbyfan64.github.io/rs/index.html?script=(NBM)%7C(NB)%7C(BM)%7C(N)%7C(B)%7C(M)%2Fa%5C1bc%5C2de%5C3fg%5C4hi%5C5jk%5C6l%0A%5BA-Z%5D%2B%2F_%0A%23%0A%2B(%23.*%3F)a_b%2FA%5C1%0A%2B(%23.*%3F)c_d%2FB%5C1%0A%2B(%23.*%3F)e_f%2FC%5C1%0A%2B(%23.*%3F)g_h%2FD%5C1%0A%2B(%23.*%3F)i_j%2FE%5C1%0A%2B(%23.*%3F)k_l%2FF%5C1%0A%23.*%2F%0A%23%0A%23(A*)%2F(%5E%5E%5C1)NBM%20%23%0A%23(B*)%2F(%5E%5E%5C1)NB%20%23%0A%23(C*)%2F(%5E%5E%5C1)BM%20%23%0A%23(D*)%2F(%5E%5E%5C1)N%20%23%0A%23(E*)%2F(%5E%5E%5C1)B%20%23%0A%23(F*)%2F(%5E%5E%5C1)M%20%23%0A%5C(%5C%5E%5C%5E%5C)%2F0%0A%20%23%2F&input=NB%0ANBM%0ANBMMBNBNBM%0AMBNNBBMNBM%0ANNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)
The workings are simple but a little odd:
```
(NBM)|(NB)|(BM)|(N)|(B)|(M)/a\1bc\2de\3fg\4hi\5jk\6l
```
This creatively uses groups to turn input like:
```
NBMBM
```
into
```
aNBMbcdeBMfghijkl
```
The next line:
```
[A-Z]+/_
```
This replaces the sequences of capital letters with underscores.
```
#
```
This simply inserts a pound sign at the beginning of the line.
```
+(#.*?)a_b/A\1
+(#.*?)c_d/B\1
+(#.*?)e_f/C\1
+(#.*?)g_h/D\1
+(#.*?)i_j/E\1
+(#.*?)k_l/F\1
#.*/
```
*This* is the beginning cool part. It basically takes the sequences of lowercase letters and underscores, converts them into capital letters, groups them together, and places them before the pound that was inserted. The purpose of the pound is to manage the sequences that have already been processed.
```
#
```
The pound is re-inserted at the beginning of the line.
```
#(A*)/(^^\1)NBM #
#(B*)/(^^\1)NB #
#(C*)/(^^\1)BM #
#(D*)/(^^\1)N #
#(E*)/(^^\1)B #
#(F*)/(^^\1)M #
\(\^\^\)/0
 #/
```
The capital letters are replaced by their text equivalents with the associated counts. Because of a bug in rs (I didn't want to risk fixing it and getting disqualified), the empty sequences are converted into `(^^)`, which is replaced by a 0 in the second-to-last line. The very last line simply removes the pound.
[Answer]
# KDB(Q), 76 bytes
```
{" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}
```
# Explanation
```
                                                   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
```
# Test
```
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"
```
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 18 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
â╥)3╨‼!∩╢←◘♀←N╟Ijƒ
```
[Run and debug it](https://staxlang.xyz/#p=83d22933d01321efb61b080c1b4ec7496a9f&i=NB%0ANBM%0ANBMMBNBNBM%0AMBNNBBMNBM%0ANNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM&m=2)
[Answer]
# Haskell, 244 bytes
```
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
```
]