高尔夫简单代码挑战:角色模式!


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)
  • 注意:这不是实际输入。这是程序应如何工作的示例。您的程序应输出TrueFalse或其他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

Answers:


12

Perl 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
马修·

@Arnauld确实,谢谢。(我一定读得太快了,这太糟糕了)。不得不将字节数加倍以修复它,但现在可以正常工作!
达达

生成像这样的正则表达式会不会更高尔夫球手(.)((?!\1).)\1\2((?!\1)(?!\2).)
彼得·泰勒

@Peter Taylor也许..我含糊地想到了,但似乎很难(读得更长)。
达达

@Peter Taylor没关系,它要短30个字节;我会稍等一下,谢谢:)
Dada

10

果冻,9个字节

=þ
ẆÇ€ċÇ}

返回找到模式的次数,非零为真实,零为虚假。

在线尝试!

怎么运行的

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

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>

通过将模式转换成regexp来工作,例如为其XYXYZ产生/(.)(?!\1)(.)\1\2(?!\2)(?!\1)(.)/

我注意到PCRE和JavaScript regexp之间有一个有趣的区别:在PCRE中,在定义捕获组之前\<n>失败(因此(?!\<n>)成功),而JavaScript成功匹配空字符串(因此(?!\<n>)失败)。


7

Python 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

05AB1E19 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,否则返回null。


如果允许返回XYZ的可能值,则可以为14个字节:

05AB1E,14个字节

ÙœJv¹y…XYZ‡²å—

在线尝试2!


假设在05AB1E中一个非空字符串是真实的,而一个空字符串是虚假的,则您的第二个版本应符合规范。
丹尼斯

1
输入“ abcd”和“ XYZZ”的结果错误。您需要添加第四个字母作为默认替换。
GB

@丹尼斯:如果我们按中继文章进行操作,则05AB1E中唯一的真实值是1True(通常是这类挑战的缺点),但是如果挑战规范可以解释为允许我们为挑战定义真/假第二版如您所说。
Emigna '17

@Emigna哦,我没有意识到。
丹尼斯

4

Java 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字节

从A礼品@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 '17

1
不适用于我:Sandbox。无论如何,代码的高尔夫版本:[,$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“礼物”是的学习努力!。那么,用您好的解决方案可以达到的要点就更有价值。
约尔格Hülsermann

1
我算的是109,而不是108。如果您不复制$argv$a$b,则为-3个字节;-6个字节for(;a&$v=$argv[1][$i++];);-1个字节,具有更长的变量名(的确是这样!:使用$vv代替$v$ii代替$i$rr代替$r$yy代替,$y并且可以$$vv代替使用$x[$v]
Titus

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

我只是注意到打高尔夫球,它暴露了我没有使用过的逻辑,将很快更新
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
Kevin Cruijssen

双重检查实际上是从更大的if系统中遗留下来的,而该系统在高尔夫运动中消失了,因此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说,请恢复莫妮卡(Monica),2017年

3

Ruby,63 61字节

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

无需搜索正则表达式模式,只需尝试以所有可能的方式替换“ X”,“ Y”和“ Z”,然后找到文字匹配项即可。

(实际上与carusocomputing的05AB1E答案具有相同的概念)


2

JavaScript(ES6),92 89 87 86字节

采用currying语法输入p(pattern)和s(string)(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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.