Sfida di golf con codice semplice: modelli di personaggi!


22

In questa sfida, ricevi una stringa come input contenente una stringa di X, Y e Z ad es. "XYZZ". X, Y e Z rappresentano un personaggio particolare. Questo modello viene quindi confrontato con un secondo input di stringa. Se il pattern esiste come sottostringa nel secondo input, return True, altrimenti, return False. Una volta trovato un modello nella parola, il programma interrompe la ricerca e ritorna True.

Esempi

Modello: "XXYY"

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

Modello: "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Nota: questo non è l'input effettivo. Questo è un esempio di come dovrebbe funzionare il programma. Il tuo programma dovrebbe produrre Trueo False, o altri valori di Verità / Falsi.

Altre informazioni importanti / utili

  • Non è necessario che il modello contenga una X, una Y e una Z, potrebbe contenere le X e le Y o persino (anche se in qualche modo inutile) solo le X.
  • Il modello non può essere vuoto, ma questo non verrà utilizzato come test case.
  • La stringa di ricerca non sarà vuota e sarà minuscola.
  • L'ordine alfabetico di X, Y e Z nel modello non ha importanza.
  • X, Y e Z devono essere caratteri unici.
  • Puoi utilizzare qualsiasi libreria desideri.
  • Il punteggio è determinato dalla dimensione del codice , in byte. Il punteggio più basso vince.

In bocca al lupo!


Il modello può essere qualsiasi cosa. Probabilmente avrei dovuto menzionare che il modello non deve avere una X, una Y e una Z, potrebbe avere solo una X e una Y. Quei modelli sono solo esempi, quindi sentiti libero di inventare il tuo esempi con questi schemi.
notHalfBad

Cosa intendi con "il modello esiste"? Come un pezzo contiguo? Come sottostringa? Ad esempio, X e Y possono rappresentare la stessa cosa?
xnor

@xnor X e Y devono essere indipendenti l'uno dall'altro, e ciò che intendo con lo schema esistente è che ovunque nella stringa c'è una sottostringa che corrisponde allo schema. Aggiungerò questi alla descrizione della mia sfida per chiarire.
notHalfBad

3
Relazionato. (Stessa cosa, ma richiede corrispondenze esatte del modello, non per sottostringhe.)
Martin Ender

4
Maggiori dettagli: il modello può essere vuoto? La stringa di ricerca? La stringa di ricerca utilizzerà solo lettere minuscole? Il modello sarà alfabeticamente il primo tra i modelli equivalenti, cioè usa prima X poi Y poi Z?
xnor

Risposte:


12

Perl 5 , 85 byte

40 byte salvati grazie al suggerimento di Peter Taylor! (vedi la mia versione precedente qui sotto per vedere le differenze)

83 byte di codice + -plflag.

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

Provalo online!

XYXYZ viene trasformato in ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)(sì, alcuni dei test non possono essere veri, ma è più breve in quel modo), e il secondo input viene quindi confrontato con quel regex. (vedi le spiegazioni della mia versione precedente per avere più intuizione di come funziona)


La mia versione precedente:
Grazie ad Arnauld per aver segnalato un errore che ho fatto nella mia prima versione.
113 byte di codice +-pl flag e -Mre=eval.

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

Provalo online!

Sull'esempio XYXYZ: (.) (.) (.) Il primo regex convertirà il pattern \ 1 \ 2, e aggiungere alla fine un test per verificare se $1, $2e $3sono diversi: in tal caso, $\è impostato a uno. Quindi, il secondo input viene testato contro questa regex e $\viene implicitamente stampato alla fine.
Il regex generato per XYXYZ è (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Aggiungerò un po 'più di dettagli alle spiegazioni quando avrò un momento)


Quindi, usando regex per trasformare non-regex in regex? coolio
Matthew Roh,

@Arnauld In effetti, grazie. (Devo aver letto la sfida troppo in fretta, il mio male). Ho dovuto raddoppiare il byte per risolverlo, ma ora funziona!
Dada,

Non sarebbe più golfista generare una regex come (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor,

@Peter Taylor forse .. Ci ho pensato vagamente, ma mi è sembrato più difficile (leggi più a lungo) generare .. Avrò un altro sguardo quando avrò un momento.
Dada,

@Peter Taylor non importa, sarà più corto di 30 byte; Lo aggiornerò tra poco, grazie :)
Dada,

10

Gelatina , 9 byte

=þ
ẆÇ€ċÇ}

Restituisce il numero di volte in cui è stato trovato il modello, diverso da zero è verità e zero è falsa.

Provalo online!

Come funziona

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

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>

Funziona trasformando il pattern in una regexp, ad esempio XYXYZperché genera /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

Noto un'interessante distinzione tra PCRE e JavaScript regexp: in PCRE, \<n>fallisce (e quindi ha (?!\<n>)successo) prima che venga definito il gruppo di acquisizione, mentre JavaScript corrisponde correttamente alla stringa vuota (e quindi (?!\<n>)fallisce).


7

Python 2 , 70 byte

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

Provalo online!

Verifica se una stringa corrisponde a un modello utilizzando il metodo in questa risposta . Utilizza un prefisso della stringa di ricerca la cui lunghezza è uguale al modello. Taglia il primo carattere della stringa di stringa fino a quando non viene trovata una corrispondenza o Falsese diventa vuota


73 byte:

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

Provalo online

Verifica se una stringa corrisponde a un modello utilizzando il metodo in questa risposta . Controlla ricorsivamente tutte le sottostringhe ramificandole per rimuovere il primo o l'ultimo carattere fino a quando la stringa non è vuota.



4

05AB1E , 19 16 byte

ÙœJv¹y…XYZ‡²åi1q

Provalo 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.

Restituirà 1 se vero, null se non vero.


Questo può essere di 14 byte se è consentito restituire i possibili valori di XYZ:

05AB1E , 14 byte

ÙœJv¹y…XYZ‡²å—

Provalo online 2!


Supponendo che una stringa non vuota sia vera in 05AB1E e che una stringa vuota sia falsa, la tua seconda versione dovrebbe essere conforme alle specifiche.
Dennis,

1
Risultato errato sull'ingresso "abcd" e "XYZZ". È necessario aggiungere una quarta lettera come sostituzione predefinita.
GB

@Dennis: se seguiamo il meta post, l'unico valore di verità in 05AB1E è 1e True(che di solito è uno svantaggio per questo tipo di sfide), ma se le specifiche della sfida possono essere interpretate come permettendoci di definire verità / falsità per la sfida la seconda versione funziona come dici tu.
Emigna,

@Emigna Oh, non ne ero a conoscenza.
Dennis,

4

Java 7, 177 176 173 byte

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

Spiegazione:

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

Codice di prova:

Provalo qui.

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

Produzione:

true
false
true
true
false

4

PHP, 89 byte

Un regalo di @Christoph e @Titus

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

PHP, 105 byte

Un regalo di @Christoph

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

PHP, 167 byte

[,$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);

1
Dovresti essere in grado di salvare 2 byte utilizzando ++$pinvece di ($p+1), anche se non l'ho ancora testato.
user59178

1
Non funziona per me: Sandbox . In ogni caso una versione del codice di 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
Prendi questo in regalo: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Nota che dovresti tenere i tuoi vecchi punteggi usando <strike>)
Christoph

1
@Christoph A Gift è stato lo sforzo di apprendimento con !. Vale più la pena quindi i punti che ho potuto raggiungere con la tua bella soluzione.
Jörg Hülsermann,

1
Conto 109, non 108. -3 byte se non copi $argvsu $ae $b; -6 byte con for(;a&$v=$argv[1][$i++];); -1 byte con nomi di variabili più lunghi (in effetti!: Usa $vvinvece di $v, $iiinvece di $i, $rrinvece di $r, $yyinvece di $ye puoi usare $$vvinvece di $x[$v])
Tito

4

C #, 184 165 155 byte

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

soluzione di backtracking, come bonus funziona con uno schema con qualsiasi personaggio!

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

ho appena notato che il golf ha esposto la logica che non ho usato, che aggiornerò presto
downrep_nation

2
Prima di tutto, perché il var s=l==n.Length;? Lo usi solo su return s?!s:(dove !sè sempre false), quindi può essere cambiato in return l==n.Length?0>1:. Inoltre, che cosa è questo: (n[i]!=n[j]||n[i]!=n[j]). Controlli n[i]!=n[j]due volte .. Sarà sempre true or true/ false or false..: S
Kevin Cruijssen,

Il doppio controllo in realtà lasciato da un sistema più grande se scomparso nel golf, quindi è stato usato molto, lo migliorerò ulteriormente. Grazie!
downrep_nation

Puoi decalare tutte le tue variabili in una rigaint l = p.Length,i = 0, j;
aloisdg dice Reinstate Monica il

Può spostare te i++e il tuo j--dentro il ciclo for. per esempio:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg dice Reinstate Monica il

3

Rubino, 63 61 byte

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

Invece di cercare un modello regex, prova a sostituire "X", "Y" e "Z" in tutti i modi possibili e trova una corrispondenza letterale.

(In realtà lo stesso concetto della risposta 05AB1E di carusocomputing)


2

JavaScript (ES6), 92 89 87 86 byte

Accetta input p(pattern) e s(string) nella sintassi del curry (p)(s). Restituisce 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)

Formattato e commentato

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

Casi 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


0

Mathematica 18 caratteri (senza contare la stringa e il motivo)

StringContainsQ[string,pattern]

Esempi:

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

True

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

True


Questo non è valido perché non accetta la stringa e il modello come input di stringa come richiesto.
lunedì
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.