Ниндзя и Обезьяны и Медведи, О, Боже!


37

Эта задача является призом NinjaBearMonkey за победу в моих блоках Block Building Bot! вызов с представлением Черного рыцаря . Поздравляем NinjaBearMonkey!

Задача здесь довольно проста, но имеет множество возможных подходов. История гласит, что в мире Изометрических иллюзий существует 6 различных типов существ:

  1. Ниндзя, сокращенно N
  2. Медведи, сокращенно B
  3. Обезьяны, сокращенно M
  4. NinjaBears, сокращенно NB
  5. BearMonkeys, сокращенно BM
  6. NinjaBearMonkeys, сокращенно NBM

( NinjaBearMonkey , конечно, последний, самый мощный тип.)

Ваша задача - провести перепись этих существ, когда они выстроены в ряд, то есть, когда их строки сокращений объединены. Предостережение заключается в том, что вам нужно следить за тем, чтобы части некоторых существ не были переоценены как отдельные существа, которые выглядят одинаково. Существа будут выстроены так, что:

  • Любой экземпляр NBM- 1 NinjaBearMonkey и 0 других существ.
  • Любой случай, за которым NBне следует, Mэто 1 NinjaBear и 0 других существ.
  • Любому экземпляру, BMкоторому не предшествует, Nявляется 1 BearMonkey и 0 других существ.
  • В противном случае, экземпляры N, Bи Mодиночные Ninjas, медведи и обезьяны соответственно.

Строка читается слева направо.

Так, например, в линейке существ NBMMBNBNBMесть 0 ниндзя, 1 медведь, 1 обезьяна, 1 ниндзя-медведь, 0 медведей-обезьян и 2 ниндзя-медведей-обезьян.

Вызов

Напишите программу или функцию, которая принимает строку символов N, Bи M, и печатает или возвращает, сколько из каждого из 6 типов существ присутствует в ней.

Вывод должен иметь форму

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

с соответствующим количеством существ, заменяющим каждый #знак. Все 6 отсчетов должны быть показаны через пробел, даже если они равны 0. Однако они могут быть в любом порядке (например, могут стоять #NBMпервыми).

Также:

  • Строка ввода будет содержать только символы N, Bи M.
  • Если вводится пустая строка, то все счетчики равны 0.
  • Выходные данные могут дополнительно содержать один начальный и / или завершающий пробел и / или один завершающий символ новой строки.

Самая короткая подача в байтах побеждает.

Примеры

Вход: NB
Выход:0N 0B 0M 1NB 0BM 0NBM

Вход: NBM
Выход:0N 0B 0M 0NB 0BM 1NBM

Вход: NBMMBNBNBM(пример сверху)
Выход:0N 1B 1M 1NB 0BM 2NBM

Вход: MBNNBBMNBM
Выход:1N 1B 1M 1NB 1BM 1NBM

Вход: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Выход:17N 6B 14M 5NB 8BM 3NBM


53
Я одобряю этот вызов.
NinjaBearMonkey

Просто чтобы подтвердить: если у вас было всего 2 NinjaBearMonkeys, вы не можете сформировать линию? Потому что они не могут стоять рядом друг с другом?
Алан Кэмпбелл

3
@AlanCampbell Нет. NBMNBMБудет вполне корректным вводом. Читая это слева направо, ясно, что есть 2 NinjaBearMonkeys.
Увлечения Кэлвина

Ответы:


20

Pyth, 22 байта

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

Довольно хакерский способ сэкономить 1 байт, благодаря @Jakube.


Pyth, 23 байта

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

Демонстрация.

Печать в обратном порядке, с завершающим пробелом и без завершающего перевода строки.

.:"NBM")Это все подстроки, размещает _их в правильном порядке, /zNподсчитывает вхождения и =:zNdзаменяет каждое вхождение каждой строки на пробел.

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 байт

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

(Я просто должен был ответить на это.) Он проходит через каждую подстроку NBM, начиная с более длинных, которые имеют более высокий приоритет. Он ищет каждое вхождение этой конкретной строки и удаляет ее (в этом случае его заменяют текущим счетчиком, чтобы он больше не совпадал). Наконец, каждая подстрока заменяется на число + строку.

Этот фрагмент стека написан в ES5-эквиваленте приведенного выше кода, чтобы его было проще тестировать из любого браузера. Это также немного неопрятный код. Пользовательский интерфейс обновляется с каждым нажатием клавиши.

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>


Не могли бы вы изменить часть регулярного выражения на 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', где <newline>s - буквальные символы новой строки, а 's - обратные метки, образующие строку шаблона ES6? Сохраняет два байта в регулярном выражении ( .не соответствует символам новой строки).
wchargin

@WChargin К сожалению, нет, потому что выходные данные должны быть разделены пробелом.
NinjaBearMonkey

17

Python 2, 78

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

Вариант ответа Виоса . Удовольствие от представления строки Python 2!

Косвенно подсчитывает вхождения подстроки, разделяя ее, подсчитывая части и вычитая 1. Вместо замены подстрок символом-заполнителем строка заменяется созданным списком split. Затем, когда мы берем его строковое представление, части разделяются пробелами и запятыми.


5
Это безумие! Отлично безумный, но все еще безумный.
Sp3000

Хорошо сделано! Не думал об этом :)
Каде

14

Рубин, 166 80 72 68 символов

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

Объяснение:

  • Подсчет производится в обратном порядке. Это потому, что более длинные ниндзя, медведи и обезьяны имеют преимущество перед более короткими.

  • Для NBM, BMи NB, последовательности gsub!извлекаются из исходной строки с блоком для подсчета количества этих последовательностей (да, функция изменяет свой аргумент).

    • Тем не менее, они не могут быть заменены ничем, так как в противном случае BNBMMбудет считаться , NBMи BMвместо того B, NBMи M(потому что , когда NBMбудет удален, он бы поставил Bи Mвместе , и не было бы способ отличить его). Первоначально я возвращал одну символьную строку ( .gsub!('NBM'){c+=1;?|}), но я понял, что могу просто вернуть результат +=(который является числом, поэтому он не может быть любым N B M).
  • И M, Bи N, я могу только, countсколько их в строке (нет необходимости удалять их через gsub!). Теперь это цикл (не знаю, почему я вообще об этом не задумывался), поэтому все делается так же.


Аналогичное решение в страусе , 54 51 символ :

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

К сожалению, недопустимое решение, так как в текущей версии Страуса есть ошибка (которая теперь исправлена, но после того, как эта проблема была опубликована).


Вы можете сохранить 3 символа, используя обозначение массива %w(NBM BM NB M B N)и удалив разделение.
DickieBoy

@DickieBoy Это на самом деле 4 символа; Благодарность!
Дверная ручка

Ах да, точка!
DickieBoy

14

Ява, 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],".");}

И с несколькими переносами строк:

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],".");
}

Это работает довольно просто. Просто зациклите токены, заменив их точками и считая до тех пор, пока вход содержит некоторые. Сначала подсчитывает большие, чтобы маленькие не испортили.

Сначала я попытался заменить все сразу и посчитать разницу в длине, но таким образом потребовалось еще несколько символов :(


2
Как разработчик Java, я хочу сделать это короче и увидеть, как Java выиграет от перемен. Посмотрев на него некоторое время, я еще не нашел способ сделать его короче.
DeadChex

1
Ну, это определенно не победит в целом. Текущий лидер - 22 байта, и в Java такого размера просто невозможно что-либо сделать. Мое printlnутверждение одно больше, чем это. Я доволен этим, хотя: D
Geobits

1
Я немного опоздал, но я нашел способ ... изменить String q[]=наString[]q=
DeadChex

1
Ницца! Не могу поверить, что я пропустил это, это в моем стандартном списке вещей, чтобы посмотреть :)
Geobits

Я обнаружил это только после попытки войти в Code Golf как JavaDev, я очень удивлен тем, что вы можете сделать
DeadChex

11

CJam, 36 32 31 байт

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

Спасибо @Optimizer за удаление 1 байта.

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

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*-> `должно быть достаточно.
Оптимизатор

@ Оптимизировать: это работает хорошо. Спасибо.
Деннис

7

R 153 134 118

Это действительно дольше, но надеюсь, я смогу побриться немного. Вход STDIN и выход STDOUT.

Изменить Смена такта. Избавился от расщепленной струны и счетных частей. Теперь я заменяю детали строкой, которая короче детали. Разница между длинами строк собирается для вывода.

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

объяснение

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

Тестовый забег

> 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

Pyth, 19 байт

jd+Ltl=zc`zd_.:"NBM

Это смесь решения Python @ isaacg и невероятного трюка Python @ xnor.

Попробуйте онлайн: демонстрация или тестовая привязь

объяснение

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

Юлия, 106 97 байт

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

Это создает безымянную функцию, которая принимает строку в качестве входных данных и печатает результат в STDOUT с одним завершающим пробелом и без завершающего перевода строки. Чтобы назвать его, дайте ему имя, например f=b->....

Ungolfed + объяснение:

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

Примеры:

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 байта

Принимая простой подход.

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

Звоните вот так:

f("NBMMBNBNBM")

Вывод выглядит так:

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

Вы можете удалить пространство после in.
Исаак

В Python 2 вы можете преобразовать в строковое представление с помощью `x`.
xnor

4

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;

Использование (добавлено 7 байт для 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

или

%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;

Использование:

data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)

Результат:

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

Вы можете сохранить пару байтов, используя cats('s/',z,'/x/')вместо 's/'||strip(z)||'/x/'.
Алекс А.

1
Хорошо, это было довольно путешествие назад к 139 :)
Жареное яйцо

1
126 байтов: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;%
Алекс А.

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;. Поскольку вы уже читаете из sysparm, вы можете просто запустить его как шаг данных. И если вы работаете в пакетном режиме, вам не нужно run;.
Алекс А.

1
Но вы могли бы получить 129, используя макрос современного стиля, который не читается из аргумента командной строки:%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;
Алекс А.

3

PHP4.1, 92 байта

Не самый короткий, но что еще можно ожидать от PHP?

Чтобы использовать его, установите ключ на COOKIE, POST, GET, SESSION ...

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

Apporach является основным:

  • Разбейте строку на имена существ
  • Подсчитайте, сколько элементов
  • Вычтите 1 (пустая строка даст массив с 1 элементом)
  • Выведите количество и имя существа
  • Соедините все это вместе, используя пустую строку (которая уменьшит строку и удалит последнее существо)

Легко, правда?


2

JavaScript, 108 116 байт

Просто прямой подход, ничего особенного

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
Не работает: All 6 counts must be shown, separated by spaces, even when they are 0.. Контрольный пример:N
edc65

@ edc65 Воу. Я просто пропустил эту часть. Спасибо что подметил это. Исправлено это за стоимость 8 знаков
C5H8NNaO4

2

Perl, 46

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

Объяснение того, как это работает?
Каин

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$

Использует тот же подход, что и многие другие. Строка 4 продолжает циклически повторять строку (начиная с самой большой), заменяя ее, если найдена.

У SpecBAS есть несколько приятных штрихов к оригинальному ZX / Sinclair BASIC (просмотр списков, поиск символов), которые я до сих пор выясняю.


1

C 205 186 184 байта

Немного другой подход, основанный на состоянии машины. где tнаходится государство.

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]);}

расширенный

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]);
}

Тестовая функция

#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]);
}

Не использовать for(;;*s++){...}вместо того, чтобы do{...}while(*s++);сохранить несколько байтов? Кроме того, вам не нужен символ перевода строки в printf.
Spikatrix

Я думаю, что вы имели в виду for(;*s;s++). Но мне нужно было зацикливаться на этом последнем нулевом символе. Хороший призыв к сохранению \n, который не требуется.
какой-то пользователь

1

С, 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 байт (без импорта)

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

(Извините за интернет-некромантию здесь.)

На платформе Haskell нет поиска строк без импорта, и я хотел показать и использовать тот факт, что искомые строки - это все подстроки одной (без повторений), так что группирование символов может быть выполнено путем определения пар, которым разрешено следовать друг за другом, что fздесь и происходит.

Мне все еще нужен полный список lв конце, чтобы проверить на равенство и отобразить точно так, как требуется, но не будет, если бы задачей было только сообщить количество возможных случаев wordsв любом порядке.


0

Баш - 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\ ;}

Передайте строку в качестве первого аргумента.

bash nmb.sh MBNNBBMNBM 

Объяснил немного:

# 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 байт

(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
 #/

Живая демоверсия и тесты.

Работа проста, но немного странна:

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

Это творчески использует группы, чтобы включить ввод, как:

NBMBM

в

aNBMbcdeBMfghijkl

Следующая строка:

[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
 #/

Заглавные буквы заменяются их текстовыми эквивалентами с соответствующими значениями. Из-за ошибки в rs (я не хотел рисковать, исправляя ее и получая дисквалификацию), пустые последовательности конвертируются в (^^), что заменяется на 0 в строке от второй до последней. Самая последняя строка просто удаляет фунт.


0

KDB (Q), 76 байт

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

объяснение

                                                   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

Тест

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 байта

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

Несколько советов: вы используете pи sтолько один раз, поэтому нет необходимости давать ему имя (-> a#[]=[]:a#"NBM", то же самое для p). Кстати: words"N B M NB BM NBM"вместо списка строк сохраняются дополнительные байты. Это importтолько потому intercalate, что короче, т. Е. Заново внедри его: ...putStrLn.tail.((' ':)=<<)$map...и избавься от import. Поместите всех охранников |в определении #в одну строку и используйте 1<2вместо True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?может быть определена короче со списком понимания: c?t=sum[1|x<-c,x==t]. Опять же , вы используете ?только один раз, так что используйте тело непосредственно: ...show(sum[1|x<-l#[],x==t]).
nimi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.