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


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.

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>


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.


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).


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 :(


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.

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 
> 

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

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 

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

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

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é?


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

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

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.


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

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

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.


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

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.


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"

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.