Einfache Code-Golf-Herausforderung: Zeichenmuster!

22

In dieser Herausforderung erhalten Sie eine Zeichenfolge als Eingabe, die eine Zeichenfolge aus X, Y und Z enthält, z. "XYZZ". X, Y und Z stehen für ein bestimmtes Zeichen. Dieses Muster wird dann mit einer zweiten Zeichenfolge verglichen. Wenn das Muster in der zweiten Eingabe als Teilzeichenfolge vorhanden ist, kehren Sie zurück True, andernfalls kehren Sie zurück False. Sobald ein Muster im Wort gefunden wurde, stoppt das Programm die Suche und kehrt zurück True.

Beispiele

Muster: "XXYY"

succeed ---> True (pattern found: ccee)
success ---> False (pattern not matched)
balloon ---> True (pattern found: lloo)

Muster: "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Hinweis: Dies ist nicht die tatsächliche Eingabe. Dies ist ein Beispiel dafür, wie das Programm funktionieren sollte. Ihr Programm sollte Trueoder Falseoder andere Truthy / Falsy-Werte ausgeben.

Andere wichtige / nützliche Informationen

  • Das Muster muss kein X, Y und Z enthalten, es könnte X und Y oder sogar (obwohl etwas sinnlos) nur X enthalten.
  • Das Muster kann nicht leer sein, dies wird jedoch nicht als Testfall verwendet.
  • Die Suchzeichenfolge ist nicht leer und wird in Kleinbuchstaben angegeben.
  • Die alphabetische Reihenfolge von X, Y und Z im Muster spielt keine Rolle.
  • X, Y und Z müssen eindeutige Zeichen sein.
  • Sie können jede Bibliothek benutzen, die Sie wünschen.
  • Die Bewertung wird durch die Codegröße in Byte bestimmt. Die niedrigste Punktzahl gewinnt.

Viel Glück!

notHalfBad
quelle
Das Muster kann alles sein. Ich sollte wohl erwähnt haben , dass das Muster kein X haben muss, Y, und Z, es könnte einfach nur ein X und ein Y Diese Muster sind nur einige Beispiele, obwohl, so fühlen sich frei , mit Ihrem eigenen zu kommen Beispiele mit diesen Mustern.
notHalfBad
Was meinst du mit "das Muster existiert"? Als zusammenhängendes Stück? Als Teilzeichenfolge? Können beispielsweise X und Y für dasselbe stehen?
Xnor
@xnor X und Y müssen unabhängig voneinander sein, und mit dem vorhandenen Muster meine ich, dass sich an einer beliebigen Stelle in der Zeichenfolge eine Teilzeichenfolge befindet, die mit dem Muster übereinstimmt. Ich werde diese meiner Herausforderungsbeschreibung hinzufügen, um sie zu verdeutlichen.
notHalfBad
3
Verbunden. (Gleiches, fragt aber nach genauen Übereinstimmungen des Musters, nicht nach Teilzeichenfolgen.)
Martin Ender
4
Weitere Details: Kann das Muster leer sein? Der Suchbegriff? Verwendet die Suchzeichenfolge nur Kleinbuchstaben? Wird das Muster unter den äquivalenten Mustern zuerst alphabetisch sein, dh zuerst X, dann Y, dann Z verwenden?
Xnor

Antworten:

12

Perl 5 , 85 Bytes

40 Bytes gespart dank Peter Taylors Vorschlag! (siehe meine ältere Version unten, um die Unterschiede zu sehen)

83 Byte Code + -plFlag.

s/./$h{$&}?"\\$h{$&}":($h{$&}=$.,join("",map"(?!\\$_)",1..$.++)."(.)")/ge;$_=<>=~$_

Probieren Sie es online!

XYXYZ wird in umgewandelt ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)(yup, einige der Tests können nicht wahr sein, aber es ist so kürzer), und die zweite Eingabe wird dann gegen diesen regulären Ausdruck geprüft. (Weitere Informationen zur Funktionsweise finden Sie in den Erläuterungen zu meiner älteren Version.)


Meine ältere Version:
Danke an Arnauld für den Hinweis auf einen Fehler, den ich in meiner ersten Version gemacht habe.
113 Byte Code + -plFlags und -Mre=eval.

s/./$h{$&}?"\\$h{$&}":($h{$&}=++$i,"(.)")/ge;$_.='(?{++$c;$\=1if!grep$v{$c}{${$_}}++,1..'.(keys%h).'})^';<>=~$_}{

Probieren Sie es online!

Am Beispiel XYXYZ: (.) (.) (.) Die erste regex wird das Muster konvertieren \ 1 \ 2, und am Ende eines Test hinzufügen , wenn zu überprüfen $1, $2und $3sind unterschiedlich: wenn dem so ist , $\auf eins gesetzt ist. Dann wird die zweite Eingabe gegen diesen regulären Ausdruck getestet und $\implizit am Ende gedruckt.
Der für XYXYZ generierte reguläre Ausdruck ist (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Ich werde ein bisschen mehr Details zu den Erklärungen hinzufügen, wenn ich einen Moment Zeit habe)

Dada
quelle
Verwenden von Regex, um Nicht-Regex in Regex umzuwandeln? coolio
Matthew Roh
@ Arnauld In der Tat, danke. (Ich muss die Herausforderung zu schnell gelesen haben, meine schlechte). Musste das bytecount verdoppeln, um es zu beheben, aber es funktioniert jetzt!
Dada
Wäre es nicht golfer, einen Regex wie zu generieren (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor
@ Peter Taylor vielleicht .. Ich vage darüber nachgedacht, aber es schien schwieriger (länger zu lesen) zu generieren .. Ich werde einen anderen Blick haben, wenn ich einen Moment habe.
Dada
@ Peter Taylor vergiss es, es wird 30 Bytes kürzer sein; Ich werde das gleich aktualisieren, danke :)
Dada
10

Gelee , 9 Bytes

=þ
ẆÇ€ċÇ}

Gibt die Häufigkeit zurück, mit der das Muster gefunden wurde, wobei Nicht-Null wahr und Null falsch ist.

Probieren Sie es online!

Wie es funktioniert

ẆÇ€ċÇ}  Main link. Left argument: s (string). Right argument: p (pattern)

Ẇ       Window; generate all substrings of s.
 ǀ     Map the helper link over the substrings.
    Ç}  Apply the helper link to p.
   ċ    Count the number of times the right result appears in the left result.


=þ      Helper link. Argument: t (string)

=þ      Compare all characters of t for equality with all characters of t, yielding
        a square matrix of Booleans.
Dennis
quelle
8

JavaScript (ES6), 94 Byte

f=
(p,s)=>s.match(p.replace(/./g,c=>m[c]||(t=r,r=`(?!\\${++g})`+r,m[c]=`\\`+g,t),g=m=[],r=`(.)`))
<div oninput=o.textContent=!!f(p.value,s.value)><input id=p placeholder=Pattern><input id=s placeholder=String><span id=o>

Arbeitet, indem das Muster in einen regulären Ausdruck umgewandelt wird, der z . B. XYXYZgeneriert wird /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

Ich bemerke einen interessanten Unterschied zwischen PCRE und JavaScript regexp: In PCRE \<n>schlägt fehl (und ist daher (?!\<n>)erfolgreich), bevor die Erfassungsgruppe definiert wird, während JavaScript erfolgreich mit der leeren Zeichenfolge übereinstimmt (und daher (?!\<n>)fehlschlägt).

Neil
quelle
7

Python 2 , 70 Bytes

f=lambda p,s:s>''and(map(s.find,s[:len(p)])==map(p.find,p))|f(p,s[1:])

Probieren Sie es online!

Prüft anhand der in dieser Antwort beschriebenen Methode, ob eine Zeichenfolge mit einem Muster übereinstimmt . Verwendet ein Präfix der Suchzeichenfolge, deren Länge dem Muster entspricht. Schneidet das erste Zeichen der Zeichenfolge ab, bis eine Übereinstimmung gefunden wird oder Falsewenn es leer wird


73 Bytes:

f=lambda p,s:s>''and(map(s.find,s)==map(p.find,p))|f(p,s[1:])|f(p,s[:-1])

Probieren Sie es online aus

Prüft anhand der in dieser Antwort beschriebenen Methode, ob eine Zeichenfolge mit einem Muster übereinstimmt . Überprüft rekursiv alle Teilzeichenfolgen, indem verzweigt wird, das erste oder letzte Zeichen zu entfernen, bis die Zeichenfolge leer ist.

xnor
quelle
4

05AB1E , 19 16 Bytes

ÙœJv¹y…XYZ‡²åi1q

Probieren Sie es online!


ÙœJ              # Get powerset of all unique characters in string.
   v             # Loop through each...
    ¹            # Push input word.
     y           # Push current set of letters in powerset.
      …XYZ‡      # Replace each of the 3 letters in the original word with XYZ.
           ²å    # Check if second input is in this string, push 1 if it is.
             i1q # If 1, push 1 and quit.

Gibt 1 zurück, wenn wahr, null, wenn nicht wahr.


Dies können 14 Bytes sein, wenn die Rückgabe der möglichen Werte von XYZ erlaubt ist:

05AB1E , 14 Bytes

ÙœJv¹y…XYZ‡²å—

Probieren Sie es online 2!

Magische Kraken-Urne
quelle
Unter der Annahme, dass ein nicht leerer String in 05AB1E wahr und ein leerer falsch ist, sollte Ihre zweite Version der Spezifikation entsprechen.
Dennis
1
Falsches Ergebnis bei Eingabe "abcd" und "XYZZ". Sie müssen einen vierten Buchstaben als Standardersetzung hinzufügen.
GB
@ Tennis: Wenn wir durch die gehen Meta-Post durchgehen, sind die einzigen Wahrheitswerte in 05AB1E 1und True(was normalerweise ein Nachteil für diese Art von Herausforderungen ist), aber wenn die Herausforderungsspezifikation so interpretiert werden kann, dass wir Wahrheit / Falschheit für die Herausforderung definieren können Die zweite Version funktioniert wie Sie sagen.
Emigna
@Emigna Oh, das wusste ich nicht.
Dennis
4

Java 7, 177 176 173 Bytes

Object c(String p,String s){int i=p.length();if(s.length()<i)return 0>1;for(;i-->0;)if(p.indexOf(p.charAt(i))!=s.indexOf(s.charAt(i)))return c(p,s.substring(1));return 1>0;}

Erläuterung:

Object c(String p, String s){                             // Method with two String parameters and Object return-type
  int i = p.length();                                     //  Index that starts at the length of the pattern
  if(s.length() < i)                                      //  If the length of the input is smaller than the length of the pattern
    return 0>1;//false                                    //   Simply return false
  for(;i-->0;)                                            //  Loop from 0 to length_of_pattern
    if(p.indexOf(p.charAt(i)) != s.indexOf(s.charAt(i)))  //   If the index of the characters of the pattern and input aren't matching
     return c(p, s.substring(1));                         //    Return the recursive-call of pattern and input minus the first character
                                                          //  End of loop (implicit / single-line body)
  return 1>0;//true                                       //  If every index of the characters are matching: return true
}                                                         // End of method

Testcode:

Probieren Sie es hier aus.

class M{
  static Object c(String p,String s){int i=p.length();if(s.length()<i)return 0>1;for(;i-->0;)if(p.indexOf(p.charAt(i))!=s.indexOf(s.charAt(i)))return c(p,s.substring(1));return 1>0;}

  public static void main(String[] a){
    System.out.println(c("XXYY", "succeed"));
    System.out.println(c("XXYY", "success"));
    System.out.println(c("XXYY", "balloon"));

    System.out.println(c("XYXYZ", "bananas"));
    System.out.println(c("XYXYZ", "banana"));
  }
}

Ausgabe:

true
false
true
true
false
Kevin Cruijssen
quelle
4

PHP, 89 Bytes

Ein Geschenk von @Christoph und @Titus

for(;$v=$argv[1][$i++];)$r.=$$v?"\\".$$v:"(.)".!$$v=++$j;echo preg_match("#$r#",$argv[2]);

PHP, 105 Bytes

Ein Geschenk von @Christoph

foreach(str_split($argv[1])as$v)$r.=$x[$v]?"\\$x[$v]":"(.)".!$x[$v]=++$y;echo preg_match("#$r#",$argv[2]);

PHP, 167 Bytes

[,$a,$b]=$argv;foreach($s=str_split($a)as$v)$r[]=$k++>strpos($a,$v)?"\\".(1+array_search($v,array_keys(array_count_values($s)))):"(.)";echo preg_match(_.join($r)._,$b);
Jörg Hülsermann
quelle
1
Sie sollten in der Lage sein, 2 Bytes zu sparen, indem Sie ++$panstelle von verwenden ($p+1), obwohl ich es nicht wirklich getestet habe.
user59178
1
Funktioniert bei mir nicht: Sandbox . Auf jeden Fall eine Version des Codes golfed: [,$a,$b]=$argv;foreach(str_split($a)as$k=>$v)$r.=$k==($p=strpos($a,$v))?"(.)":"\\".++$p;echo preg_match("#$r#",$b);.
Christoph
1
Nehmen Sie dies als Geschenk: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Beachten Sie, dass Sie Ihre alten Noten mit behalten sollten <strike>)
Christoph
1
@Christoph Ein Geschenk war der Lernaufwand bei der !. Es ist mehr wert als die Punkte, die ich mit Ihrer netten Lösung erreichen konnte.
Jörg Hülsermann
1
Ich zähle 109, nicht 108. -3 Bytes, wenn Sie nicht $argvnach $aund kopieren $b; -6 Bytes mit for(;a&$v=$argv[1][$i++];); -1 Byte mit längeren Variablennamen ( in der Tat! : Verwenden Sie $vvstatt $v, $iistatt $i, $rrstatt $r, $yystatt $yund Sie können $$vvstatt $x[$v])
Titus
4

C # 184 165 155 Bytes

danke aloisdg!

bool c(string p,string n){for(int l=p.Length,i=0,j;i<l;i++)for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))return l!=n.Length&&c(p,n.Substring(1));return 2>1;}

Backtracking-Lösung, als Bonus funktioniert es mit einem Muster mit beliebigen Zeichen!

    public static bool c(string p,string n)
    {
        for (int l = p.Length, i = 0, j; i < l; i++)
            for (j = i; j >= 0;)
                if (p[i]==p[j]==(n[i]!=n[j--]))
                    return l != n.Length && c(p,n.Substring(1));
        return 2>1;
    }
downrep_nation
quelle
Ich habe gerade bemerkt, Golf es ausgesetzt Logik, die ich nicht verwendet habe, wird bald aktualisiert
downrep_nation
2
Zuallererst, warum die var s=l==n.Length;? Sie verwenden es nur bei return s?!s:(wo !simmer false), damit es geändert werden kann return l==n.Length?0>1:. Auch, was das ist: (n[i]!=n[j]||n[i]!=n[j]). Sie überprüfen n[i]!=n[j]zweimal .. Dies wird immer sein true or true/ false or false..: S
Kevin Cruijssen
Der Double Check, der von einem größeren System übrig geblieben ist, das beim Golfen verschwunden ist, wurde viel genutzt, und ich werde ihn weiter verbessern. Vielen Dank!
Downrep_nation
Sie können alle Variablen in einer Zeile int l = p.Length,i = 0, j;
dekalieren
Kann Ihr bewegen i++und Ihr j--innerhalb der for - Schleife. Zum Beispiel:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg sagt Reinstate Monica
3

Ruby, 63 61 Bytes

->a,b{a.chars.permutation.any?{|w|a.tr((w|[])*'','XYZW')[b]}}

Anstatt nach einem Regex-Muster zu suchen, versuchen Sie einfach, 'X', 'Y' und 'Z' auf alle möglichen Arten zu ersetzen, und finden Sie eine wörtliche Übereinstimmung.

(Eigentlich das gleiche Konzept wie die 05AB1E-Antwort von carusocomputing)

GB
quelle
2

JavaScript (ES6), 92 89 87 86 Bytes

Übernimmt Eingaben p(Muster) und s(Zeichenfolge) in der aktuellen Syntax (p)(s). Rückgabe 0/ 1.

p=>g=s=>s&&g(s.slice(1))|[...p].every((C,i,x)=>C==(x[c=s[i]]=x[c]||'XYZ'[c&&j++]),j=0)

Formatiert und kommentiert

p =>                             // main function: takes pattern p as input, returns g
  g = s =>                       // g = recursive function: takes string s as input
    s &&                         // if s is not empty:
      g(s.slice(1))              //   do a recursive call, starting at the next character
    |                            // merge the result with this iteration
    [...p].every((C, i, x) =>    // for each character C at position i in p:
      C ==                       //   check whether C is matching the next expected
      (                          //   character, which is either:
        x[c = s[i]] = x[c] ||    //   - a substitution character already associated to s[i]
        'XYZ'[c && j++]          //   - the next substitution character ('X', 'Y' or 'Z')
      ),                         //   - undefined if c = s[i] doesn't exist or j > 2
      j = 0                      //   initialize j = pointer in 'XYZ'
    )                            //

Testfälle

let f =

p=>g=s=>s&&g(s.slice(1))|[...p].every((C,i,x)=>C==(x[c=s[i]]=x[c]||'XYZ'[c&&j++]),j=0)

console.log(f("XXYY")("succeed"))   // 1
console.log(f("XXYY")("success"))   // 0
console.log(f("XXYY")("balloon"))   // 1
console.log(f("XYXYZ")("bananas"))  // 1
console.log(f("XYXYZ")("banana"))   // 0

Arnauld
quelle
0

Mathematica 18 Zeichen (ohne Zeichenfolge und Muster)

StringContainsQ[string,pattern]

Beispiele:

StringContainsQ["succeed", x_ ~~ x_ ~~ y_ ~~ y_]

True

StringContainsQ["bananas", x_ ~~ y_ ~~ x_ ~~ y_ ~~ z_]

True

Vitaliy Kaurov
quelle
Dies ist ungültig, da die Zeichenfolge und das Muster nicht wie erforderlich als Zeichenfolgeeingaben verwendet werden.
Lirtosiast