간단한 코드 골프 도전 : 캐릭터 패턴!


22

이 과제에서 X, Y 및 Z의 문자열을 포함하는 입력으로 문자열을받습니다. "XYZZ". X, Y 및 Z는 특정 문자를 나타냅니다. 그런 다음이 패턴을 두 번째 문자열 입력과 비교합니다. 패턴이 두 번째 입력에 하위 문자열로 존재하면를 반환하고 True, 그렇지 않으면를 반환 False합니다. 단어에서 패턴이 발견되면 프로그램은 검색을 중지하고를 반환합니다 True.

패턴 : "XXYY"

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

패턴 : "XYXYZ"

bananas ---> True (pattern found: nanas)
banana  ---> False (pattern not found)
  • 참고 : 이것은 실제 입력이 아닙니다. 프로그램이 작동하는 방법의 예입니다. 프로그램은 True또는 False, 또는 다른 Truthy / Falsy 값을 출력해야 합니다.

다른 중요한 / 유용한 정보

  • 패턴은 X, Y 및 Z를 포함 할 필요가 없으며, X 및 Y를 포함하거나 심지어 X를 포함 할 수도 있습니다.
  • 패턴은 비워 둘 수 없지만 테스트 케이스로 사용되지는 않습니다.
  • 검색 문자열은 비어 있지 않으며 소문자입니다.
  • 패턴에서 X, Y 및 Z의 알파벳 순서는 중요하지 않습니다.
  • X, Y 및 Z 고유 한 문자 여야합니다 .
  • 원하는 라이브러리를 사용할 수 있습니다.
  • 점수는 코드 크기 ( 바이트 )로 결정됩니다 . 최저 점수가 이깁니다.

행운을 빕니다!


패턴은 무엇이든 될 수 있습니다. 패턴에 X, Y 및 Z가 필요하지 않고 X와 Y 만 있을 수 있다고 언급했을 것입니다 . 이러한 패턴은 단지 예일뿐입니다. 그러한 패턴을 가진 예제.
notHalfBad

"패턴이 존재"한다는 것은 무슨 뜻입니까? 연속적인 덩어리로? 부분 문자열로? 예를 들어 X와 Y가 같은 것을 의미 할 수 있습니까?
xnor

@ xnor X와 Y 서로 독립적 이어야 하며, 기존 패턴의 의미는 문자열의 어느 곳에 나 패턴과 일치하는 하위 문자열이 있다는 것입니다. 나는 이것을 명확히하기 위해 도전 과제 설명에 추가 할 것이다.
notHalfBad

3
관련. (동일하지만 하위 문자열이 아닌 패턴의 정확한 일치를 요구합니다.)
Martin Ender

4
자세한 내용 : 패턴을 비울 수 있습니까? 검색 문자열? 검색 문자열은 소문자 만 사용합니까? 등가 패턴 중에서 패턴이 알파벳순으로 표시됩니까? 예를 들어 X를 먼저 사용한 다음 Y를 Z로 사용합니까?
xnor

답변:


12

펄 5 , 85 바이트

Peter Taylor의 제안 덕분에 40 바이트가 절약되었습니다! (차이점을 보려면 이전 버전을 참조하십시오)

83 바이트의 코드 + -pl플래그.

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

온라인으로 사용해보십시오!

XYXYZ는 ((?!\1).)((?!\1)(?!\2).)\1\2((?!\1)(?!\2)(?!\3).)( 그렇지만 일부 테스트는 사실 일 수는 없지만 그렇게 짧습니다)로 변환되고 두 번째 입력은 해당 정규식에 대해 검사됩니다. (작동 방식에 대한 더 직관을 얻으려면 이전 버전의 설명을 참조하십시오)


내 이전 버전 :
첫 번째 버전에서 실수를 지적 해 준 Arnauld에게 감사합니다.
코드 + 113 바이트 -pl플래그 및 -Mre=eval.

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

온라인으로 사용해보십시오!

(.) (.) (.) 예제 XYXYZ의 제 정규식에 패턴으로 변환한다 \ 1 \ 2, 마지막에 있는지 확인하는 테스트를 추가 $1, $2$3다른 그래서, 만약 $\하나에 설정된다. 그런 다음 두 번째 입력은이 정규식에 대해 테스트 $\되며 끝 부분에 암시 적으로 인쇄됩니다.
XYXYZ에 대해 생성 된 정규식은 (.)(.)\1\2(.)(?{++$c;$\=1if!grep{$v{$c}{${$_}}++}1..3})^입니다.
(잠깐 시간을 내면 설명에 더 자세한 내용을 추가하겠습니다.)


그렇다면 정규식을 사용하여 비정규 식을 정규식으로 바꾸시겠습니까? coolio
Matthew Roh

@Arnauld 정말 감사합니다. (나의 도전을 너무 빨리 읽었을 것이다). 그것을 고치기 위해 바이트 수를 두 배로 늘 렸지만 지금은 작동합니다!
Dada

정규 표현식을 생성하는 것이 골퍼가 아닐까요 (.)((?!\1).)\1\2((?!\1)(?!\2).)?
Peter Taylor

@ 피터 테일러. 어쩌면 나는 그것을 모호하게 생각했지만 생성하기가 더 어려워 보였습니다.
Dada

@Peter Taylor는 신경 쓰지 않습니다. 30 바이트 더 짧아 질 것입니다. 감사합니다. :)
Dada

10

젤리 , 9 바이트

=þ
ẆÇ€ċÇ}

패턴이 발견 된 횟수를 리턴합니다. 0이 아닌 값은 진실이고 0은 거짓입니다.

온라인으로 사용해보십시오!

작동 원리

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

자바 스크립트 (ES6), 94 바이트

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>

패턴을 정규 표현식으로 변환하여 작동합니다 (예 : XYXYZ생성) /(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/.

PCRE와 JavaScript regexp 사이에 흥미로운 차이점이 있습니다. PCRE 에서는 캡처 그룹이 정의되기 전에 \<n>실패하고 (?!\<n>)성공 하므로 JavaScript는 빈 문자열과 성공적으로 일치하므로 (?!\<n>)실패합니다.


7

파이썬 2 , 70 바이트

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

온라인으로 사용해보십시오!

이 답변 의 메소드를 사용하여 문자열이 패턴과 일치하는지 확인합니다 . 길이가 패턴과 같은 검색 문자열의 접두사를 사용합니다. 일치하는 것을 찾을 때까지 또는 False비어있는 경우 문자열 문자열의 첫 문자를 잘라냅니다.


73 바이트 :

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

온라인으로 사용해보십시오

이 답변 의 메소드를 사용하여 문자열이 패턴과 일치하는지 확인합니다 . 문자열이 비워 질 때까지 첫 번째 또는 마지막 문자를 제거하여 분기하여 모든 하위 문자열을 재귀 적으로 검사합니다.



4

05AB1E , 19 16 바이트

ÙœJv¹y…XYZ‡²åi1q

온라인으로 사용해보십시오!


Ùœ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이면 1을 반환하고, true가 아니면 null을 반환합니다.


가능한 XYZ 값 리턴이 허용되는 경우 14 바이트 일 수 있습니다.

05AB1E , 14 바이트

ÙœJv¹y…XYZ‡²å—

온라인으로 사용해보십시오 2!


비어 있지 않은 문자열이 05AB1E에서 진실하고 빈 문자열이 거짓이라고 가정하면 두 번째 버전은 사양을 준수해야합니다.
Dennis

1
"abcd"및 "XYZZ"입력에 잘못된 결과가 있습니다. 기본 대용으로 네 번째 글자를 추가해야합니다.
GB

@Dennis : 메타 포스트 로 가면 05AB1E의 유일한 진실한 가치는 ( 1그리고 True이런 종류의 도전에 대한 단점)이지만 도전 과제가 우리가 도전에 대한 진실 / 거짓을 정의 할 수 있도록 해석 될 수 있다면 두 번째 버전은 말한대로 작동합니다.
Emigna

@Emigna 아, 나는 그것을 몰랐다.
Dennis

4

자바 7 177 176 173 바이트

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

설명:

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

테스트 코드 :

여기에서 시도하십시오.

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

산출:

true
false
true
true
false

4

PHP, 89 바이트

에서 선물 @Christoph@Titus

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

PHP, 105 바이트

@Christoph의 선물

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

PHP, 167 바이트

[,$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
실제로 테스트하지는 않았지만 ++$p대신을 사용하여 2 바이트를 절약 할 수 있어야 ($p+1)합니다.
user59178

1
나를 위해 작동하지 않습니다 : 샌드 박스 . 어쨌든 골프 버전의 코드 : [,$a,$b]=$argv;foreach(str_split($a)as$k=>$v)$r.=$k==($p=strpos($a,$v))?"(.)":"\\".++$p;echo preg_match("#$r#",$b);.
Christoph

1
이것을 선물로 가져 가십시오. [,$a,$b]=$argv;foreach(str_split($a)as$v)$r.=$x[$v]?"\\$x[$v]":'(.)'.!$x[$v]=++$y;echo preg_match("#$r#",$b);(을 사용하여 이전 점수를 유지해야 함 <strike>)
Christoph

1
@Christoph A Gift는의 학습 노력이었습니다 !. 멋진 솔루션으로 도달 할 수있는 포인트보다 가치가 있습니다.
Jörg Hülsermann

1
나는 109를 계산하지 (108) -3 당신이 사본을하지는 경우 바이트 $argv$a$b; for(;a&$v=$argv[1][$i++];); -6 바이트 더 이상 변수 이름을 가진 -1 바이트 ( 참! : 사용 $vv하는 대신 $v, $ii대신 $i, $rr대신 $r, $yy대신 $y사용할 수 있으며, $$vv대신 $x[$v])
디도

4

C #을 184 165 155 바이트

감사합니다 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;}

역 추적 솔루션, 보너스로 모든 캐릭터의 패턴과 함께 작동합니다!

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

난 그냥 내가 didnt 한 사용, 곧 업데이트됩니다 논리를 노출 골프 눈치
downrep_nation

2
우선, 왜 var s=l==n.Length;? 당신은 그것을 사용 return s?!s:(여기서 !s항상 false이 변경 될 수 있습니다) return l==n.Length?0>1:. 또한 이것은 무엇입니까 : (n[i]!=n[j]||n[i]!=n[j]). 당신은 n[i]!=n[j]두 번 확인 .. 이것은 항상 true or true/ false or false.. : S
케빈 크루이 센

더블 체크는 실제로 골프에서 사라진 시스템이 더 큰 경우에 실제로 남았으므로 s가 많이 사용되었으므로 더 향상시킬 것입니다. 감사!
downrep_nation

당신은 한 줄에 모든 변수를 decalre 수int l = p.Length,i = 0, j;
aloisdg는 분석 재개 모니카 말한다

for 루프 내부 i++j--내부를 이동할 수 있습니다 . 예 :for(j=i;j>=0;)if(p[i]==p[j]==(n[i]!=n[j--]))
aloisdg는 Reinstate Monica

3

루비, 63 61 바이트

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

정규식 패턴을 검색하는 대신 가능한 모든 방법으로 'X', 'Y'및 'Z'를 대체하고 리터럴 일치를 찾으십시오.

(실제로 carusocomputing의 05AB1E 답변과 동일한 개념)


2

자바 스크립트 (ES6), 92 89 87 86 바이트

카레 구문에서 입력 p(패턴) 및 s(문자열)을 사용합니다 (p)(s). 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)

형식화 및 의견

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

테스트 사례

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 자 (문자열 및 패턴 제외)

StringContainsQ[string,pattern]

예 :

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

True

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

True


필요에 따라 문자열과 패턴을 문자열 입력으로 사용하지 않기 때문에 유효하지 않습니다.
lirtosiast
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.