Código simple desafío de golf: patrones de personajes!

22

En este desafío, recibirá una cadena como entrada que contiene una cadena de X, Y y Z, por ejemplo. "XYZZ". X, Y y Z representan un personaje en particular. Este patrón se compara con una segunda entrada de cadena. Si el patrón existe como una subcadena en la segunda entrada, regrese True, de lo contrario, regrese False. Una vez que se encuentra un patrón en la palabra, el programa deja de buscar y regresa True.

Ejemplos

Patrón: "XXYY"

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

Patrón: "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Nota: Esta no es la entrada real. Este es un ejemplo de cómo debería funcionar el programa. Su programa debería generar Trueo False, u otros valores de Verdad / Falsificación.

Otra información importante / útil

  • El patrón no necesita contener una X, Y y una Z, podría contener X e Y o incluso (aunque algo sin sentido) solo X.
  • El patrón no puede estar vacío, pero esto no se utilizará como un caso de prueba.
  • La cadena de búsqueda no estará vacía y estará en minúscula.
  • El orden alfabético de X, Y y Z en el patrón no importa.
  • X, Y y Z deben ser personajes únicos.
  • Puede usar cualquier biblioteca que desee.
  • La puntuación está determinada por el tamaño del código , en bytes. La puntuación más baja gana.

¡Buena suerte!

notHalfBad
fuente
El patrón puede ser cualquier cosa. Probablemente debería haber mencionado que el patrón no tiene que tener una X, Y y una Z, podría tener solo una X y una Y. Sin embargo, esos patrones son solo ejemplos, así que siéntete libre de crear tu propio ejemplos con esos patrones.
notHalfBad
¿Qué quieres decir con "el patrón existe"? Como un trozo contiguo? Como una subcadena? ¿Pueden, por ejemplo, X e Y representar lo mismo?
xnor
@xnor X e Y deben ser independientes entre sí, y lo que quiero decir con el patrón existente es que en cualquier parte de la cadena hay una subcadena que coincide con el patrón. Agregaré esto a la descripción de mi desafío para aclararlo.
notHalfBad
3
Relacionado. (Lo mismo, pero pide coincidencias exactas del patrón, no subcadenas.)
Martin Ender
44
Más detalles: ¿Puede el patrón estar vacío? La cadena de búsqueda? ¿La cadena de búsqueda solo usará letras minúsculas? ¿Será el patrón alfabéticamente primero entre patrones equivalentes, es decir, usar X primero, luego Y y luego Z?
xnor

Respuestas:

12

Perl 5 , 85 bytes

¡Ahorré 40 bytes gracias a la sugerencia de Peter Taylor! (vea mi versión anterior a continuación para ver las diferencias)

83 bytes de código + -plbandera.

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

Pruébalo en línea!

XYXYZ se transforma en ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)(sí, algunas de las pruebas no pueden ser verdaderas, pero es más corto de esa manera), y la segunda entrada se verifica contra esa expresión regular. (vea las explicaciones de mi versión anterior para tener una mayor intuición de cómo funciona)


Mi versión anterior:
Gracias a Arnauld por señalar un error que cometí en mi primera versión.
113 bytes de código + -plbanderas, y -Mre=eval.

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

Pruébalo en línea!

En el ejemplo XYXYZ: la primera expresión regular convertirá el patrón a (.) (.) \ 1 \ 2 (.), Y agregará al final una prueba para verificar si $1, $2y $3son diferentes: si es así, $\se establece en uno. Luego, la segunda entrada es testículos contra esta expresión regular, y $\se imprime implícitamente al final.
La expresión regular generada para XYXYZ es (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Agregaré un poco más de detalles a las explicaciones cuando tenga un momento)

Dada
fuente
Entonces, ¿usa regex para convertir no regex en regex? coolio
Matthew Roh
@Arnauld De hecho, gracias. (Debo haber leído el desafío demasiado rápido, mi mal). Tuve que duplicar el bytecount para solucionarlo, ¡pero funciona ahora!
Dada
¿No sería más golfista generar una expresión regular como (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor
@Peter Taylor tal vez ... Pensé vagamente en ello, pero me pareció más difícil (leer más) generarlo ... Tendré otra mirada cuando tenga un momento.
Dada
@Peter Taylor no importa, será 30 bytes más corto; Lo actualizaré en un momento, gracias :)
Dada
10

Jalea , 9 bytes

=þ
ẆÇ€ċÇ}

Devuelve el número de veces que se encontró el patrón, siendo cero verdadero y falso falso.

Pruébalo en línea!

Cómo funciona

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

JavaScript (ES6), 94 bytes

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>

Funciona transformando el patrón en una expresión regular, por ejemplo, para XYXYZgenerar /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

Noto una distinción interesante entre PCRE y JavaScript regexp: en PCRE, \<n>falla (y por lo tanto (?!\<n>)tiene éxito) antes de que se defina el grupo de captura, mientras que JavaScript coincide con éxito con la cadena vacía (y por lo tanto (?!\<n>)falla).

Neil
fuente
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:])

Pruébalo en línea!

Comprueba si una cadena coincide con un patrón utilizando el método en esta respuesta . Utiliza un prefijo de la cadena de búsqueda cuya longitud es igual al patrón. Corta el primer carácter de la cadena hasta que se encuentre una coincidencia, o Falsesi queda vacía


73 bytes:

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

Pruébalo en línea

Comprueba si una cadena coincide con un patrón utilizando el método en esta respuesta . Verifica recursivamente todas las subcadenas ramificándose para eliminar el primer o el último carácter hasta que la cadena esté vacía.

xnor
fuente
4

05AB1E , 19 16 bytes

ÙœJv¹y…XYZ‡²åi1q

Pruébalo en línea!


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

Devolverá 1 si es verdadero, nulo si no es cierto.


Esto puede ser de 14 bytes si se permite devolver los posibles valores de XYZ:

05AB1E , 14 bytes

ÙœJv¹y…XYZ‡²å—

Pruébelo en línea 2!

Urna de pulpo mágico
fuente
Suponiendo que una cadena no vacía es verdadera en 05AB1E y que una cadena vacía es falsa, su segunda versión debe cumplir con la especificación.
Dennis
1
Resultado incorrecto en la entrada "abcd" y "XYZZ". Debe agregar una cuarta letra como una sustitución predeterminada.
GB
@Dennis: Si seguimos la meta publicación, los únicos valores de verdad en 05AB1E son 1y True(que generalmente es un inconveniente para este tipo de desafíos), pero si la especificación del desafío puede interpretarse como que nos permite definir la verdad / falsedad para el desafío La segunda versión funciona como usted dice.
Emigna
@Emigna Oh, no estaba al tanto de eso.
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;}

Explicación:

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

Código de prueba:

Pruébalo aquí

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

Salida:

true
false
true
true
false
Kevin Cruijssen
fuente
4

PHP, 89 bytes

Un regalo de @Christoph y @Titus

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

PHP, 105 bytes

Un regalo 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 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
fuente
1
Debería poder guardar 2 bytes utilizando en ++$plugar de ($p+1), aunque en realidad no lo he probado.
user59178
1
No funciona para mí: Sandbox . De todos modos una versión del código 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
Tome esto como un regalo: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Tenga en cuenta que debe mantener sus puntajes anteriores usando <strike>)
Christoph
1
@Christoph A Gift fue el esfuerzo de aprendizaje con el !. Vale más la pena que los puntos que podría alcanzar con su buena solución.
Jörg Hülsermann
1
Cuento 109, no 108. -3 bytes si no copia $argva $ay $b; -6 bytes con for(;a&$v=$argv[1][$i++];); -1 byte con nombres de variables más largos ( ¡en efecto!: Use en $vvlugar de $v, en $iilugar de $i, en $rrlugar de $r, en $yylugar de $yy puede usar en $$vvlugar de $x[$v])
Tito
4

C #, 184 165 155 bytes

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

solución de retroceso, como beneficio adicional, funciona con un patrón con cualquier personaje.

    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
fuente
Acabo de notar golf se expone la lógica i no usamos, a actualizar pronto
downrep_nation
2
En primer lugar, ¿por qué var s=l==n.Length;? Solo lo usa en return s?!s:(donde !ssiempre está false), por lo que se puede cambiar a return l==n.Length?0>1:. Además, ¿qué es esto (n[i]!=n[j]||n[i]!=n[j])? Verifica n[i]!=n[j]dos veces. Esto siempre será true or true/ false or false..: S
Kevin Cruijssen
La doble verificación en realidad quedó de un sistema más grande que desapareció en el golf, por lo que se usó mucho, lo mejoraré aún más. ¡Gracias!
downrep_nation
Puede descalcificar todas sus variables en una líneaint l = p.Length,i = 0, j;
aloisdg dice Reinstate Monica
Puede mover su i++y su j--dentro del bucle for. por ejemplo:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg dice Reinstate Monica
3

Ruby, 63 61 bytes

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

En lugar de buscar un patrón de expresiones regulares, simplemente intente sustituir 'X', 'Y' y 'Z' de todas las formas posibles, y encuentre una coincidencia literal.

(En realidad, el mismo concepto que la respuesta 05AB1E de carusocomputing)

GB
fuente
2

JavaScript (ES6), 92 89 87 86 bytes

Toma entrada p(patrón) y s(cadena) en la sintaxis de curry (p)(s). Devoluciones 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)

Formateado y comentado

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

Casos de prueba

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
fuente
0

Mathematica 18 caracteres (sin contar cadenas y patrones)

StringContainsQ[string,pattern]

Ejemplos:

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

True

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

True

Vitaliy Kaurov
fuente
Esto no es válido porque no toma la cadena y el patrón como entradas de cadena según sea necesario.
lirtosiast