Ninjas und Affen und Bären, oh mein Gott!


37

Diese Herausforderung ist NinjaBearMonkeys Preis für den Gewinn meiner Block Building Bot Flocks! Herausforderung mit dem Black Knight Submission. Glückwunsch NinjaBearMonkey!

Die Herausforderung ist hier relativ einfach, es gibt jedoch eine Vielzahl möglicher Ansätze. Die Geschichte besagt, dass es in der Welt der isometrischen Illusionen 6 verschiedene Arten von Kreaturen gibt:

  1. Ninjas, abgekürzt N
  2. Bären, abgekürzt B
  3. Affen, abgekürzt M
  4. NinjaBears, abgekürzt NB
  5. BearMonkeys, abgekürzt BM
  6. NinjaBearMonkeys, abgekürzt NBM

( NinjaBearMonkey ist natürlich der letzte, mächtigste Typ.)

Ihre Aufgabe ist es, eine Zählung dieser Kreaturen durchzuführen, wenn sie nebeneinander aufgereiht sind, dh wenn ihre Abkürzungszeichenfolgen verkettet sind. Die Einschränkung ist, dass Sie darauf achten müssen, die Teile einiger Kreaturen nicht als separate Kreaturen zu überzählen, die zufällig ähnlich aussehen. Die Kreaturen richten sich so aus, dass:

  • Jede Instanz von NBMist 1 NinjaBearMonkey und 0 andere Kreaturen.
  • Jede Instanz von NBnicht gefolgt von Mist 1 NinjaBear und 0 andere Kreaturen.
  • Jede Instanz von, der BMkeine vorangestellt Nist, ist 1 BearMonkey und 0 andere Kreaturen.
  • Andernfalls sind Instanzen von N, Bund Meinzelne Ninjas, Bären bzw. Affen.

Die Zeile wird von links nach rechts gelesen.

So gibt es zum Beispiel in der Reihe der Kreaturen NBMMBNBNBM0 Ninjas, 1 Bär, 1 Affe, 1 NinjaBär, 0 BearMonkeys und 2 NinjaBearMonkeys.

Herausforderung

Schreiben Sie ein Programm oder eine Funktion , die in einer Reihe von Zeichen nimmt N, Bund M, und druckt oder gibt , wie viele von jedem der sechs Arten von Lebewesen in ihm vorhanden sind.

Die Ausgabe sollte die Form haben

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

wobei die jeweilige Kreaturenzahl jedes #Zeichen ersetzt. Alle 6 Zählungen müssen durch Leerzeichen getrennt angezeigt werden, auch wenn sie 0 sind. Sie können jedoch in beliebiger Reihenfolge angegeben werden (z. B. #NBMkönnen sie an erster Stelle stehen).

Ebenfalls:

  • Die Eingabezeichenfolge enthält nur die Zeichen N, Bund M.
  • Wenn die leere Zeichenfolge eingegeben wird, sind alle Zählwerte 0.
  • Die Ausgabe kann optional ein einzelnes führendes und / oder nachfolgendes Leerzeichen und / oder eine einzelne nachfolgende Newline enthalten.

Die kürzeste Übermittlung in Bytes gewinnt.

Beispiele

Eingabe: NB
Ausgabe:0N 0B 0M 1NB 0BM 0NBM

Eingabe: NBM
Ausgabe:0N 0B 0M 0NB 0BM 1NBM

Eingabe: NBMMBNBNBM(Beispiel von oben)
Ausgabe:0N 1B 1M 1NB 0BM 2NBM

Eingabe: MBNNBBMNBM
Ausgabe:1N 1B 1M 1NB 1BM 1NBM

Eingabe: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Ausgabe:17N 6B 14M 5NB 8BM 3NBM


53
Ich stimme dieser Herausforderung zu.
NinjaBearMonkey

Nur zur Bestätigung: Wenn Sie nur 2 NinjaBearMonkeys hatten, können Sie keine Linie bilden? Weil sie nicht nebeneinander stehen können?
Alan Campbell

3
@ AlanCampbell No. NBMNBMwäre eine völlig gültige Eingabe. Beim Lesen von links nach rechts gibt es eindeutig 2 NinjaBearMonkeys.
Calvins Hobbys

Antworten:


20

Pyth, 22 Bytes

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

Ein ziemlich hackiger Weg, um 1 Byte zu sparen, dank @Jakube.


Pyth, 23 Bytes

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

Demonstration.

Druckt in umgekehrter Reihenfolge mit einem Leerzeichen und ohne Zeilenumbruch.

.:"NBM")Sind alle Teilzeichenfolgen vorhanden, werden _sie in die richtige Reihenfolge gebracht, /zNVorkommen gezählt und =:zNdan Ort und Stelle durch ein Leerzeichen ersetzt.

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)

(Ich musste das nur beantworten.) Es durchläuft jeden Teilstring von NBM, beginnend mit den längeren, die eine höhere Priorität haben. Es sucht nach jedem Vorkommen dieser bestimmten Zeichenfolge und entfernt sie (in diesem Fall wird sie durch die aktuelle Anzahl ersetzt, damit sie nicht erneut abgeglichen wird). Schließlich wird jede Teilzeichenfolge durch die Anzahl + die Zeichenfolge ersetzt.

Dieses Stack-Snippet ist in der ES5-Entsprechung des obigen Codes geschrieben, um das Testen in jedem Browser zu vereinfachen. Es ist auch etwas ungolfed Code. Die Benutzeroberfläche wird bei jedem Tastendruck aktualisiert.

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>


Könnten Sie den Regex-Teil in ändern 'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)', in dem das <newline>s wörtliche Zeilenumbrüche und das 's Backticks sind und eine ES6-Vorlagenzeichenfolge bilden? Speichert zwei Bytes im .regulären Ausdruck ( entspricht nicht den Zeilenumbrüchen).
wchargin

@WChargin Leider nein, da die Ausgabe durch Leerzeichen getrennt sein muss.
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,

Eine Variante der Antwort von Vioz . Spaß mit Python 2-Zeichenfolgendarstellungen!

Zählt Vorkommen des Teilstrings indirekt, indem es aufgeteilt, die Teile gezählt und 1 subtrahiert wird. Anstatt die Teilstrings durch ein Füllersymbol zu ersetzen, wird der String durch die spliterzeugte Liste ersetzt . Wenn wir dann die Zeichenfolgendarstellung nehmen, werden die Teile durch Leerzeichen und Kommas getrennt.


5
Das ist verrückt! Hervorragend verrückt, aber immer noch verrückt.
Sp3000,

Gute Arbeit! Habe nicht daran gedacht :)
Kade

14

Ruby, 166 80 72 68 Zeichen

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

Erläuterung:

  • Die Zählung erfolgt in umgekehrter Reihenfolge. Dies liegt daran, dass die längeren Ninjas, Bären und Affen Vorrang vor den kürzeren haben.

  • Für NBM, BMund NBsind die Sequenzen gsub!außerhalb des ursprünglichen Strings mit einem Block versehen, um zu zählen, wie viele dieser Sequenzen existieren (ja, die Funktion ändert ihr Argument).

    • Sie können jedoch nicht durch nichts ersetzt werden, da sonst BNBMMwürde als gezählt wird NBMund BMstatt B, NBMund M(weil , wenn das NBMentfernt werden würde, wäre es das setzen Bund Mzusammen , und es gäbe keine Möglichkeit , sie zu unterscheiden). Ursprünglich habe ich eine einzelne Zeichenfolge ( .gsub!('NBM'){c+=1;?|}) zurückgegeben, aber ich habe festgestellt, dass ich nur das Ergebnis der zurückgeben kann +=(das ist eine Zahl, von der es also keine geben kann N B M).
  • Für M,, Bund Nkann ich nur countwie viele von ihnen in der Zeichenfolge sind (keine Notwendigkeit, sie über zu entfernen gsub!). Jetzt ist es eine Schleife (ich weiß nicht, warum ich das überhaupt nicht gedacht habe), also werden diese auf die gleiche Weise durchgeführt.


Ähnliche Lösung in Strauß , 54 51 Zeichen :

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

Leider keine gültige Lösung, da es in der aktuellen Ostrich-Version einen Fehler gibt (der jetzt behoben ist, aber nachdem diese Challenge gepostet wurde).


Sie können 3 Zeichen sparen, indem Sie die Array-Notation verwenden %w(NBM BM NB M B N)und die Teilung entfernen.
DickieBoy

@DickieBoy Das sind eigentlich 4 Zeichen; Vielen Dank!
Türklinke

Ach ja, der Punkt!
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],".");}

Und mit ein paar Zeilenumbrüchen:

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

Es funktioniert ziemlich einfach. Führen Sie einfach eine Schleife über die Token, ersetzen Sie sie durch Punkte und zählen Sie, solange die Eingabe einige enthält. Zählt zuerst die Großen, damit die Kleinen es nicht vermasseln.

Ich habe ursprünglich versucht, alles auf einmal zu ersetzen und den Längenunterschied zu zählen, aber es hat ein paar Zeichen mehr gedauert :(


2
Als Java-Entwickler möchte ich dies kürzer machen und sehen, dass Java zur Abwechslung gewinnt. Nachdem ich es eine Weile angestarrt habe, muss ich noch einen Weg finden, es kürzer zu machen.
DeadChex

1
Nun , es auf jeden Fall ist nicht gewinnen insgesamt. Der aktuelle Leader ist 22 Byte groß und es gibt keine Möglichkeit, in Java in dieser Größe etwas Sinnvolles zu tun. Meine printlnAussage allein ist größer als das. Ich bin aber zufrieden damit: D
Geobits 18.06.15

1
Ich bin ein bisschen spät String q[]=String[]q=
dran,

1
Nett! Ich kann nicht glauben, dass ich das verpasst habe, es ist auf meiner Standardliste der Dinge, die ich mir ansehen muss :)
Geobits

Ich habe es erst entdeckt, nachdem ich versucht hatte, in Code Golf als JavaDev einzusteigen. Ich bin ziemlich überrascht über einige Dinge, die Sie tun können
DeadChex

11

CJam, 36 32 31 Bytes

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

Vielen Dank an @Optimizer für das Golfen ab 1 Byte.

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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*-> `sollte reichen
Optimierer

@Optimize: Das funktioniert gut. Vielen Dank.
Dennis

7

R 153 134 118

Das wurde sehr schnell länger, aber hoffentlich kann ich mich ein paar mal rasieren. Der Eingang ist STDIN und der Ausgang ist STDOUT.

Bearbeiten Kehrtwende. Hab die gespaltene Saite losgeworden und Teile gezählt. Jetzt ersetze ich die Teile durch einen String, der kürzer ist als der Teil. Die Differenz zwischen den Stringlängen wird für die Ausgabe gesammelt.

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

Erläuterung

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

Testlauf

> 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

Dies ist eine Mischung aus @ isaacgs Pyth-Lösung und @ xnors unglaublichem Python-Trick.

Probieren Sie es online aus: Vorführ- oder Testgeschirr

Erläuterung

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

Dadurch wird eine unbenannte Funktion erstellt, die eine Zeichenfolge als Eingabe verwendet und das Ergebnis mit einem einzelnen nachgestellten Leerzeichen und ohne nachgestellte Zeilenumbrüche an STDOUT ausgibt. Um es zu nennen, geben Sie ihm einen Namen, z f=b->....

Ungolfed + Erklärung:

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

Beispiele:

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

Einfacher Ansatz.

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

Rufen Sie wie folgt an:

f("NBMMBNBNBM")

Die Ausgabe ist wie folgt:

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

Sie können das Leerzeichen danach entfernen in.
Isaacg

In Python 2 können Sie mit "x" in eine Zeichenfolgendarstellung konvertieren.
Donnerstag,

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;

Verwendung (7 Bytes für sysparm hinzugefügt):

$ 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

oder

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

Verwendung:

data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)

Ergebnis:

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

Sie können ein paar Bytes mit cats('s/',z,'/x/')anstelle von speichern 's/'||strip(z)||'/x/'.
Alex A.

1
Schön, das war eine ziemliche Rückreise nach 139 :)
Spiegelei

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;. Da Sie bereits von lesen sysparm, können Sie es auch einfach als Datenschritt ausführen. Und wenn Sie im Stapelbetrieb arbeiten, brauchen Sie nicht run;.
Alex A.

1
Aber Sie könnten 129 erhalten, indem Sie ein modernes Makro verwenden, das nicht aus dem Befehlszeilenargument liest:%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

Nicht die kürzeste, aber was würden Sie sonst noch von PHP erwarten?

Um es zu benutzen, lege einen Schlüssel auf ein COOKIE, POST, GET, SESSION ...

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

Der Ansatz ist grundlegend:

  • Teilen Sie die Zeichenfolge in die Namen der Kreaturen auf
  • Zählen Sie, wie viele Elemente es gibt
  • Subtrahiere 1 (ein leerer String würde ein Array mit 1 Element ergeben)
  • Gib die Zählung und den Namen der Kreatur aus
  • Füge alles zusammen, indem du eine leere Schnur verwendest (die die Schnur verkleinert und die letzte Kreatur entfernt).

Einfach richtig?


2

JavaScript, 108 116 Bytes

Nur ein direkter Ansatz, nichts Besonderes

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
Funktioniert nicht: All 6 counts must be shown, separated by spaces, even when they are 0.. Testfall:N
edc65

@ edc65 Woah. Ich habe diesen Teil einfach verpasst. Vielen Dank für den Hinweis. Es wurde für die Kosten von 8
Zeichen

2

Perl, 46

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

Erklärung, wie das funktioniert?
Cain

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$

Verwendet den gleichen Ansatz wie viele andere. Zeile 4 durchläuft weiterhin die Zeichenfolge (von der größten zuerst) und ersetzt sie, wenn sie gefunden wird.

SpecBAS hat einige nette Details über Original ZX / Sinclair BASIC (Listen durchlaufen, Zeichen finden), die ich noch herausfinde.


1

C 205 186 184 Bytes

Ein etwas anderer Ansatz basiert auf der Zustandsmaschine. Wo tist der Staat?

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

Erweitert

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

Testfunktion

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

Würden Sie nicht for(;;*s++){...}stattdessen do{...}while(*s++);einige Bytes speichern? Außerdem benötigen Sie das Zeilenumbruchzeichen in der printf.
Spikatrix

Ich denke du meintest for(;*s;s++). Aber ich musste mit dem letzten Nullzeichen eine Schleife machen. Guter Aufruf zum Speichern der \n, was nicht erforderlich ist.
Einige Benutzer

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 (ohne Importe)

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

(Entschuldigung für die Internet-Nekromantie hier.)

Auf der Haskell-Plattform gibt es keine Zeichenfolgensuche ohne Import, und ich wollte die Tatsache demonstrieren und ausnutzen, dass die gesuchten Zeichenfolgen alle Teilzeichenfolgen einer Zeichenfolge sind (ohne Wiederholungen) folge einander, was fhier der Fall ist.

Ich brauche am lEnde noch die vollständige Liste , um die Gleichheit zu überprüfen und genau wie erforderlich anzuzeigen, hätte aber nicht die Herausforderung bestanden, nur die Anzahl der möglichen Vorkommen wordsin beliebiger Reihenfolge zu melden .


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

Übergeben Sie die Zeichenfolge als erstes Argument.

bash nmb.sh MBNNBBMNBM 

Ein bisschen erklärt:

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

Live-Demo und Tests.

Die Arbeitsweise ist einfach, aber ein bisschen seltsam:

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

Dies verwendet kreativ Gruppen, um Eingaben wie folgt umzuwandeln:

NBMBM

in

aNBMbcdeBMfghijkl

Die nächste Zeile:

[A-Z]+/_

Dadurch werden die Folgen von Großbuchstaben durch Unterstriche ersetzt.

#

Hiermit wird einfach ein Nummernzeichen am Zeilenanfang eingefügt.

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

Dies ist der erste coole Teil. Grundsätzlich werden die Folgen von Kleinbuchstaben und Unterstrichen in Großbuchstaben umgewandelt, gruppiert und vor dem eingegebenen Pfund platziert. Das Pfund dient dazu, die bereits verarbeiteten Sequenzen zu verwalten.

#

Das Pfund wird am Zeilenanfang neu eingefügt.

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

Die Großbuchstaben werden durch ihre Textäquivalente mit den zugehörigen Zählungen ersetzt. Aufgrund eines Fehlers in rs (ich wollte nicht riskieren, ihn zu reparieren und disqualifiziert zu werden) werden die leeren Sequenzen in konvertiert (^^), die in der vorletzten Zeile durch eine 0 ersetzt werden. Die allerletzte Zeile entfernt einfach das Pfund.


0

KDB (Q), 76 Bytes

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

Erläuterung

                                                   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

Prüfung

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

Einige Vorschläge: Sie verwenden pund snur einmal, daher ist es nicht erforderlich, ihm einen Namen zu geben (-> a#[]=[]:a#"NBM", dasselbe für p). Übrigens: words"N B M NB BM NBM"Anstelle der Liste der Zeichenfolgen werden zusätzliche Bytes gespeichert. Das importist nur für intercalate, es ist kürzer, um es neu zu implementieren: ...putStrLn.tail.((' ':)=<<)$map...und das loszuwerden import. Setzen Sie die alle Wachen |in der Definition von #in einer einzigen Zeile und verwenden Sie 1<2anstelle von True: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?kann kürzer mit einer Liste Verständnis definiert werden: c?t=sum[1|x<-c,x==t]. Auch hier verwenden Sie ?nur einmal, also direkt den Körper zu benutzen ...show(sum[1|x<-l#[],x==t]).
nimi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.