Proste wyzwanie golfowe: Wzory postaci!


22

W tym wyzwaniu otrzymujesz ciąg wejściowy zawierający ciąg znaków X, Y i Z, np. „XYZZ”. X, Y i Z reprezentują określoną postać. Ten wzór jest następnie porównywany z drugim ciągiem wejściowym. Jeśli wzorzec istnieje jako podłańcuch na drugim wejściu, zwróć True, w przeciwnym razie zwróć False. Po znalezieniu wzorca w słowie program przestaje wyszukiwać i wraca True.

Przykłady

Wzór: „XXYY”

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

Wzór: „XYXYZ”

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Uwaga: To nie jest rzeczywiste wejście. To jest przykład działania programu. Twój program powinien wypisać Truelub Falselub inne wartości Truthy / Falsy.

Inne ważne / przydatne informacje

  • Wzorzec nie musi zawierać X, Y i Z, może zawierać X i Y, a nawet (choć nieco bezcelowo) tylko X.
  • Wzorzec nie może być pusty, ale nie zostanie użyty jako przypadek testowy.
  • Wyszukiwany ciąg nie będzie pusty i będzie pisany małymi literami.
  • Kolejność alfabetyczna X, Y i Z we wzorze nie ma znaczenia.
  • X, Y i Z muszą być unikalnymi znakami.
  • Możesz użyć dowolnej biblioteki.
  • Wynik zależy od wielkości kodu , w bajtach. Najniższy wynik wygrywa.

Powodzenia!


Wzór może być dowolny. Prawdopodobnie powinienem wspomnieć, że wzór nie musi mieć X, Y i Z, może mieć tylko X i Y. Te wzory są jednak tylko przykładami, więc możesz wymyślić własne przykłady z tymi wzorami.
— notHalfBad

Co masz na myśli mówiąc, że „wzór istnieje”? Jako ciągły kawałek? Jako podciąg? Czy, powiedzmy, X i Y mogą oznaczać to samo?
— xnor

@ xnor X i Y muszą być od siebie niezależne, a rozumiem przez istniejący wzorzec, że gdziekolwiek w ciągu znajduje się podciąg pasujący do wzorca. Dodam je do opisu wyzwania w celu wyjaśnienia.
— notHalfBad

3
Związane z. (To samo, ale prosi o dokładne dopasowanie wzorca, a nie o podciągi).
— Martin Ender

4
Więcej informacji: Czy wzór może być pusty? Wyszukiwany ciąg? Czy w ciągu wyszukiwania będą używane tylko małe litery? Czy wzorzec będzie alfabetycznie pierwszy spośród równoważnych wzorców, tj. Najpierw użyje X, a następnie Y, a następnie Z?
— xnor

Odpowiedzi:


12

Perl 5 , 85 bajtów

Zaoszczędzono 40 bajtów dzięki sugestii Petera Taylora! (zobacz moją starszą wersję poniżej, aby zobaczyć różnice)

83 bajty kodu + -plflaga.

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

Wypróbuj online!

XYXYZ jest przekształcany w ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)(tak, niektóre testy nie mogą być prawdziwe, ale w ten sposób są krótsze), a następnie drugie wejście jest sprawdzane pod kątem tego wyrażenia regularnego. (zobacz wyjaśnienia mojej starszej wersji, aby uzyskać więcej intuicji, jak to działa)


Moja starsza wersja:
Podziękowania dla Arnaulda za wskazanie błędu, który popełniłem w mojej pierwszej wersji.
113 bajtów kodu + -plflagi i -Mre=eval.

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

Wypróbuj online!

Na przykład XYXYZ: (.) (.) (.) Pierwszy regex będzie przekształcić wzór do \ 1 \ 2 i dodać na końcu badania, aby sprawdzić, czy $1, $2i $3są różne: jeśli tak, to $\jest ustawiona na jeden. Następnie drugie wejście jest testowane względem tego wyrażenia regularnego i $\jest domyślnie drukowane na końcu.
Wyrażenie regularne wygenerowane dla XYXYZ to (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Dodam trochę więcej szczegółów do wyjaśnień, kiedy będę miał chwilę)


Tak więc, używając wyrażenia regularnego, aby zmienić wyrażenie nie-wyrażeniowe na wyrażenie regularne? coolio
— Matthew Roh

@Arnauld Rzeczywiście, dzięki. (Musiałem zbyt szybko przeczytać wyzwanie, moje złe). Musiałem podwoić liczbę bajtów, aby to naprawić, ale teraz działa!
— Dada

Czy nie byłoby bardziej golfowe generowanie wyrażenia regularnego (.)((?!\1).)\1\2((?!\1)(?!\2).)?
— Peter Taylor

@Peter Taylor może .. Niejasno o tym myślałem, ale wydawało mi się trudniejsze (więcej czytać) do wygenerowania. Spojrzę jeszcze raz, kiedy będę miał chwilę.
— Dada

@Peter Taylor nieważne, będzie o 30 bajtów krótszy; Za chwilę to zaktualizuję, dziękuję :)
— Dada

10

Galaretka , 9 bajtów

=þ
ẆÇ€ċÇ}

Zwraca liczbę przypadków znalezienia wzorca, przy czym niezerowe oznacza prawdę, a zero - fałsz.

Wypróbuj online!

Jak to działa

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

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>

Działa poprzez przekształcenie wzorca w wyrażenie regularne, np. Do XYXYZgenerowania /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

Zauważam ciekawe rozróżnienie między wyrażeniami regularnymi PCRE i JavaScript: w PCRE \<n>nie udaje się (i dlatego się (?!\<n>)udaje) przed zdefiniowaniem grupy przechwytywania, podczas gdy JavaScript z powodzeniem dopasowuje pusty ciąg (i dlatego się (?!\<n>)nie udaje).


7

Python 2 , 70 bajtów

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

Wypróbuj online!

Sprawdza, czy łańcuch pasuje do wzorca przy użyciu metody opisanej w tej odpowiedzi . Używa prefiksu szukanego ciągu, którego długość jest równa wzorowi. Odcina pierwszy znak ciągu znaków, dopóki nie zostanie znalezione dopasowanie lub Falsestanie się puste


73 bajty:

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

Wypróbuj online

Sprawdza, czy łańcuch pasuje do wzorca przy użyciu metody opisanej w tej odpowiedzi . Rekurencyjnie sprawdza wszystkie podciągi, rozgałęziając się w celu usunięcia pierwszego lub ostatniego znaku, aż łańcuch będzie pusty.



4

05AB1E , 19 16 bajtów

ÙœJv¹y…XYZ‡²åi1q

Wypróbuj 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.

Zwróci 1, jeśli prawda, zero, jeśli nie prawda.


Może to być 14 bajtów, jeśli dozwolone jest zwracanie możliwych wartości XYZ:

05AB1E , 14 bajtów

ÙœJv¹y…XYZ‡²å—

Wypróbuj online 2!


Zakładając, że niepusty łańcuch jest prawdziwy w 05AB1E i że pusty jest fałszem, twoja druga wersja powinna być zgodna ze specyfikacją.
— Dennis

1
Błędny wynik na wejściach „abcd” i „XYZZ”. Musisz dodać czwartą literę jako podstawienie domyślne.
— GB

@Dennis: Jeśli przejdziemy do meta postu, jedynymi prawdziwymi wartościami w 05AB1E są 1i True(co jest zwykle wadą dla tego rodzaju wyzwań), ale jeśli specyfikacja wyzwania może być interpretowana jako pozwalająca nam zdefiniować prawdę / fałsz dla wyzwania druga wersja działa tak, jak mówisz.
— Emigna,

@Emigna Och, nie byłem tego świadomy.
— Dennis

4

Java 7, 177 176 173 bajtów

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

Wyjaśnienie:

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

Kod testowy:

Wypróbuj tutaj.

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

Wydajność:

true
false
true
true
false

4

PHP, 89 bajtów

Prezent od @Christoph i @Titus

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

PHP, 105 bajtów

Prezent od @Christoph

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

PHP, 167 bajtów

[,$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
Powinieneś być w stanie zaoszczędzić 2 bajty, używając ++$pzamiast ($p+1), chociaż tak naprawdę go nie testowałem.
— user59178

1
Nie działa dla mnie: piaskownica . Zresztą golfed wersji kodu: [,$a,$b]=$argv;foreach(str_split($a)as$k=>$v)$r.=$k==($p=strpos($a,$v))?"(.)":"\\".++$p;echo preg_match("#$r#",$b);.
— Christoph

1
Weź to jako prezent: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Pamiętaj, że powinieneś zachować swoje stare wyniki <strike>)
— Christoph

1
@Christoph A Gift był wysiłkiem naukowym związanym z !. To jest bardziej warte niż punkty, do których mógłbym dotrzeć z twoim fajnym rozwiązaniem.
— Jörg Hülsermann

1
Liczę 109, a nie 108. -3 bajty, jeśli nie kopiujesz $argvdo $ai $b; -6 bajtów z for(;a&$v=$argv[1][$i++];); -1 bajt z dłuższymi nazwami zmiennych ( naprawdę! Use $vvzamiast $v, $iizamiast $i, $rrzamiast $r, $yyzamiast $ymożna użyć $$vvzamiast $x[$v])
— Titus

4

C #, 184 165 155 bajtów

dzięki 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;}

rozwiązanie cofania, jako bonus działa ze wzorem z dowolnymi postaciami!

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

Właśnie zauważyłem, że
— grałem w golfa, ujawniłem

2
Po pierwsze, dlaczego var s=l==n.Length;? Używasz go tylko w return s?!s:(gdzie !sjest zawsze false), więc możesz go zmienić na return l==n.Length?0>1:. Także, co to jest: (n[i]!=n[j]||n[i]!=n[j]). Sprawdzasz n[i]!=n[j]dwa razy .. Zawsze będzie true or true/ false or false..: S
— Kevin Cruijssen

Podwójne sprawdzenie faktycznie pozostało z większego systemu, który zniknął podczas gry w golfa, więc użyto go dużo, idę go ulepszyć. Dzięki!
— downrep_nation

Możesz dekalować wszystkie zmienne w jednym wierszuint l = p.Length,i = 0, j;
— aloisdg mówi: Przywróć Monikę

Może przenieść twoją i++i twoją j--wewnątrz pętli for. na przykład:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
— aloisdg mówi Przywróć Monikę

3

Rubin, 63 61 bajtów

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

Zamiast szukać wzorca wyrażenia regularnego, po prostu spróbuj podstawić „X”, „Y” i „Z” na wszystkie możliwe sposoby i znaleźć dosłowne dopasowanie.

(Właściwie to ta sama koncepcja, co odpowiedź 05AB1E firmy carusocomputing)


2

JavaScript (ES6), 92 89 87 86 bajtów

Pobiera dane wejściowe p(wzorzec) i s(ciąg) w składni curry (p)(s). Zwraca 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)

Sformatowane i skomentowane

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

Przypadki testowe

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

Matematyka 18 znaków (nie licząc łańcucha i wzoru)

StringContainsQ[string,pattern]

Przykłady:

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

True

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

True


Jest to nieprawidłowe, ponieważ nie przyjmuje ciągu i wzorca jako danych wejściowych ciągu, jeśli jest to wymagane.
— lirtosiast
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.