Ninjas y Monos y Osos, ¡Dios mío!


37

¡Este desafío es el premio de NinjaBearMonkey por ganar mis bloques de bloques de construcción! desafío con la presentación del Caballero Negro . ¡Felicidades NinjaBearMonkey!

El desafío aquí es bastante simple, pero tiene una variedad de enfoques posibles. La historia cuenta que en el mundo de las ilusiones isométricas , hay 6 tipos diferentes de criaturas:

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

( NinjaBearMonkey es, por supuesto, el último tipo más poderoso).

Su tarea es hacer un censo de estas criaturas cuando están alineadas una al lado de la otra, es decir, cuando sus cadenas de abreviatura están concatenadas. La advertencia es que debes asegurarte de no contar en exceso las partes de algunas criaturas como criaturas separadas que parecen similares. Las criaturas se alinearán de manera que:

  • Cualquier instancia de NBMes 1 NinjaBearMonkey y 0 otras criaturas.
  • Cualquier instancia de NBno seguido Mes 1 NinjaBear y 0 otras criaturas.
  • Cualquier instancia de BMno precedida Nes 1 BearMonkey y 0 otras criaturas.
  • De lo contrario, las instancias de N, By Mson Ninjas, Osos y Monos solteros respectivamente.

La línea se lee de izquierda a derecha.

Entonces, por ejemplo, en la línea de criaturas NBMMBNBNBM, hay 0 Ninjas, 1 Oso, 1 Mono, 1 NinjaBear, 0 BearMonkeys y 2 NinjaBearMonkeys.

Reto

Escriba un programa o función que tome una cadena de caracteres N,, By M, e imprima o devuelva cuántos de cada uno de los 6 tipos de criaturas están presentes en él.

La salida debe tener la forma

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

con el respectivo conteo de criaturas reemplazando cada #signo. Se deben mostrar los 6 recuentos, separados por espacios, incluso cuando son 0. Sin embargo, pueden estar en cualquier orden (p. Ej., #NBMPodrían aparecer primero).

También:

  • La cadena de entrada sólo contendrá los caracteres N, By M.
  • Si se ingresa la cadena vacía, todos los recuentos son 0.
  • La salida puede contener opcionalmente un único espacio inicial y / o final, y / o una nueva línea final.

La presentación más corta en bytes gana.

Ejemplos

Entrada: NB
Salida:0N 0B 0M 1NB 0BM 0NBM

Entrada: NBM
Salida:0N 0B 0M 0NB 0BM 1NBM

Entrada: NBMMBNBNBM(ejemplo de arriba)
Salida:0N 1B 1M 1NB 0BM 2NBM

Entrada: MBNNBBMNBM
Salida:1N 1B 1M 1NB 1BM 1NBM

Entrada: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Salida:17N 6B 14M 5NB 8BM 3NBM


53
Apruebo este desafío.
NinjaBearMonkey

Solo para confirmar: si todo lo que tenía eran 2 NinjaBearMonkeys, ¿no puede formar una línea? ¿Porque no pueden pararse uno al lado del otro?
Alan Campbell

3
@AlanCampbell No. NBMNBMsería una entrada perfectamente válida. Leyendo de izquierda a derecha, claramente hay 2 NinjaBearMonkeys.
Aficiones de Calvin

Respuestas:


20

Pyth, 22 bytes

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

Manera bastante hacker de ahorrar 1 byte, gracias a @Jakube.


Pyth, 23 bytes

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

Demostración.

Imprime en orden inverso, con un espacio final y sin nueva línea final.

.:"NBM")es todas las subcadenas, las _coloca en el orden correcto, /zNcuenta las ocurrencias y =:zNdsustituye en el lugar cada ocurrencia de la cadena en cuestión con un espacio.

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)

(Solo tenía que responder esto.) Pasa por cada subcadena de NBM, comenzando por las más largas, que tienen mayor prioridad. Busca cada aparición de esa cadena en particular y la elimina (en este caso, reemplazándola con el recuento actual para que no vuelva a coincidir). Finalmente reemplaza cada subcadena con el recuento + la cadena.

Este fragmento de pila está escrito en el equivalente ES5 del código anterior para facilitar la prueba desde cualquier navegador. También es un código ligeramente sin golf. La interfaz de usuario se actualiza con cada pulsación 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>


¿Podría cambiar la parte regex a 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', donde las <newline>s son líneas nuevas literales y las 's son backticks, formando una cadena de plantilla ES6? Guarda dos bytes en la expresión regular ( .no coincide con las nuevas líneas).
wchargin

@WChargin Desafortunadamente, no, porque la salida debe estar separada por espacios.
NinjaBearMonkey

17

Pitón 2, 78

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

Una variante de la respuesta de Vioz . ¡Diversión con representaciones de cuerdas de Python 2!

Cuenta las ocurrencias de la subcadena indirectamente dividiéndola, contando las partes y restando 1. En lugar de reemplazar las subcadenas por un símbolo de relleno, reemplaza la cadena por la lista que splitprodujo. Luego, cuando tomamos su representación de cadena, las partes están separadas por espacios y comas.


55
¡Eso es una locura! Excelentemente loco, pero aún loco.
Sp3000

¡Buen trabajo! No pensé en eso :)
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}*' '}

Explicación:

  • El recuento se realiza a la inversa. Esto se debe a que los ninjas, osos y monos más largos tienen prioridad sobre los más cortos.

  • Para NBM, BMy NB, las secuencias están gsub!fuera de la cadena original con un bloque para contar cuántas de estas secuencias existen (sí, la función modifica su argumento).

    • Sin embargo, no se pueden reemplazar con nada, ya que de BNBMMlo contrario se contarían como NBMy en BMlugar de B, NBMy M(porque cuando NBMse eliminen, se juntarán By Mno habrá forma de distinguirlo). Originalmente devolví una cadena de caracteres única (.gsub!('NBM'){c+=1;?|} ), pero me di cuenta de que podía devolver el resultado de +=(que es un número, por lo que no puede ser ninguno N B M).
  • Para M, ByN , puedo saber countcuántos de ellos hay en la cadena (no es necesario eliminarlos a través de gsub!). Ahora es un bucle (no sé por qué no pensé en eso en primer lugar), por lo que se hacen de la misma manera.


Solución similar en Avestruz , 54 51 caracteres :

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

Desafortunadamente, no es una solución válida, ya que hay un error en la versión actual de Avestruz (que ahora está solucionado, pero después de que se publicó este desafío).


Puede guardar 3 caracteres utilizando la notación de matriz %w(NBM BM NB M B N)y eliminando la división.
DickieBoy

@DickieBoy Eso es en realidad 4 caracteres; ¡Gracias!
Pomo de la puerta

Ah si, el punto!
DickieBoy

14

Java, 166 162

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

Y con algunos saltos de línea:

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 bastante simple. Simplemente recorra los tokens, reemplazándolos con puntos y contando siempre que la entrada contenga algunos. Cuenta los grandes primero, para que los pequeños no lo estropeen.

Originalmente intenté reemplazar todo de una vez y contar la diferencia en la longitud, pero de esa manera se necesitaron algunos caracteres más :(


2
Como desarrollador de Java, quiero acortar esto y ver que Java gana para variar. Después de mirarlo por un tiempo, todavía tengo que encontrar una manera de acortarlo.
DeadChex

1
Bueno, definitivamente no va a ganar en general. El líder actual es de 22 bytes y simplemente no hay forma de hacer nada significativo en Java en ese tamaño. Mi printlndeclaración sola es más grande que eso. Sin embargo, estoy satisfecho con eso: D
Geobits

1
Llegué un poco tarde pero encontré una forma ... cambiar String q[]=aString[]q=
DeadChex

1
¡Agradable! No puedo creer que me perdí eso, está en mi lista estándar de cosas para mirar :)
Geobits

Solo lo descubrí después de intentar ingresar a Code Golf como JavaDev, estoy bastante sorprendido por algunas de las cosas que puedes hacer
DeadChex

11

CJam, 36 32 31 bytes

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

Gracias a @Optimizer por jugar golf en 1 byte.

Pruébelo en línea en el intérprete de CJam .

Cómo 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*->` debería ser suficiente.
Optimizador

@Optimize: Eso funciona bien. Gracias.
Dennis

7

R, 153 134 118

Esto se alargó muy rápido, pero espero poder afeitarme algunos. La entrada es STDIN y la salida a STDOUT.

Editar cambio de táctica. Se deshizo de la cadena dividida y contando las partes. Ahora reemplazo las partes con una cuerda más corta que la parte. La diferencia entre las longitudes de cadena se recopila para la salida.

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

Explicación

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

Prueba de funcionamiento

> 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 bytes

jd+Ltl=zc`zd_.:"NBM

Esta es una mezcla de la solución Pyth de @ isaacg y el increíble truco de Python de @ xnor.

Pruébelo en línea: demostración o prueba de arnés

Explicación

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

Esto crea una función sin nombre que toma una cadena como entrada e imprime el resultado en STDOUT con un solo espacio final y sin nueva línea final. Para llamarlo, asígnele un nombre, p. Ej.f=b->... .

Ungolfed + explicación:

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

Ejemplos:

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

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

4

Pitón 2, 93 88 89 84 Bytes

Tomando el enfoque directo.

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

Llame así:

f("NBMMBNBNBM")

La salida es así:

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

Puede eliminar el espacio después in.
isaacg

En Python 2, puede convertir a una representación de cadena con `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;

Uso (7 bytes agregados para 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

o

%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

Puede guardar un par de bytes cats('s/',z,'/x/')en lugar de 's/'||strip(z)||'/x/'.
Alex A.

1
Bien, eso fue un viaje de regreso a 139 :)
Fried Egg

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

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;. Como ya estás leyendo sysparm, también puedes ejecutarlo como un paso de datos. Y si está ejecutando en lote, no necesita run;.
Alex A.

1
Pero podría obtener 129 utilizando una macro de estilo moderno que no lea el argumento de la línea 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

No es el más corto, pero ¿qué más esperarías de PHP?

Para usarlo, configure una clave en una COOKIE, POST, GET, SESSION ...

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

El apporach es básico:

  • Divide la cadena en los nombres de las criaturas.
  • Cuenta cuántos elementos hay
  • Restar 1 (una cadena vacía daría una matriz con 1 elemento)
  • Salida del recuento y el nombre de la criatura
  • Une todo junto, usando una cadena vacía (que reducirá la cadena y eliminará la última criatura)

Fácil, verdad?


2

JavaScript, 108 116 bytes

Solo un enfoque directo, nada lujoso

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
No funciona: All 6 counts must be shown, separated by spaces, even when they are 0.. Caso de prueba:N
edc65

@ edc65 Woah. Acabo de perder esa parte. Gracias por señalar eso. Se arregló por el costo de 8 caracteres
C5H8NNaO4

2

Perl, 46

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

¿Explicación sobre cómo funciona esto?
Caín

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$

Utiliza el mismo enfoque que muchos otros. La línea 4 sigue girando sobre la cadena (desde la más grande primero), la reemplaza si se encuentra.

SpecBAS tiene algunos toques agradables sobre ZX / Sinclair BASIC original (recorrer listas, encontrar personajes) que todavía estoy descubriendo.


1

C, 205 186 184 bytes

Un enfoque un poco diferente basado en la máquina de estados. donde testa el 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]);
}

Función de prueba

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

¿No usaría en for(;;*s++){...}lugar de do{...}while(*s++);guardar algunos bytes? Además, no necesita el carácter de nueva línea en el printf.
Spikatrix

Creo que quisiste decir for(;*s;s++). Pero necesitaba un bucle con ese último personaje nulo. Buena llamada para guardar el \n, que no es obligatorio.
algún usuario

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 (sin importaciones)

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

(Perdón por la nigromancia de Internet aquí).

La plataforma Haskell no tiene búsqueda de cadenas sin importaciones, y quería mostrar y explotar el hecho de que las cadenas buscadas son todas las subcadenas de una (sin repeticiones), por lo que la agrupación de caracteres se puede hacer mediante la identificación de pares que están permitidos seguirse, que es lo que fhace aquí.

Todavía necesito la lista completa lal final para verificar la igualdad y mostrar exactamente como se requiere, pero no lo haría, si el desafío hubiera sido informar el número de ocurrencias posibles wordsen cualquier orden.


0

Golpe - 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\ ;}

Pase la cadena como primer argumento.

bash nmb.sh MBNNBBMNBM 

Explicado un poco:

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

Demostración en vivo y pruebas.

El funcionamiento es simple pero un poco extraño:

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

Esto utiliza creativamente grupos para activar entradas como:

NBMBM

dentro

aNBMbcdeBMfghijkl

La proxima linea:

[A-Z]+/_

Esto reemplaza las secuencias de letras mayúsculas con guiones bajos.

#

Esto simplemente inserta un signo de libra al comienzo de la línea.

+(#.*?)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 es la parte inicial genial. Básicamente toma las secuencias de letras minúsculas y guiones bajos, las convierte en letras mayúsculas, las agrupa y las coloca antes de la libra que se insertó. El propósito de la libra es administrar las secuencias que ya han sido procesadas.

#

La libra se vuelve a insertar al comienzo de la línea.

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

Las letras mayúsculas se reemplazan por sus equivalentes de texto con los recuentos asociados. Debido a un error en rs (no quería arriesgarme a arreglarlo y descalificarme), las secuencias vacías se convierten en (^^), que se reemplaza por un 0 en la penúltima línea. La última línea simplemente elimina la 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"}

Explicación

                                                   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

Prueba

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

Algunas sugerencias: está utilizando py ssolo una vez, por lo que no es necesario darle un nombre (-> a#[]=[]:a#"NBM", lo mismo para p). Por cierto: en words"N B M NB BM NBM"lugar de la lista de cadenas guarda bytes adicionales. El importes sólo para intercalate, que es más corto te ejecutarla de nuevo: ...putStrLn.tail.((' ':)=<<)$map...y deshacerse de los import. Ponga a todos los guardias |en la definición de #en una sola línea y use en 1<2lugar de True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?se puede definir más corto con una lista por comprensión: c?t=sum[1|x<-c,x==t]. Una vez más, se está utilizando ?sólo una vez, a fin de utilizar el cuerpo directamente: ...show(sum[1|x<-l#[],x==t]).
nimi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.