Ninja e scimmie e orsi, oh mio!


37

Questa sfida è il premio NinjaBearMonkey per aver vinto il mio Block Building Bot Flocks! sfida con l' invio di Black Knight . Congratulazioni NinjaBearMonkey!

La sfida qui è abbastanza semplice, ma ha una varietà di possibili approcci. La storia racconta che nel mondo di Isometric Illusions , ci sono 6 diversi tipi di creature:

  1. Ninja, abbreviata N
  2. Orsi, abbreviati B
  3. Scimmie, abbreviate M
  4. NinjaBears, abbreviato NB
  5. BearMonkeys, abbreviato BM
  6. NinjaBearMonkeys, abbreviato NBM

( NinjaBearMonkey è, ovviamente, l'ultimo, il tipo più potente.)

Il tuo compito è prendere un censimento di queste creature quando sono allineate fianco a fianco, cioè quando le loro stringhe di abbreviazione sono concatenate. L'avvertenza è che devi assicurarti di non contare in eccesso le parti di alcune creature come creature separate che sembrano simili. Le creature si allineeranno in modo tale che:

  • Ogni istanza di NBMè 1 NinjaBearMonkey e 0 altre creature.
  • Qualsiasi istanza di NBnon seguita da Mè 1 NinjaBear e 0 altre creature.
  • Qualsiasi istanza BMnon preceduta da Nè 1 BearMonkey e 0 altre creature.
  • Altrimenti, le istanze di N, Be Msono rispettivamente Ninja, Orsi e Scimmie.

La riga viene letta da sinistra a destra.

Quindi, per esempio, nella linea di creature NBMMBNBNBMci sono 0 Ninja, 1 Orso, 1 Scimmia, 1 NinjaBear, 0 BearMonkeys e 2 NinjaBearMonkeys.

Sfida

Scrivi un programma o una funzione che accetta una stringa di caratteri N, Be M, e stampa o restituisce il numero di ciascuno dei 6 tipi di creature presenti in esso.

L'output dovrebbe avere il modulo

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

con il rispettivo conteggio delle creature sostituendo ogni #segno. Tutti e 6 i conteggi devono essere mostrati, separati da spazi, anche quando sono 0. Tuttavia, possono essere in qualsiasi ordine (ad es. #NBMPotrebbero venire per primi).

Anche:

  • La stringa di input conterrà solo i personaggi N, Be M.
  • Se viene immessa la stringa vuota, tutti i conteggi sono 0.
  • L'output può contenere facoltativamente un singolo spazio iniziale e / o finale e / o una nuova riga finale finale.

Vince l'invio più breve in byte.

Esempi

Ingresso: NB
Uscita:0N 0B 0M 1NB 0BM 0NBM

Ingresso: NBM
Uscita:0N 0B 0M 0NB 0BM 1NBM

Input: NBMMBNBNBM(esempio dall'alto)
Output:0N 1B 1M 1NB 0BM 2NBM

Ingresso: MBNNBBMNBM
Uscita:1N 1B 1M 1NB 1BM 1NBM

Ingresso: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Uscita:17N 6B 14M 5NB 8BM 3NBM


53
Approvo questa sfida.
NinjaBearMonkey il

Solo per confermare: se tutto ciò che avevi erano 2 NinjaBearMonkeys, non puoi formare una linea? Perché non possono stare uno accanto all'altro?
Alan Campbell,

3
@AlanCampbell No. NBMNBMsarebbe un input perfettamente valido. Leggendolo da sinistra a destra ci sono chiaramente 2 NinjaBearMonkeys.
Calvin's Hobbies,

Risposte:


20

Pyth, 22 byte

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

Un modo abbastanza semplice per salvare 1 byte, grazie a @Jakube.


Pyth, 23 byte

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

Dimostrazione.

Stampa in ordine inverso, con uno spazio finale e nessuna nuova riga finale.

.:"NBM")è tutte le sottostringhe, le _mette nel giusto ordine, /zNconta le occorrenze e =:zNdsostituisce sul posto ogni occorrenza della stringa in questione con uno spazio.

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 byte

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

(Ho dovuto solo rispondere a questa domanda.) Passa attraverso ogni sottostringa di NBM, a partire da quelli più lunghi, che hanno la priorità più alta. Cerca ogni occorrenza di quella particolare stringa e la rimuove (in questo caso sostituendola con il conteggio corrente in modo che non venga nuovamente abbinata). Sostituisce infine ogni sottostringa con il conteggio + la stringa.

Questo frammento di stack è scritto nell'equivalente ES5 del codice precedente per semplificare il test da qualsiasi browser. È anche un codice leggermente non golfato. L'interfaccia utente si aggiorna ad ogni pressione di un tasto.

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>


Potresti cambiare la parte regex in 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', dove <newline>s sono newline letterali e 's sono backtick, formando una stringa modello ES6? Salva due byte nella regex ( .non corrisponde alle nuove righe).
wchargin,

@WChargin Purtroppo no, perché l'output deve essere separato da spazio.
NinjaBearMonkey il

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,

Una variante della risposta di Vioz . Divertimento con le rappresentazioni di stringhe in Python 2!

Conta indirettamente le occorrenze della sottostringa dividendola, contando le parti e sottraendo 1. Invece di sostituire le sottostringhe con un simbolo di riempimento, sostituisce la stringa con l'elenco che ha splitprodotto. Quindi, quando prendiamo la sua rappresentazione in stringa, le parti sono separate da spazi e virgole.


5
È folle! Eccellente pazzo, ma pazzo.
Sp3000,

Bel lavoro! Non ci ho pensato :)
Kade,

14

Rubino, 166 80 72 68 caratteri

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

Spiegazione:

  • Il conteggio viene eseguito al contrario. Questo perché i ninja e gli orsi e le scimmie più lunghi hanno la precedenza su quelli più corti.

  • Perché NBM, BMe NB, le sequenze gsub!escono dalla stringa originale con un blocco per contare quante di queste sequenze esistono (sì, la funzione modifica il suo argomento).

    • Tuttavia, essi non possono essere sostituiti con niente, perché altrimenti BNBMMverrebbero contati come NBMe BMinvece di B, NBMe M(perché quando il NBMverrebbe eliminato, metterebbe laB e Minsieme e non ci sarebbe un modo per distinguerlo). Inizialmente ho restituito una singola stringa di caratteri ( .gsub!('NBM'){c+=1;?|}), ma mi sono reso conto che potevo semplicemente restituire il risultato di +=(che è un numero, quindi non può essere nessuno dei N B M).
  • Per M , Be N, posso solo countquanti di essi ci sono nella stringa (non è necessario rimuoverli tramite gsub!). Ora è un ciclo (non so perché non ci ho pensato in primo luogo), quindi questi sono fatti allo stesso modo.


Soluzione simile in struzzo , 54 51 caratteri :

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

Sfortunatamente non è una soluzione valida, in quanto esiste un bug nell'attuale versione di Struzzo (che ora è stata risolta, ma dopo che questa sfida è stata pubblicata).


È possibile salvare 3 caratteri utilizzando la notazione dell'array %w(NBM BM NB M B N)e rimuovendo la divisione.
DickieBoy,

@DickieBoy Questo è in realtà 4 caratteri; Grazie!
Maniglia della porta

Ah sì, il 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],".");}

E con alcune interruzioni di riga:

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

Funziona abbastanza semplicemente. Basta passare sopra i token, sostituendoli con punti e contando fino a quando l'input ne contiene alcuni. Conta prima i più grandi, quindi i più piccoli non sbagliano.

Inizialmente ho provato a sostituire tutto in una volta e contare la differenza di lunghezza, ma ci sono voluti alcuni altri caratteri in questo modo :(


2
Come sviluppatore Java, voglio renderlo più breve e vedere Java vincere per un cambiamento. Dopo averlo fissato per un po ', devo ancora trovare un modo per accorciarlo.
DeadChex,

1
Beh, sicuramente non vincerà in generale. L'attuale leader ha 22 byte e non c'è proprio modo di fare qualcosa di significativo in Java di quelle dimensioni. La mia printlnaffermazione da sola è più grande di così. Sono soddisfatto, però: D
Geobits il

1
Sono un po 'in ritardo ma ho trovato un modo ... String q[]=passa aString[]q=
DeadChex il

1
Bello! Non riesco a credere che mi sia perso, è nella mia lista standard di cose da guardare :)
Geobits,

L'ho scoperto solo dopo aver provato ad entrare in Code Golf come JavaDev, sono abbastanza sorpreso da alcune delle cose che puoi fare
DeadChex,

11

CJam, 36 32 31 byte

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

Grazie a @Optimizer per giocare a golf a 1 byte.

Provalo online nell'interprete CJam .

Come funziona

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*-> `dovrebbe essere sufficiente.
Ottimizzatore,

@Optimize: funziona bene. Grazie.
Dennis,

7

R, 153 134 118

Si è allungato molto rapidamente, ma spero di riuscire a raderne alcuni. L'ingresso è STDIN e l'uscita su STDOUT.

Modifica Cambio di virata. Sbarazzarsi della corda divisa e contare le parti. Ora sostituisco le parti con una stringa una più corta della parte. La differenza tra le lunghezze delle stringhe viene raccolta per l'output.

N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')

Spiegazione

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

Prova

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

jd+Ltl=zc`zd_.:"NBM

Questa è una miscela della soluzione Pyth di @ isaacg e dell'incredibile trucco di @ xnor Python.

Provalo online: cablaggio dimostrativo o di prova

Spiegazione

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 byte

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

Ciò crea una funzione senza nome che accetta una stringa come input e stampa il risultato su STDOUT con un singolo spazio finale e nessuna nuova riga finale. Per chiamarlo, dagli un nome, ad esf=b->... .

Ungolfed + spiegazione:

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

Esempi:

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 byte

Adottare un approccio semplice.

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

Chiama così:

f("NBMMBNBNBM")

L'output è così:

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

È possibile rimuovere lo spazio dopo in.
Isaacg,

In Python 2, puoi convertire in una rappresentazione di stringa 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;

Utilizzo (7 byte aggiunti per 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)

Risultato:

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

È possibile salvare un paio di byte usando cats('s/',z,'/x/')al posto di 's/'||strip(z)||'/x/'.
Alex A.

1
Bello, è stato un bel viaggio di ritorno a 139 :)
Fried Egg,

1
126 byte: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;. Dal momento che stai già leggendo sysparm, puoi anche eseguirlo come un passaggio di dati. E se si esegue in batch, non è necessario run;.
Alex A.

1
Ma potresti ottenere 129 usando una macro di stile moderno che non legge dall'argomento della riga di 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 byte

Non il più breve, ma cos'altro ti aspetteresti da PHP?

Per usarlo, imposta una chiave su un COOKIE, POST, GET, SESSION ...

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

L'apporach è di base:

  • Dividi la stringa nei nomi delle creature
  • Conta quanti elementi ci sono
  • Sottrai 1 (una stringa vuota darebbe un array con 1 elemento)
  • Emetti il ​​conteggio e il nome della creatura
  • Uniscili tutti insieme, usando una stringa vuota (che ridurrà la stringa e rimuoverà l'ultima creatura)

Facile vero?


2

JavaScript, 108 116 byte

Solo un approccio semplice, niente di speciale

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
Non funziona: All 6 counts must be shown, separated by spaces, even when they are 0.. Test case:N
edc65,

@ edc65 Woah. Mi è appena mancata quella parte. Grazie per la segnalazione. Risolto il problema con il costo di 8chars
C5H8NNaO4,

2

Perl, 46

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

Spiegazione su come funziona?
Caino

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$

Utilizza lo stesso approccio di molti altri. La riga 4 continua a scorrere sopra la stringa (dalla prima più grande), sostituendola se trovata.

SpecBAS ha dei bei tocchi sull'originale ZX / Sinclair BASIC (scorrere gli elenchi, trovare i personaggi) che sto ancora scoprendo.


1

C, 205 186 184 byte

Un approccio leggermente diverso basato sulla macchina a stati. dov'è tlo stato.

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

allargato

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

Funzione di test

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

Non utilizzeresti for(;;*s++){...}invece di do{...}while(*s++);salvare alcuni byte? Inoltre, non è necessario il carattere di nuova riga in printf.
Spikatrix,

Penso che volevi dire for(;*s;s++). Ma avevo bisogno di fare un ciclo con l'ultimo carattere null. Buona chiamata per il salvataggio di \n, che non è richiesto.
alcuni utenti il

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 byte (senza importazioni)

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

(Mi dispiace per la negromanzia di Internet qui.)

La piattaforma Haskell non ha la ricerca di stringhe senza importazioni e volevo mostrare e sfruttare il fatto che le stringhe cercate sono tutte sottostringhe di una (senza ripetizioni), in modo che i caratteri di raggruppamento possano essere fatti identificando le coppie che sono autorizzate si susseguono, che è ciò che ffa qui.

Ho ancora bisogno dell'elenco completo lalla fine per verificare l'uguaglianza e visualizzare esattamente come richiesto, ma non lo sarebbe, se la sfida fosse solo quella di riportare il numero di occorrenze del possibile wordsin qualsiasi ordine.


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

Passa la stringa come primo argomento.

bash nmb.sh MBNNBBMNBM 

Spiegato un po ':

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

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

Demo live e test.

Il funzionamento è semplice ma un po 'strano:

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

Questo utilizza in modo creativo gruppi per trasformare input come:

NBMBM

in

aNBMbcdeBMfghijkl

La prossima riga:

[A-Z]+/_

Questo sostituisce le sequenze di lettere maiuscole con caratteri di sottolineatura.

#

Questo inserisce semplicemente un cancelletto all'inizio della riga.

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

Questo è la parte più interessante dell'inizio. Prende fondamentalmente le sequenze di lettere minuscole e caratteri di sottolineatura, le converte in lettere maiuscole, le raggruppa e le mette davanti alla sterlina che è stata inserita. Lo scopo della sterlina è gestire le sequenze che sono già state elaborate.

#

La sterlina viene reinserita all'inizio della riga.

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

Le lettere maiuscole sono sostituite dai loro equivalenti testuali con i conteggi associati. A causa di un bug in rs (non volevo rischiare di risolverlo e di essere squalificato), le sequenze vuote vengono convertite in (^^), che viene sostituito da uno 0 nella penultima riga. L'ultima riga rimuove semplicemente la sterlina.


0

KDB (Q), 76 byte

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

Spiegazione

                                                   l:" "vs"NBM NB BM N B M"     / substrings
                        enlist[x]{y vs" "sv x}\l                                / replace previous substring with space and cut
              -1+count@'                                                        / counter occurrence
       string[                                  ],'                             / string the count and join to substrings
{" "sv                                                                     }    / concatenate with space, put in lambda

Test

q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}"NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM"
"3NBM 5NB 8BM 17N 6B 14M"
q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}""
"0NBM 0NB 0BM 0N 0B 0M"

0

Haskell: 244 byte

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

Alcuni suggerimenti: stai usando pe ssolo una volta, quindi non c'è bisogno di dargli un nome (-> a#[]=[]:a#"NBM", lo stesso per p). A proposito: words"N B M NB BM NBM"invece dell'elenco di stringhe salva byte aggiuntivi. L' importè solo per intercalate, è più breve te nuovamente esecuzione a quest'ultimo: ...putStrLn.tail.((' ':)=<<)$map...e sbarazzarsi della import. Metti tutte le guardie |nella definizione di #in una sola riga e usa 1<2invece di True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?può essere definito più breve con una lista di comprensione: c?t=sum[1|x<-c,x==t]. Anche in questo caso, si utilizza ?solo una volta, in modo da usare il corpo direttamente: ...show(sum[1|x<-l#[],x==t]).
nimi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.