Ninjas e Macacos e Ursos, Oh Meu!

37

Esse desafio é o prêmio de NinjaBearMonkey por ganhar meus blocos de construção de blocos de blocos! desafio com a finalização do Cavaleiro Negro . Parabéns NinjaBearMonkey!

O desafio aqui é bastante simples, mas tem uma variedade de abordagens possíveis. A história diz que, no mundo das Ilusões Isométricas , existem 6 tipos diferentes de criaturas:

  1. Ninjas, abreviado N
  2. Ursos, abreviados B
  3. Macacos, abreviados M
  4. NinjaBears, abreviado NB
  5. BearMonkeys, abreviado BM
  6. NinjaBearMonkeys, abreviado NBM

( NinjaBearMonkey é, obviamente, o último e mais poderoso tipo.)

Sua tarefa é fazer um censo dessas criaturas quando elas estão alinhadas lado a lado, ou seja, quando suas cadeias de abreviação são concatenadas. A ressalva é que você precisa se certificar de não contar demais as partes de algumas criaturas como criaturas separadas que parecem semelhantes. As criaturas se alinharão de tal forma que:

  • Qualquer instância de NBMé 1 NinjaBearMonkey e 0 outras criaturas.
  • Qualquer instância de NBnão seguido por M1 NinjaBear e 0 outras criaturas.
  • Qualquer instância BMnão precedida por Né 1 BearMonkey e 0 outras criaturas.
  • Caso contrário, as instâncias de N, Be Msão Ninjas, Ursos e Macacos únicos, respectivamente.

A linha é lida da esquerda para a direita.

Assim, por exemplo, na linha de criaturas NBMMBNBNBM, existem 0 Ninjas, 1 Urso, 1 Macaco, 1 NinjaBear, 0 BearMonkeys e 2 NinjaBearMonkeys.

Desafio

Escreva um programa ou função que recebe de uma série de personagens N, B, e Me impressões ou retornos quantos de cada um dos 6 tipos de criaturas estão presentes nele.

A saída deve ter o formato

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

com a respectiva contagem de criaturas substituindo cada #sinal. Todas as 6 contagens devem ser exibidas, separadas por espaços, mesmo quando são 0. No entanto, elas podem estar em qualquer ordem (por exemplo, #NBMpode vir primeiro).

Além disso:

  • A cadeia de entrada irá conter apenas os personagens N, Be M.
  • Se a sequência vazia for inserida, todas as contagens serão 0.
  • A saída pode opcionalmente conter um único espaço à esquerda e / ou à direita e / ou uma nova linha à direita.

O menor envio em bytes vence.

Exemplos

Entrada: NB
Saída:0N 0B 0M 1NB 0BM 0NBM

Entrada: NBM
Saída:0N 0B 0M 0NB 0BM 1NBM

Entrada: NBMMBNBNBM(exemplo acima)
Saída:0N 1B 1M 1NB 0BM 2NBM

Entrada: MBNNBBMNBM
Saída:1N 1B 1M 1NB 1BM 1NBM

Entrada: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Saída:17N 6B 14M 5NB 8BM 3NBM

Passatempos de Calvin
fonte
53
Eu aprovo esse desafio.
NinjaBearMonkey 18/06
Só para confirmar: se tudo o que você tinha era 2 NinjaBearMonkeys, você não pode formar uma linha? Porque eles não podem ficar próximos um do outro?
Alan Campbell
3
@AlanCampbell No. NBMNBMseria uma entrada perfeitamente válida. Lendo da esquerda para a direita, existem claramente 2 NinjaBearMonkeys.
Passatempos de Calvin

Respostas:

20

Pitão, 22 bytes

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

Maneira bastante hackish de economizar 1 byte, graças a @Jakube.


Pitão, 23 bytes

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

Demonstração.

Imprime na ordem inversa, com um espaço à direita e sem nova linha à direita.

.:"NBM")é todas as substrings, _coloca-as na ordem correta, /zNconta as ocorrências e =:zNdno local substitui cada ocorrência da sequência em questão por um espaço.

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.
isaacg
fonte
23

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)

(Eu apenas tive que responder a isso.) Ele passa por cada substring de NBM, começando pelos mais longos, que têm maior prioridade. Ele procura cada ocorrência dessa sequência específica e a remove (nesse caso, substituindo-a pela contagem atual para que não seja correspondida novamente). Finalmente, substitui cada substring pela contagem + a string.

Esse snippet de pilha está escrito no equivalente do código acima ES5 para facilitar o teste em qualquer navegador. Também é um código ligeiramente não-destruído. A interface do usuário é atualizada a cada pressionamento de tecla.

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>

NinjaBearMonkey
fonte
Você poderia alterar a parte do regex para 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', onde <newline>s são novas linhas literais e 's são backticks, formando uma sequência de modelos ES6? Salva dois bytes no regex ( .não corresponde a novas linhas).
wchargin
@WChargin Infelizmente, não, porque a saída deve ser separada por espaço.
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,

Uma variante da resposta de Vioz . Diversão com representações de string em Python 2!

Conta as ocorrências da substring indiretamente, dividindo-as, contando as partes e subtraindo 1. Em vez de substituir as substrings por um símbolo de preenchimento, substitui a string pela lista que foi splitproduzida. Então, quando tomamos sua representação de string, as partes são separadas por espaços e vírgulas.

xnor
fonte
5
Isso é insano! Excelentemente insano, mas ainda insano.
SP3000
Bom trabalho! Não tinha pensado nisso :)
Kade
14

Ruby, 166 80 72 68 caracteres

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

Explicação:

  • A contagem é feita ao contrário. Isso ocorre porque os ninjas, ursos e macacos mais longos têm precedência sobre os mais curtos.

  • Para NBM,, BMe NB, as seqüências estão gsub!fora da string original com um bloco para contar quantas dessas sequências existem (sim, a função modifica seu argumento).

    • No entanto, eles não podem ser substituídos com nada, pois caso contrário BNBMMseria contado como NBMe BMem vez de B, NBMe M(porque quando o NBMseria removido, ele iria colocar o Be Mjuntos e não haveria uma maneira de distingui-lo). Originalmente, retornei uma única sequência de caracteres ( .gsub!('NBM'){c+=1;?|}), mas percebi que poderia retornar o resultado de +=(que é um número, portanto não pode ser nenhum N B M).
  • Para M,, Be N, posso countsaber quantos deles existem na cadeia de caracteres (não é necessário removê-los via gsub!). Agora é um loop (não sei por que não pensei nisso em primeiro lugar), então isso é feito da mesma maneira.


Solução semelhante em Avestruz , 54 51 caracteres :

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

Infelizmente, não é uma solução válida, pois há um erro na versão atual do Avestruz (que agora está corrigida, mas depois que esse desafio foi lançado).

Maçaneta da porta
fonte
Você pode salvar três caracteres usando a notação de matriz %w(NBM BM NB M B N)e removendo a divisão.
DickieBoy
@DickieBoy Na verdade, são 4 caracteres; obrigado!
Maçaneta
Ah sim, o ponto!
DickieBoy 18/06
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],".");}

E com algumas quebras de linha:

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

Funciona de maneira bem simples. Basta fazer um loop sobre os tokens, substituindo-os por pontos e contando enquanto a entrada contiver alguns. Conta os grandes primeiro, para que os pequenos não estraguem tudo.

Inicialmente, tentei substituir tudo de uma vez e contar a diferença de tamanho, mas foram necessários mais alguns caracteres dessa maneira :(

Geobits
fonte
2
Como desenvolvedor Java, quero tornar isso mais curto e ver o Java vencer por uma mudança. Depois de encará-lo por um tempo, ainda não encontrei uma maneira de reduzi-lo.
23815 DeadChex
11
Bem, definitivamente não vai ganhar no geral. O líder atual tem 22 bytes e simplesmente não há como fazer algo significativo em Java nesse tamanho. Minha printlnafirmação sozinha é maior que isso. Estou satisfeito com isso, no entanto: D
Geobits
11
Eu sou um pouco tarde, mas eu encontrei uma maneira ... mudança String q[]=paraString[]q=
DeadChex
11
Agradável! Não posso acreditar que eu perdi isso, é na minha lista padrão de coisas para olhar :)
Geobits
Eu só descobri-lo depois de tentar entrar em Código Golf como um JavaDev, estou bastante surpreendido com algumas das coisas que você pode fazer
DeadChex
11

CJam, 36 32 31 bytes

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

Agradecimentos ao @Optimizer por jogar fora 1 byte.

Experimente online no intérprete CJam .

Como funciona

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.
Dennis
fonte
N*-> `deve ser suficiente.
Optimizer
@ Optimizar: Isso funciona bem. Obrigado.
Dennis
7

R, 153 134 118

Isso ficou muito mais rápido, mas espero poder raspar alguns. A entrada é STDIN e a saída para STDOUT.

Editar Alteração de aderência. Livre-se da corda dividida e da contagem de peças. Agora substituo as peças por uma corda mais curta que a peça. A diferença entre os comprimentos de sequência é coletada para saída.

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

Explicação

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

Execução de teste

> 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 
> 
MickyT
fonte
7

Pitão, 19 bytes

jd+Ltl=zc`zd_.:"NBM

Esta é uma mistura da solução Pyth do @ isaacg e do incrível truque do Python do @ xnor.

Experimente on-line: demonstração ou equipamento de teste

Explicação

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
Jakube
fonte
6

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

Isso cria uma função sem nome que recebe uma string como entrada e imprime o resultado em STDOUT com um único espaço à direita e sem uma nova linha à direita. Para chamá-lo, dê um nome, por exemplo f=b->....

Ungolfed + explicação:

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

Exemplos:

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

julia> f("NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM")
3NBM 8BM 5NB 14M 6B 17N 
Alex A.
fonte
4

Python 2, 93 88 89 84 Bytes

Adotando a abordagem direta.

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

Ligue assim:

f("NBMMBNBNBM")

A saída é assim:

2NBM 0BM 1NB 1M 1B 0N
Kade
fonte
Você pode remover o espaço depois in.
Isaacg
No Python 2, você pode converter em uma representação de string com `x`.
xnor
4

SAS, 142 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;

Uso (7 bytes adicionados ao 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

ou

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

Uso:

data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)

Resultado:

3NBM 5NB 8BM 17N 6B 14M
Ovo frito
fonte
Você pode salvar alguns bytes usando cats('s/',z,'/x/')no lugar de 's/'||strip(z)||'/x/'.
Alex A.
11
Bom, isso foi um grande viagem de volta a 139 :)
Ovo frito
11
126 bytes: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.
11
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;. Como você já está lendo sysparm, é melhor executá-lo como uma etapa de dados. E se você estiver executando em lote, não precisará run;.
Alex A.
11
Mas você pode obter 129 usando um estilo macro moderno, que não lê a partir do argumento de linha de comando:%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 bytes

Não é o mais curto, mas o que mais você esperaria do PHP?

Para usá-lo, defina uma chave em COOKIE, POST, GET, SESSION ...

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

O apporach é básico:

  • Divida a corda nos nomes das criaturas
  • Conte quantos elementos existem
  • Subtrair 1 (uma sequência vazia daria uma matriz com 1 elemento)
  • Gera a contagem e o nome da criatura
  • Junte tudo isso, usando uma corda vazia (o que reduzirá a corda e removerá a última criatura)

Fácil né?

Ismael Miguel
fonte
2

JavaScript, 108 116 bytes

Apenas uma abordagem direta, nada extravagante

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);
C5H8NNaO4
fonte
11
Não funciona: All 6 counts must be shown, separated by spaces, even when they are 0.. Caso de teste:N
edc65 18/06/2015
@ edc65 Woah. Eu apenas perdi essa parte. Obrigado por apontar isso. Fixa-lo para o custo de 8chars
C5H8NNaO4
2

Perl, 46

#!perl -p
$_="NBM BM NB M B N"=~s/\w+/~~s!$&!x!g.$&/ger
nutki
fonte
Explicação sobre como isso funciona?
Caim
1

EspecificaçõesBAS - 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$

Usa a mesma abordagem que muitas outras. A linha 4 continua fazendo loop sobre a string (da maior primeira), substituindo-a se encontrada.

O SpecBAS tem alguns toques legais sobre o ZX / Sinclair BASIC original (percorrendo listas, encontrando caracteres) que ainda estou descobrindo.

Brian
fonte
1

C, 205 186 184 bytes

Uma abordagem um pouco diferente baseada na máquina de estado. onde tfica o estado

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

Expandido

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

Função de teste

#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]);
}
algum usuário
fonte
Não usaria em for(;;*s++){...}vez de do{...}while(*s++);salvar alguns bytes? Além disso, você não precisa do caractere de nova linha no printf.
Spikatrix
Eu acho que você quis dizer for(;*s;s++). Mas eu precisava fazer um loop com esse último caractere nulo. Boa chamada para salvar o \nque não é necessário.
algum usuário
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]);
}  
edc65
fonte
1

Haskell - 177 bytes (sem importações)

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

(Desculpe pela necromancia da internet aqui.)

A Plataforma Haskell não possui pesquisa de strings sem importações, e eu queria mostrar e explorar o fato de que as strings pesquisadas são todas substrings de uma (sem repetições), para que o agrupamento de caracteres possa ser feito através da identificação de pares que têm permissão para seguem um ao outro, que é o que ffaz aqui.

No final, ainda preciso da lista completa lpara verificar a igualdade e exibir exatamente como necessário, mas não teria, se o desafio fosse apenas relatar o número de ocorrências possíveis wordsem qualquer ordem.

Leif Willerts
fonte
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\ ;}

Passe a string como o primeiro argumento.

bash nmb.sh MBNNBBMNBM 

Explicou um pouco:

# 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
Daniel Wakefield
fonte
0

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

Demonstração e testes ao vivo.

O funcionamento é simples, mas um pouco estranho:

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

Isso usa criativamente grupos para ativar entradas como:

NBMBM

para dentro

aNBMbcdeBMfghijkl

A próxima linha:

[A-Z]+/_

Isso substitui as seqüências de letras maiúsculas por sublinhados.

#

Isso simplesmente insere um sinal de libra no início da linha.

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

Esta é a parte legal do começo. Basicamente, pega as seqüências de letras minúsculas e sublinhados, converte-as em letras maiúsculas, agrupa-as e as coloca antes da libra que foi inserida. O objetivo da libra é gerenciar as seqüências que já foram processadas.

#

A libra é reinserida no início da linha.

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

As letras maiúsculas são substituídas por seus equivalentes de texto pelas contagens associadas. Por causa de um bug no rs (eu não queria arriscar corrigi-lo e ser desqualificado), as seqüências vazias são convertidas em (^^), que são substituídas por um 0 na penúltima linha. A última linha simplesmente remove a libra.

kirbyfan64sos
fonte
0

KDB (Q), 76 bytes

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

Explicação

                                                   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

Teste

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"
WooiKent Lee
fonte
0

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
Jeremy List
fonte
Algumas sugestões: você está usando pe sapenas uma vez, portanto não há necessidade de dar um nome (-> a#[]=[]:a#"NBM", o mesmo para p). BTW: em words"N B M NB BM NBM"vez da lista de cadeias salva bytes adicionais. O importé apenas para intercalate, é mais curto para reimplementá-lo:...putStrLn.tail.((' ':)=<<)$map... e se livrar do import. Coloque todos os guardas |na definição de #em uma única linha e use em 1<2vez de True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi
... ?pode ser definido mais curto com uma compreensão da lista: c?t=sum[1|x<-c,x==t]. Mais uma vez, você está usando ?apenas uma vez, por isso use o corpo diretamente: ...show(sum[1|x<-l#[],x==t]).
nimi