Basit kod golf mücadelesi: Karakter kalıpları!


22

Bu zorlukla, örneğin X, Y ve Z 'nin bir dizesini içeren girdi olarak bir string alırsınız. "XYZZ". X, Y ve Z, belirli bir karakteri temsil eder. Bu desen daha sonra ikinci bir dize girişi ile karşılaştırılır. Desen ikinci girişte bir alt çerçeve olarak mevcutsa, geri dönün True, aksi takdirde geri dönün False. Kelimede bir kalıp bulunduğunda, program aramayı durdurur ve geri döner True.

Örnekler

Model: "XXYY"

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

Model: "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • Not: Bu gerçek giriş değil. Bu programın nasıl çalışması gerektiğine bir örnektir. Programınız çıktı almalı Trueya Falseda diğer Truthy / Falsy değerlerini vermeli.

Diğer önemli / faydalı bilgiler

  • Desenin bir X, Y ve Z içermesi gerekmez, X ve Y'leri veya hatta (biraz anlamsız olsa da) sadece X'leri içerebilir.
  • Desen boş olamaz, ancak bu bir test durumu olarak kullanılmayacaktır.
  • Arama dizesi boş olmayacak ve küçük harf olacaktır.
  • Desendeki X, Y ve Z'nin alfabetik sırası önemli değildir.
  • X, Y ve Z benzersiz karakterler olmalıdır .
  • Dilediğiniz kütüphaneyi kullanabilirsiniz.
  • Puan bayt cinsinden kod büyüklüğüne göre belirlenir . En düşük puan kazanır.

İyi şanslar!


Desen herhangi bir şey olabilir. Muhtemelen, desenin bir X, Y ve Z'ye sahip olması gerekmediğini, sadece bir X ve Y'ye sahip olabileceğinden bahsetmeliydim. bu kalıplarla örnekler.
notHalfBad

Ne demek "desen var"? Bitişik bir öbek olarak mı? Bir substring olarak? Diyelim ki, X ve Y aynı şey için durabilir mi?
xnor

@xnor X ve Y birbirinden bağımsız olmalıdır ve var olan kalıptan kastettiğim, dizginin herhangi bir yerinde, kalıpla eşleşen bir alt dizenin olmasıdır. Bunları açıklığa kavuşturmak için sorun tanımıma ekleyeceğim.
notHalfBad

3
İlgili. (Aynı şey, ancak modelin tam eşleşmesi için sorulur, alt diziler için değil.)
Martin Ender,

4
Daha fazla detay: Desen boş olabilir mi? Arama dizesi? Arama dizgisinde sadece küçük harf kullanılacak mı? Desen, eşdeğer modeller arasında alfabetik olarak ilk olacak mı, yani önce X sonra Y, sonra Z kullanın?
xnor

Yanıtlar:


12

Perl 5 , 85 bayt

Peter Taylor'ın önerisi sayesinde 40 bayt kaydedildi! (farklılıkları görmek için eski sürümüme bakınız)

83 bayt kodu + -plbayrak.

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

Çevrimiçi deneyin!

XYXYZ dönüştürülür ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)( evet, testlerin bazıları doğru olamaz, ancak bu şekilde daha kısadır) ve ikinci giriş daha sonra bu regex'e karşı kontrol edilir. (nasıl çalıştığı hakkında daha fazla sezgi edinmek için eski sürümümün açıklamalarına bakın)


Eski
sürümüm : Arnauld'a ilk sürümümde yaptığım bir hatayı işaret ettiği için teşekkür ederim.
113 bayt kod + -plbayrakları ve -Mre=eval.

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

Çevrimiçi deneyin!

(). (). (.) Örnek XYXYZ üzerinde ilk normal ifade deseni dönüştürür \ 1 \ 2 ve sonunda kontrol etmek için bir test eklemek $1, $2ve $3farklıdır: bu nedenle, eğer $\bir ayarlanır. Ardından, ikinci giriş bu regex'e karşı test $\edilir ve sonunda yazdırılır.
XYXYZ için oluşturulan regex (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^.
(Bir dakikam olduğunda açıklamalara biraz daha ayrıntı ekleyeceğim)


Yani, regex'i regex'e çevirmek için kullanmak mı? coolio
Matthew Roh

@Arnauld Gerçekten, teşekkürler. (Mücadeleyi çok hızlı okumuş olmalıyım kötüüm). Düzeltmek için bayt sayısını ikiye katlamak zorunda kaldım, ancak şimdi çalışıyor!
Dada

Gibi bir regex oluşturmak için golfçü olmaz mıydı (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor

@Peter Taylor belki .. Belli belirsiz düşündüm, ama daha zor (daha uzun okundu) üretmek gibiydi .. Bir anım olduğunda başka bir göz atacağım.
Dada

Peter Taylor boşuna, 30 bayt daha kısa olacak; Bunu birazdan güncelleyeceğim, teşekkürler :)
Dada

10

Jöle , 9 bayt

=þ
ẆÇ€ċÇ}

Desenin bulunma sayısını, sıfır olmayanı gerçeğe yakın, sıfırı sahte olarak geri döndürür.

Çevrimiçi deneyin!

Nasıl çalışır

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

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>

İçin örneğin bir regexp'nin içine desen dönüştürerek Çalışır XYXYZoluşturduğu/(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/ .

PCRE ve JavaScript regexp arasında ilginç bir ayrım olduğunu fark ettim: PCRE'de, yakalama grubu tanımlanmadan önce \<n>başarısız olur (ve bu nedenle (?!\<n>)başarılı olur), JavaScript ise boş dizeyle başarılı bir şekilde eşleşir (ve bu nedenle (?!\<n>)başarısız olur).


7

Python 2,70 bayt

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

Çevrimiçi deneyin!

Bir dizginin bu cevaptaki yöntemi kullanarak bir kalıpla eşleşip eşleşmediğini kontrol eder . Uzunluğu kalıba eşit olan arama dizesinin önekini kullanır. Dize dizesinin ilk karakterini, bir eşleşme bulunana veya Falseboş kaldığında keser


73 bayt:

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

Çevrimiçi deneyin

Bir dizginin bu cevaptaki yöntemi kullanarak bir kalıpla eşleşip eşleşmediğini kontrol eder . Dize boşalana kadar ilk veya son karakteri çıkarmak için dallanma yaparak tüm alt dizileri tekrar tekrar kontrol eder.



4

05AB1E , 19 16 bayt

ÙœJv¹y…XYZ‡²åi1q

Çevrimiçi deneyin!


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

True olursa 1, true değilse null değerini döndürür.


XYZ'in olası değerlerinin döndürülmesine izin verilirse, bu 14 bayt olabilir:

05AB1E , 14 bayt

ÙœJv¹y…XYZ‡²å—

Çevrimiçi deneyin 2!


Boş olmayan bir dizginin 05AB1E'de kaba olduğu ve boş bir dizinin sahte olduğu varsayılarak, ikinci sürümünüz teknik özelliklere uygun olmalıdır.
Dennis,

1
"Abcd" ve "XYZZ" girişlerinde hatalı sonuç. Varsayılan bir seçenek olarak dördüncü bir harf eklemeniz gerekir.
GB

@Dennis: Meta postaya geçersek, 05AB1E'deki tek truthy değerleri ( 1ve Truebu tür zorluklar için genellikle bir dezavantajdır); ikinci versiyon dediğiniz gibi çalışıyor.
Emigna

@Emigna Oh, bunun farkında değildim.
Dennis,

4

Java 7, 177 176 173 bayt

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

Açıklama:

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

Test kodu:

Burada dene.

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

Çıktı:

true
false
true
true
false

4

PHP, 89 Bayt

@Christoph ve @ Titus'tan Bir Hediye

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

PHP, 105 Bayt

@ Christoph'tan Bir Hediye

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

PHP, 167 Bayt

[,$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
Bunu gerçekten test etmemiş olmama rağmen ++$pyerine 2 bayt kullanarak kaydedebilmelisiniz ($p+1).
user59178 14.03.2017

1
Benim için çalışmıyor: Sandbox . Neyse bir kod versiyonunu 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
Bunu hediye olarak alın: [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(Eski skorlarınızı kullanarak saklamanız gerektiğini unutmayın <strike>)
Christoph

1
@ Christoph Bir Hediye ile öğrenme çabasıydı !. Güzel çözümünüzle ulaşabileceğim noktalardan daha değerli.
Jörg Hülsermann 14:17

1
Ben 109 saymak değil, 108. -3 Eğer kopyasını düğünle eğer bayt $argviçin $ave $b; -6 bayt ile for(;a&$v=$argv[1][$i++];); Uzun değişken adları ile -1 bayt ( gerçekten! : Kullanım $vvyerine $v, $iiyerine $i, $rryerine $r, $yyyerine $ykullanabileceğiniz ve $$vvyerine $x[$v])
Titus

4

C # 184 165 155 bayt

teşekkürler 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;}

geri izleme çözümü, bonus olarak herhangi bir karakter içeren bir desenle çalışır!

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

Ben sadece ben kullanmadım, maruz
bırakma

2
Her şeyden önce, neden var s=l==n.Length;? Yalnızca return s?!s:( !sher zaman olduğu yerde false) kullanırsınız, böylece değiştirilebilir return l==n.Length?0>1:. Ayrıca, bu nedir: (n[i]!=n[j]||n[i]!=n[j]). n[i]!=n[j]İki kez kontrol edin .. Bu her zaman true or true/ false or false.. olacaktır: S
Kevin Cruijssen

Golf oynarken kaybolan bir sistem varsa, çift kontrol aslında daha büyük bir şey bıraktı, bu yüzden s de çok kullanıldı. Teşekkürler!
downrep_nation

Tüm değişkeninizi tek bir satırda int l = p.Length,i = 0, j;
çıkarabilirsiniz

Senin i++ve senin j--for döngü içinde taşıyabilir . örneğin:for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg diyor Reinstate Monica

3

Ruby, 63 61 bayt

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

Bir regex deseni aramak yerine, 'X', 'Y' ve 'Z' harflerini mümkün olan her şekilde değiştirmeyi deneyin ve değişmez bir eşleşme bulun.

(Aslında carusocomputing'in 05AB1E cevabı ile aynı kavram)


2

JavaScript (ES6), 92 89 87 86 bayt

Köreme sözdiziminde girdi p(desen) ve s(dize) alır (p)(s). Döndürür 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)

Biçimlendi ve yorumlandı

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

Test durumları

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 karakter (dize ve desen sayma)

StringContainsQ[string,pattern]

Örnekler:

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

True

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

True


Bu geçersiz, çünkü dize ve deseni gerektiği gibi dize girişleri olarak almıyor.
lirtosiast
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.