Défi de golf à code simple: modèles de personnages!

22

Dans ce défi, vous recevez une chaîne en entrée contenant une chaîne de X, Y et Z par exemple. "XYZZ". X, Y et Z représentent un caractère particulier. Ce modèle est ensuite comparé à une deuxième entrée de chaîne. Si le modèle existe en tant que sous-chaîne dans la deuxième entrée, retournez True, sinon, retournez False. Une fois qu'un motif est trouvé dans le mot, le programme arrête la recherche et revient True.

Exemples

Motif: "XXYY"

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

Motif: "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Remarque: Ce n'est pas l'entrée réelle. Ceci est un exemple de la façon dont le programme devrait fonctionner. Votre programme doit afficher Trueou False, ou d'autres valeurs Truthy / Falsy.

Autres informations importantes / utiles

  • Le motif n'a pas besoin de contenir un X, Y et un Z, il peut contenir des X et des Y ou même (bien que quelque peu inutile) que des X.
  • Le modèle ne peut pas être vide, mais il ne sera pas utilisé comme cas de test.
  • La chaîne de recherche ne sera pas vide et sera en minuscules.
  • L'ordre alphabétique de X, Y et Z dans le motif n'a pas d'importance.
  • X, Y et Z doivent être des caractères uniques.
  • Vous pouvez utiliser n'importe quelle bibliothèque de votre choix.
  • Le score est déterminé par la taille du code , en octets. Le score le plus bas l'emporte.

Bonne chance!

notHalfBad
la source
Le motif peut être n'importe quoi. J'aurais probablement dû mentionner que le modèle n'a pas besoin d'avoir un X, Y et un Z, il pourrait avoir juste un X et un Y. Ces modèles ne sont cependant que des exemples, alors n'hésitez pas à créer le vôtre exemples avec ces modèles.
notHalfBad
Que voulez-vous dire par "le modèle existe"? Comme un morceau contigu? En tant que sous-chaîne? Par exemple, X et Y peuvent-ils représenter la même chose?
xnor
@xnor X et Y doivent être indépendants l'un de l'autre, et ce que je veux dire par le modèle existant est que n'importe où dans la chaîne il y a une sous-chaîne qui correspond au modèle. Je les ajouterai à ma description de défi pour clarifier.
notHalfBad
3
En relation. (Même chose, mais demande des correspondances exactes du motif, pas des sous-chaînes.)
Martin Ender
4
Plus de détails: le motif peut-il être vide? La chaîne de recherche? La chaîne de recherche n'utilisera-t-elle que des lettres minuscules? Le motif sera-t-il d'abord alphabétique parmi les motifs équivalents, c'est-à-dire utiliser d'abord X puis Y puis Z?
xnor

Réponses:

12

Perl 5 , 85 octets

Enregistré 40 octets grâce à la suggestion de Peter Taylor! (voir mon ancienne version ci-dessous pour voir les différences)

83 octets de code + -plindicateur.

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

Essayez-le en ligne!

XYXYZ est transformé en ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)(oui, certains des tests ne peuvent pas être vrais, mais c'est plus court de cette façon), et la deuxième entrée est ensuite vérifiée par rapport à cette expression régulière. (voir les explications de mon ancienne version pour avoir plus d'intuition sur son fonctionnement)


Mon ancienne version:
Merci à Arnauld d'avoir signalé une erreur que j'ai faite dans ma première version.
113 octets de code + -pldrapeaux, et -Mre=eval.

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

Essayez-le en ligne!

Sur l'exemple XYXYZ: le premier regex convertira le modèle en (.) (.) \ 1 \ 2 (.), Et ajoutera à la fin un test pour vérifier si $1, $2et $3sont différents: si c'est le cas, $\est réglé sur un. Ensuite, la deuxième entrée est testée par rapport à cette expression régulière et $\est implicitement imprimée à la fin.
Le regex généré pour XYXYZ est (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Je vais ajouter un peu plus de détails aux explications quand j'aurai un moment)

Dada
la source
Donc, utiliser regex pour transformer des non-regex en regex? coolio
Matthew Roh
@Arnauld En effet, merci. (J'ai dû lire le défi trop vite, ma mauvaise). J'ai dû doubler le bytecount pour le réparer, mais cela fonctionne maintenant!
Dada
Ne serait-il pas plus golfeur de générer un regex comme (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor
@Peter Taylor peut-être .. J'y ai vaguement pensé, mais il m'a semblé plus difficile (lire plus) de générer .. J'aurai un autre regard quand j'aurai un moment.
Dada
@Peter Taylor nevermind, ça va être 30 octets plus court; Je mettrai cela à jour un peu, merci :)
Dada
10

Gelée , 9 octets

=þ
ẆÇ€ċÇ}

Renvoie le nombre de fois où le motif a été trouvé, non nul étant vrai et zéro étant faux.

Essayez-le en ligne!

Comment ça marche

ẆÇ€ċÇ}  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
la source
8

JavaScript (ES6), 94 octets

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>

Fonctionne en transformant le motif en expression rationnelle, par exemple car XYXYZil génère /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

Je remarque une distinction intéressante entre PCRE et regexp JavaScript: dans PCRE, \<n>échoue (et (?!\<n>)réussit donc ) avant que le groupe de capture ne soit défini, tandis que JavaScript correspond avec succès à la chaîne vide (et (?!\<n>)échoue donc ).

Neil
la source
7

Python 2 , 70 octets

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

Essayez-le en ligne!

Vérifie si une chaîne correspond à un modèle en utilisant la méthode de cette réponse . Utilise un préfixe de la chaîne de recherche dont la longueur est égale au modèle. Coupe le premier caractère de la chaîne jusqu'à ce qu'une correspondance soit trouvée, ouFalse si elle devient vide


73 octets:

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

Essayez-le en ligne

Vérifie si une chaîne correspond à un modèle en utilisant la méthode de cette réponse . Vérifie récursivement toutes les sous-chaînes en se ramifiant en supprimant le premier ou le dernier caractère jusqu'à ce que la chaîne soit vide.

xnor
la source
4

05AB1E , 19 16 octets

ÙœJv¹y…XYZ‡²åi1q

Essayez-le en ligne!


Ùœ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.

Renvoie 1 si vrai, nul sinon faux.


Cela peut être de 14 octets si le retour des valeurs possibles de XYZ est autorisé:

05AB1E , 14 octets

ÙœJv¹y…XYZ‡²å—

Essayez-le en ligne 2!

Urne de poulpe magique
la source
En supposant qu'une chaîne non vide est véridique dans 05AB1E et qu'une chaîne vide est fausse, votre deuxième version doit être conforme à la spécification.
Dennis
1
Résultat incorrect sur l'entrée "abcd" et "XYZZ". Vous devez ajouter une quatrième lettre comme substitution par défaut.
GB
@Dennis: Si nous passons par la méta-publication, les seules valeurs véridiques dans 05AB1E sont 1et True(ce qui est généralement un inconvénient pour ces types de défis), mais si la spécification de défi peut être interprétée comme nous permettant de définir la véracité / la fausseté pour le défi la deuxième version fonctionne comme vous le dites.
Emigna
@Emigna Oh, je ne le savais pas.
Dennis
4

Java 7, 177 176 173 octets

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

Explication:

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

Code de test:

Essayez-le ici.

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

Sortie:

true
false
true
true
false
Kevin Cruijssen
la source
4

PHP, 89 octets

Un cadeau de @Christoph et @Titus

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

PHP, 105 octets

Un cadeau de @Christoph

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

PHP, 167 octets

[,$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
la source
1
Vous devriez pouvoir enregistrer 2 octets en utilisant ++$pau lieu de ($p+1), bien que je ne l'ai pas testé.
user59178
1
Ça ne marche pas pour moi: Sandbox . Quoi qu'il en soit une version golfed du code: [,$a,$b]=$argv;foreach(str_split($a)as$k=>$v)$r.=$k==($p=strpos($a,$v))?"(.)":"\\".++$p;echo preg_match("#$r#",$b);.
Christoph
1
Prenez cela comme un cadeau: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Notez que vous devez conserver vos anciens scores en utilisant <strike>)
Christoph
1
@Christoph A Gift était l'effort d'apprentissage avec le !. Cela vaut plus que les points que j'ai pu atteindre avec votre belle solution.
Jörg Hülsermann
1
Je compte 109, pas 108. -3 octets si vous ne copiez pas $argvvers $aet $b; -6 octets avec for(;a&$v=$argv[1][$i++];); -1 octet avec des noms de variables plus longs (en effet!: Utilisez $vvau lieu de $v, $iiau lieu de $i, $rrau lieu de $r, $yyau lieu de $yet vous pouvez utiliser à la $$vvplace de $x[$v])
Titus
4

C #, 184 165 155 octets

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

solution de retour en arrière, en prime, elle fonctionne avec un motif avec des caractères!

    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
la source
je viens de remarquer jouer au golf avec une logique exposée que je
n'ai
2
Tout d'abord, pourquoi le var s=l==n.Length;? Vous ne l'utilisez qu'à return s?!s:(où !sest toujours false), donc il peut être changé en return l==n.Length?0>1:. En outre, ce qui est le suivant: (n[i]!=n[j]||n[i]!=n[j]). Vous vérifiez n[i]!=n[j]deux fois .. Ce sera toujours true or true/ false or false..: S
Kevin Cruijssen
Le double contrôle a en fait laissé un système plus gros si qui a disparu dans le golf, donc s a été beaucoup utilisé, je vais encore l'améliorer. Merci!
downrep_nation
Vous pouvez décalcaliser toutes vos variables sur une seule ligneint l = p.Length,i = 0, j;
aloisdg dit Réintégrer Monica
Peut déplacer votre i++et votre j--intérieur de la boucle for. par exemple:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg dit Reinstate Monica
3

Rubis, 63 61 octets

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

Au lieu de rechercher un modèle d'expression régulière, essayez simplement de remplacer «X», «Y» et «Z» de toutes les manières possibles, et trouvez une correspondance littérale.

(En fait, le même concept que la réponse 05AB1E de carusocomputing)

GB
la source
2

JavaScript (ES6), 92 89 87 86 octets

Prend entrée p (modèle) et s(chaîne) dans la syntaxe de curry (p)(s). Renvoie 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)

Formaté et commenté

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

Cas de test

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
la source
0

Mathematica 18 caractères (sans compter la chaîne et le motif)

StringContainsQ[string,pattern]

Exemples:

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

True

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

True

Vitaliy Kaurov
la source
Ceci n'est pas valide car il ne prend pas la chaîne et le modèle comme entrées de chaîne comme requis.
lirtosiast