“ a”和“ b”的数量必须相等。你有电脑吗?


75

在彼得·林茨(Peter Linz )的一本流行(且必不可少的)计算机科学书籍《形式语言和自动机简介》中,经常提到以下形式语言:

定义

主要是因为无法使用有限状态自动机处理该语言。此表达式的意思是“语言L由'a'的所有字符串组成,后跟'b',其中'a'和'b'的数量相等且非零”。

挑战

编写一个工作程序/函数,该程序将获取仅包含“ a”和“ b”的字符串作为输入,并返回/输出真值,并说出该字符串是否对形式语言L有效。

  • 您的程序不能使用任何外部计算工具,包括网络,外部程序等。Shell是此规则的例外;例如,Bash可以使用命令行实用程序。

  • 您的程序必须以“逻辑”方式返回/输出结果,例如:返回10而不是0,“哔”声,输出到stdout等。此处有更多信息。

  • 适用标准代码高尔夫规则。

这是一个。以字节为单位的最短代码获胜。祝好运!

真实的测试案例

"ab"
"aabb"
"aaabbb"
"aaaabbbb"
"aaaaabbbbb"
"aaaaaabbbbbb"

虚假的测试用例

""
"a"
"b"
"aa"
"ba"
"bb"
"aaa"
"aab"
"aba"
"abb"
"baa"
"bab"
"bba"
"bbb"
"aaaa"
"aaab"
"aaba"
"abaa"
"abab"
"abba"
"abbb"
"baaa"
"baab"
"baba"
"babb"
"bbaa"
"bbab"
"bbba"
"bbbb"

24
在可以输入是空的?(您是说这不是语言的一部分,但不是我们是否需要考虑的输入。)
Martin Ender

1
如果我们的语言不讲真话又怎么办?将empty string == truthynon-empty string == falsy是否可以接受?
DJMcMayhem

5
很好的挑战,但我认为标题可能不太含糊(即提及a^n b^n或相似,而不仅仅是as的数量等于s的数量b
Sp3000 2016年

1
@ Sp3000我选择这个标题是因为它看起来很有趣。我可能稍后

1
令我感到惊讶的是,在50多个答案中,我是唯一使用paser生成器的人。为了确保它在长度上不是严格的竞争,但是提出的问题是解析一种简单但不平凡的语言之一。我非常想在其他编译器-编译器语法中看到答案,因为我对选择不很熟悉。
dmckee '16

Answers:


34

MATL5 4字节

tSP-

如果字符串属于L,则输出一个1 s 的非空数组,否则输出一个空数组或一个0 s 的数组(均为falsy)。

感谢@LuisMendo高尔夫球1个字节!

在线尝试!

这个怎么运作

t      Push a copy of the implicitly read input.
 S     Sort the copy.
  P    Reverse the sorted copy.
   -   Take the difference of the code point of the corresponding characters
       of the sorted string and the original.

6
我的第二个(有效的)MATL答案。:)
丹尼斯

2
真理和虚假的奇怪定义:“ aabb”给出-1 -1 1 1是真理。'aaabb'给出-1 -1 0 1 1并且是虚假的
Etoplay '16

3
@Etoplay一个其所有值都不为零的非空数组是正确的。这是Matlab和Octave中使用的定义
Luis Mendo

145

Python 3,32个字节

eval(input().translate(")("*50))

通过退出代码输出:错误为false,错误为True。

该字符串被评价为Python代码,替换括号(a)b。只有该形式的表达式才能a^n b^n成为格式正确的括号表达式,例如((()))对元组求值()

(()())由于不存在分隔符,任何不匹配的括号都会产生错误,多个组(如)也会出现错误。空字符串也会失败(它将在上成功exec)。

转换( -> a) -> b使用完成str.translate,通过充当转换表中的字符串所表示它取代字符。给定100个长度的字符串“)(” * 50“,这些表将前100个ASCII值映射为

... Z[\]^_`abc
... )()()()()(

这需要( -> a) -> b。在Python 2中,必须提供对所有256个ASCII值的转换,要求"ab"*128长1个字节;感谢isaacg指出了这一点。


58
好吧,那很聪明。
TLW


5
128可以替换为50(或99就此而言)以节省一个字节。
isaacg '16

@EʀɪᴋGᴏʟғᴇʀ:我认为这是一个量词。但是我并不是很了解Python,也没有找到任何文档。
泰特斯(Titus)

4
@isaacg谢谢,我不知道Python 3的更改了。–
xnor

28

视网膜,12字节

归功于独立找到此解决方案的FryAmTheEggman。

+`a;?b
;
^;$

打印1有效输入,0否则输出。

在线尝试!(第一行启用换行分隔的测试套件。)

说明

平衡组需要昂贵的语法,因此我试图将有效输入减少为简单形式。

阶段1

+`a;?b
;

+告诉视网膜重复此阶段的循环,直到输出停止变化。它与ab或匹配,a;b并用替换;。让我们考虑几种情况:

  • 如果aS和b字符串s中没有在相同的方式,平衡()正常需要是,一些ab将保持在字符串中,因为ba,或b;a不能得到解决,一个ab自身不能要么。要摆脱所有as和bs,必须有一个对应b于每个s 的权利a
  • 如果ab都不都是嵌套的(例如,如果我们有类似abab或的嵌套aabaabbb),那么我们将得到多个;(可能还有as和bs),因为第一次迭代将找到多个abs来插入它们,并且进一步的迭代将保留;字符串中的数字。

因此,当且仅当输入为形式时,我们才会在字符串中以单个结尾。anbn;

阶段2:

^;$

检查结果字符串是否仅包含一个分号。(当我说“ check”时,我的意思是“计算给定正则表达式的匹配次数,但是由于锚点,该正则表达式最多可以匹配一次,因此给出01。)


25

Haskell,31个字节

f s=s==[c|c<-"ab",'a'<-s]&&s>""

该列表理解[c|c<-"ab",'a'<-s]做一个串'a'的每个'a's,后面跟着一个'b'每个'a's。通过避免对一个常数进行匹配并为每次匹配生成一个输出,可以避免计数。

检查此字符串是否等于原始字符串,并检查原始字符串为非空。


好可爱 我经常忘记Haskell以一致且非常特定的方式对列表理解的元素进行排序有多么有用。
Vectornaut

比我的最佳尝试(f=g.span id.map(=='a');g(a,b)=or a&&b==(not<$>a))好得多。做得好。
Jules

哇,我不知道一个人可以在列表理解中匹配一个常数!
Rubik '16

16

污垢,12字节

A=\aA?\b
e`A

在线尝试!

说明

第一行定义一个非终结符A,它匹配一个字母a(可能是非终结符)A,然后匹配一个字母b。第二行将整个输入(e)与非终结符匹配A

8字节非竞争版本

e`\a_?\b

在编写了该答案的第一个版本之后,我更新了Grime以将其视为_顶级表达式的名称。此解决方案与上述相同,但是避免了重复标签A


为什么不用J做呢?
Leaky Nun

@LeakyNun我只是想炫耀Grime。:P
Zgarb '16

您建立了这种语言?
Leaky Nun

@LeakyNun是的。发展缓慢,但仍在持续。
Zgarb

11

Brachylog23 19字节

@2L,?lye:"ab"rz:jaL

在线尝试!

说明

@2L,                  Split the input in two, the list containing the two halves is L
    ?lye              Take a number I between 0 and the length of the input              
        :"ab"rz       Zip the string "ab" with that number, resulting in [["a":I]:["b":I]]
               :jaL   Apply juxtapose with that zip as input and L as output
                        i.e. "a" concatenated I times to itself makes the first string of L
                        and "b" concatenated I times to itself makes the second string of L

8
祝贺您加入tryitonline.net!
Leaky Nun

10

05AB1E,9个字节

码:

.M{J¹ÔQ0r

说明:

.M         # Get the most frequent element from the input. If the count is equal, this
           results into ['a', 'b'] or ['b', 'a'].
  {        # Sort this list, which should result into ['a', 'b'].
   J       # Join this list.
    Ô      # Connected uniquified. E.g. "aaabbb" -> "ab" and "aabbaa" -> "aba".
     Q     # Check if both strings are equal.
      0r   # (Print 0 if the input is empty).

如果保证输入为非空,则可以丢弃最后两个字节。

使用CP-1252编码。在线尝试!


空输入会怎样?
AdmBorkBork '16

2
在帖子中查找非零值;它在里面:)
林恩

@Lynn规范不是只对有效语言说不为零吗?与输入无关。
Emigna '16

真正。那里想错了。但是您仍然可以.M{J¹ÔQ0r为自己的。
Emigna '16

@Emigna谢谢,我已经编辑了帖子。
阿德南

9

果冻,6 个字节

Ṣ=Ṛ¬Pȧ

如果字符串属于L或为空,则打印字符串本身,否则为0

在线尝试!验证所有测试用例

这个怎么运作

Ṣ=Ṛ¬Pȧ  Main link. Argument: s (string)

Ṣ       Yield s, sorted.
  Ṛ     Yield s, reversed.
 =      Compare each character of sorted s with each character of reversed s.
   ¬    Take the logical NOT of each resulting Boolean.
    P   Take the product of the resulting Booleans.
        This will yield 1 if s ∊ L or s == "", and 0 otherwise.
     ȧ  Take the logical AND with s.
       This will replace 1 with s. Since an empty string is falsy in Jelly,
       the result is still correct if s == "".

备用版本,4字节(无竞争)

ṢnṚȦ

打印10在线尝试!验证所有测试用例

这个怎么运作

ṢnṚȦ  Main link. Argument: s (string)

Ṣ     Yield s, sorted.
  Ṛ   Yield s, reversed.
 n    Compare each character of the results, returning 1 iff they're not equal.
   Ȧ  All (Octave-style truthy); return 1 if the list is non-empty and all numbers
      are non-zero, 0 in all other cases.

9

J,17个字节

#<.(-:'ab'#~-:@#)

这可以正确地为空字符串提供falsey。错误是错误的。

旧版本:

-:'ab'#~-:@#
2&#-:'ab'#~#   NB. thanks to miles

证明与解释

主要动词是包含以下三个动词的叉子:

# <. (-:'ab'#~-:@#)

意思是,“(<.)中的较小值是长度(#)和右叉((-:'ab'#~-:@#))的结果”。

右叉是4列,包括:

(-:) ('ab') (#~) (-:@#)

让我们k代表我们的输入。然后,这等效于:

k -: ('ab' #~ -:@#) k

-:是match运算符,因此-:对monadic fork下的不变性进行前导检验'ab' #~ -:@#

由于fork的左齿是动词,因此它成为常数函数。因此,fork等效于:

'ab' #~ (-:@# k)

叉的右齿将(-:)的长度(#)减半k。观察#

   1 # 'ab'
'ab'
   2 # 'ab'
'aabb'
   3 # 'ab'
'aaabbb'
   'ab' #~ 3
'aaabbb'

现在,这k仅在有效输入上,因此我们在这里完成了。永远无法满足语言要求的#奇数长度字符串错误,因此我们也完成了。

再加上较小的长度和这个长度,空字符串(它不是我们的语言的一部分)产生其长度0,然后我们就完成了所有工作。


我对其进行了修改2&#-:'ab'#~#,应避免出现该错误,而仅0在使用12个字节的情况下才输出。
英里

@miles令人着迷!我从来没有那样想过。
科纳·奥布莱恩,

这会处理空字符串吗?
Zgarb

@Zgarb修复了!
科纳·奥布莱恩,2016年

9

Bison / YACC 60(或29)字节

(嗯,YACC程序的编译仅需几个步骤,因此可能需要包括一些步骤。有关详细信息,请参见下文。)

%%
l:c'\n';
c:'a''b'|'a'c'b';
%%
yylex(){return getchar();}

如果您知道要用形式语法来解释功能,则该功能应该相当明显。解析器接受ab或,a后接任何可接受的序列,后接b

此实现依赖于接受K&R语义以丢失一些字符的编译器。

它比我想要定义yylex和调用要复杂getchar

编译

$ yacc equal.yacc
$ gcc -m64 --std=c89 y.tab.c -o equal -L/usr/local/opt/bison/lib/ -ly

(gcc的大多数选项都是特定于我的系统的,不应计入字节数;您可能想对将-std=c89其加8的值进行计数)。

与运行

$ echo "aabb" | ./equal

或同等学历。

真值返回给操作系统,错误也报告syntax error给命令行。如果我只能计算定义解析功能的那部分代码(忽略第二个%%及其后的所有内容),那么我得到的计数为29个字节。


7

Perl 5.10的,35 17个字节(带-n标志)

say/^(a(?1)?b)$/

确保字符串以as 开头,然后在bs上递归。仅当两个长度相等时才匹配。

感谢Martin Ender将字节数减半并教了我一些有关正则表达式中递归的知识:D

如果匹配则返回整个字符串,否则返回任何字符串。

在这里尝试!


我可以管理的最接近的非空测试用例是18个字节:($_&&=y/a//==y/b//需要-p),没有空,您可以丢弃&&16 个字节!如此近...
Dom Hastings

1
所以我可以再做17个字节:echo -n 'aaabbb'|perl -pe '$_+=y/a//==y/b//'但是我不能再移位一个字节……可能不得不放弃这一点!
Dom Hastings

7

JavaScript,54 55 44

s=>s&&s.match(`^a{${l=s.length/2}}b{${l}}$`)

根据字符串的长度构建一个简单的正则表达式并对其进行测试。对于长度为4的字符串(aabb),正则表达式如下所示:^a{2}b{2}$

返回真实或错误的值。

感谢Neil,节省了11个字节。

f=s=>s&&s.match(`^a{${l=s.length/2}}b{${l}}$`)
// true
console.log(f('ab'), !!f('ab'))
console.log(f('aabb'), !!f('aabb'))
console.log(f('aaaaabbbbb'), !!f('aaaaabbbbb'))
// false
console.log(f('a'), !!f('a'))
console.log(f('b'), !!f('b'))
console.log(f('ba'), !!f('ba'))
console.log(f('aaab'), !!f('aaab'))
console.log(f('ababab'), !!f('ababab'))
console.log(f('c'), !!f('c'))
console.log(f('abc'), !!f('abc'))
console.log(f(''), !!f(''))


f=可被省略。
Leaky Nun

函数表达式是有效的提交,还是实际上必须是函数式的?
Scimonster '16

功能是有效的提交。
Leaky Nun

@TimmyD它曾经返回true,但是现在返回false。
Scimonster '16

1
s=>s.match(`^a{${s.length/2}}b+$`)
l4m2 '18年

5

C,57 53字节

t;x(char*s){t+=*s%2*2;return--t?*s&&x(s+1):*s*!1[s];}

旧的57个字节长的解决方案:

t;x(char*s){*s&1&&(t+=2);return--t?*s&&x(s+1):*s&&!1[s];}

与gcc v.8.2.2 @Ubuntu一起编译

感谢ugoren的提示!

在Ideone上尝试!


由于我是新来的,还不能评论其他答案,所以我只想指出,@ Josh的62b解决方案对诸如“ aaabab”之类的字符串提供了误报。
雅斯(Jasmes)2016年

更改(t+=2)t++++为-1字节。
owacoder

@owacoder t++++不是有效的C代码。
雅斯(Jasmes)2016年

与保存一些t+=*s%2*2:*s*!1[s]
ugoren

很聪明的答案!不幸的是,它确实在输入“ ba”上失败:ideone.com/yxixG2
Josh

4

视网膜,22字节

另一个用相同语言的简短答案就来了...

^(a)+(?<-1>b)+(?(1)c)$

在线尝试!

这是regex平衡组的展示,Martin Ender对此做了充分解释

由于我的解释还不能接近它的一半,因此我将仅链接到它,而不是试图进行解释,因为这将不利于他的解释的荣耀。


4

Befunge-93,67个字节

0v@.<  0<@.!-$<  >0\v
+>~:0`!#^_:"a" -#^_$ 1
~+1_^#!-"b" _ ^#`0: <

在这里尝试!可能稍后再解释。可能还会尝试多打一点高尔夫球,只是为了踢球。


3

MATL,9个字节

vHI$e!d1=

在线尝试!

如果输出数组为非空且其所有条目均为非零,则为true。否则是虚假的。这里有一些例子

v     % concatenate the stack. Since it's empty, pushes the empty array, []
H     % push 2
I$    % specify three inputs for next function
e     % reshape(input, [], 2): this takes the input implicitly and reshapes it in 2
      % columns in column major order. If the input has odd length a zero is padded at
      % the end. For input 'aaabbb' this gives the 2D char array ['ab;'ab';'ab']
!     % transpose. This gives ['aaa;'bbb']
d     % difference along each column
1=    % test if all elements are 1. If so, that means the first tow contains 'a' and
      % the second 'b'. Implicitly display

2
这是对真理的一些方便定义。(我知道非零要求,但不知道非空要求。)
Dennis

3

x86机器代码,29 27字节

十六进制转储:

33 c0 40 41 80 79 ff 61 74 f8 48 41 80 79 fe 62
74 f8 0a 41 fe f7 d8 1b c0 40 c3

汇编代码:

    xor eax, eax;
loop1:
    inc eax;
    inc ecx;
    cmp byte ptr [ecx-1], 'a';
    je loop1;

loop2:
    dec eax;
    inc ecx;
    cmp byte ptr [ecx-2], 'b';
    je loop2;

    or al, [ecx-2];
    neg eax;
    sbb eax, eax;
    inc eax;
done:
    ret;

a在开始的字节上进行迭代,然后在随后的“ b”字节上进行迭代。第一个循环增加一个计数器,第二个循环减少它。然后,在以下条件之间进行按位或运算:

  1. 如果计数器末尾不为0,则字符串不匹配
  2. 如果跟随bs 序列的字节不为0,则字符串也不匹配

然后,它必须“倒置”其中的真值eax-如果不为0,则将其设置为0,反之亦然。事实证明,执行此操作最短的代码是以下5字节代码,我从C ++编译器的输出中窃取了以下代码result = (result == 0)

    neg eax;      // negate eax; set C flag to 1 if it was nonzero
    sbb eax, eax; // subtract eax and the C flag from eax
    inc eax;      // increase eax

1
我认为您可以改善自己的否定态度。尝试:neg eax像以前一样设置进位标志,cmc反转进位标志并将salcAL设置为FFh或0,具体取决于是否设置了进位标志。保存2个字节,尽管最终会得到8位而不是32位的结果。
Jules

使用字符串操作的同一件事,ESI指向输入字符串,并在AL中返回结果(使用SETcc,需要386+):xor eax,eax | xor ecx,ecx | l1: inc ecx | lodsb | cmp al, 'a' | jz l1 | dec esi | l2: lodsb | cmp al,'b' | loopz l2 | or eax,ecx | setz al | ret
ninjalj 2016年

@ninjalj您应该在答案中发布它-它与我的有足够的不同,我怀疑它明显更短了!
anatolyg

3

Ruby,24个字节

eval(gets.tr'ab','[]')*1

(这只是xnor以Ruby形式提出的绝妙想法我的另一个答案是我实际上一个解决方案。)

该程序将输入,转换a并转换b[]分别和,然后对其求值。

有效输入将形成一个嵌套数组,并且什么也不会发生。不平衡的表达式会使程序崩溃。在Ruby中,空输入的值为nil,由于nil未定义*方法而将崩溃。


3

Sed,38 + 2 = 40字节

s/.*/c&d/;:x;s/ca(.*)bd/c\1d/;tx;/cd/p

非空字符串输出是正确的

有限状态自动机不能做到这一点,你说呢?带有循环的有限状态自动机呢??:P

使用rn标志运行。

说明

s/.*/c&d/        #Wrap the input in 'c' and 'd' (used as markers)
:x               #Define a label named 'x'
s/ca(.*)bd/c\1d/ #Deletes 'a's preceded by 'c's and equivalently for 'b's and 'd's. This shifts the markers to the center
tx               #If the previous substitution was made, jump to label x
/cd/p            #If the markers are next to one another, print the string

好的方法。感谢您的细分。
joeytwiddle

3

JavaScript,44 42

划掉44仍然是常规44;(

f=s=>(z=s.match`^a(.+)b$`)?f(z[1]):s=="ab"

通过递归地剥离外部ab使用选择的内部值递归地工作.+。如果^a.+b$左边没有匹配项,则最终结果是剩余的字符串是否为准确值ab

测试用例:

console.log(["ab","aabb","aaabbb","aaaabbbb","aaaaabbbbb","aaaaaabbbbbb"].every(f) == true)
console.log(["","a","b","aa","ba","bb","aaa","aab","aba","abb","baa","bab","bba","bbb","aaaa","aaab","aaba","abaa","abab","abba","abbb","baaa","baab","baba","babb","bbaa","bbab","bbba","bbbb"].some(f) == false)

3

ANTLR,31个字节

grammar A;r:'ab'|'a'r'b'|r'\n';

使用与@dmckee的YACC答案相同的概念,但打高尔夫球的次数略多一些。

要进行测试,请遵循ANTLR的入门教程中的步骤。然后,将上面的代码放入一个名为的文件中A.g4并运行以下命令:

$ antlr A.g4
$ javac A*.java

然后通过在STDIN上输入以下内容进行测试grun A r

$ echo "aaabbb" | grun A r

如果输入有效,则不会输出任何内容。如果它是无效的,grun会给出错误(或者token recognition errorextraneous inputmismatched input,或者no viable alternative)。

用法示例:

$ echo "aabb" | grun A r
$ echo "abbb" | grun A r
line 1:2 mismatched input 'b' expecting {<EOF>, '
'}

巧妙的技巧将换行符添加为单个规则中的备用行。我想我也可以在yacc中保存一些方法。不过,该grammer关键字对于与antlr打高尔夫球是一个恶臭。Kinda喜欢使用fortran
dmckee

3

C,69字节

69个字节:

#define f(s)strlen(s)==2*strcspn(s,"b")&strrchr(s,97)+1==strchr(s,98)

对于那些不熟悉的人:

  • strlen 确定字符串的长度
  • strcspn 返回找到另一个字符串的字符串中的第一个索引
  • strchr 返回指向字符首次出现的指针
  • strrchr 返回一个指向字符最后一次出现的指针

非常感谢Titus!


1
保存一个字节,>97而不是==98
Titus

2
61字节的解决方案对诸如“ aaabab”之类的字符串给出了误报。参见ideone.com/nmT8rm
詹姆斯(

啊,你是正确的茉莉,谢谢。我将不得不重新考虑一下。
乔什(Josh)2016年

返回到69字节的解决方案,不确定使用这种方法是否可以缩短时间。
乔什(Josh)2016年

3

R,64 61 55字节,73 67字节(健壮)或46字节(如果允许空字符串)

  1. 再次,xnor的答案重做。如果规则暗示输入将包含as和bs 字符串,则它应该起作用:如果表达式有效,则返回NULL并抛出错误,否则不返回任何值。

    if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
    
  2. 如果输入不是健壮的并且可能包含一些垃圾,例如aa3bb,则应考虑使用以下版本(TRUE对于真正的测试用例,必须返回,而不是NULL):

    if(length(y<-scan(,'')))is.null(eval(parse(t=chartr("ab","{}",y))))
    
  3. 最后,如果允许使用空字符串,我们可以忽略非空输入的条件:

    eval(parse(text=chartr("ab","{}",scan(,''))))
    

    同样,如果成功则为NULL,否则为其他任何值。


我不知道R,空输入的结果是什么?(应该是虚假的)
泰特斯

真的没有更短的方法来测试空输入吗?
泰特斯(Titus)

版本1:根本不值一提(正确输入只返回NULL),第2版:根本不值一提(正确输入只返回TRUE),第3版(假设空字符串都OK,因为状态): NULL。R是一种面向对象的统计语言,可以对所有内容进行类型转换,而不会发出任何警告。
安德烈KOSTYRKA

这个(答案1)可以进一步提高到55个字节:if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
Giuseppe

3

Japt,11个字节

©¬n eȦUg~Y

在线尝试!

给出truefalse,除非""给出""在JS中是虚假的。

开箱及其工作方式

U&&Uq n eXYZ{X!=Ug~Y

U&&     The input string is not empty, and...
Uq n    Convert to array of chars and sort
eXYZ{   Does every element satisfy...?
X!=       The sorted char does not equal...
Ug~Y      the char at the same position on the original string reversed

Dennis的MATL解决方案中采用


2

C(Ansi),65 75字节

打高尔夫球:

l(b,i,j,k)char*b;{for(i=j=0;(k=b[i++])>0&k<=b[i];)j+=2*(k>97)-1;return !j;}

说明:

设置值j并在每个b上递增j,在其他任何值上递减j。检查前面的字母是否小于或等于下一个字母,以防止Abab工作

编辑

添加了对abab病例的检查。


这不会给像ba或这样的字符串带来误报abab吗?
Zgarb

嗯,是的,我误读了该帖子,因为它被我挡住了,所以看不到它。修复它!
dj0wns

2

批处理,133字节

@if ""=="%1" exit/b1        Fail if the input is empty
@set a=%1                   Grab the input into a variable for processing
@set b=%a:ab=%              Remove all `ab` substrings
@if "%a%"=="%b%" exit/b1    Fail if we didn't remove anything
@if not %a%==a%b%b exit/b1  Fail if we removed more than one `ab`
@if ""=="%b%" exit/b0       Success if there's nothing left to check
@%0 %b%                     Rinse and repeat

ERRORLEVEL成功返回0,失败返回1。Batch不喜欢对空字符串进行子字符串替换,因此我们必须预先检查;如果空参数合法,则不需要第6行。


2

PowerShell v2 +,61 52字节

param($n)$x=$n.length/2;$n-and$n-match"^a{$x}b{$x}$"

将输入$n作为字符串,创建$xhalf the length。构造一个-and之间布尔比较$n-match针对相等数目的正则表达式的正则表达式算子a的和b的。输出布尔值$TRUE$FALSE。其中$n-and存在""= $FALSE

备用,35个字节

$args-match'^(a)+(?<-1>b)+(?(1)c)$'

这基于Leaky的答案中的正则表达式,它基于封装在PowerShell -match运算符中的.NET平衡组。返回真值字符串,或假值字符串为空。


在你应该评估替代版本-match反对$args[0],否则-match将作为过滤器
马蒂亚斯R.杰森

@ MathiasR.Jessen是的,在生产代码中,但是我们可以在[0]这里打高尔夫,因为我们只得到一个输入,而只需要一个true / false值作为输出。由于空字符串为假,非空字符串为真,因此我们可以对数组进行过滤,并返回输入字符串或不返回任何内容,这满足了挑战性要求。
AdmBorkBork '16

2

Pyth-13个字节

&zqzS*/lz2"ab

解释:

  qz          #is input equal to
          "ab #the string "ab"
     *        #multiplied by
      /lz2    #length of input / 2
    S         #and sorted?
&z            #(implicitly) print if the above is true and z is not empty

您可以使用字符串作为输入,然后输入字符串&qS*/lQ2"ab
Leaky Nun

@LeakyNun感谢您的提示!您能解释一下这是为什么/为什么吗?这是我第一次使用Pyth
Cowabunghole

例如,+4将扩展为+4Q(隐式填充参数)
Leaky Nun

2

Haskell,39个字节

p x=elem x$scanl(\s _->'a':s++"b")"ab"x

用法示例:p "aabb"-> True

scanl(\s _->'a':s++"b")"ab"x建立所有的名单["ab", "aabb", "aaabbb", ...],总的(length x)元素。elem检查是否x在此列表中。


2

Python,43个 40字节

lambda s:''<s==len(s)/2*"a"+len(s)/2*"b"

感谢Leaky Nun考虑了明显的解决方案

其他想法,45个字节:

lambda s:s and list(s)==sorted(len(s)/2*"ab")

通过使用len / 2 -4个字节(当最后一半出现时我得到一个错误)

现在为空字符串给出false

-3个字节感谢xnor


是的,lambda不必命名。
Leaky Nun

lambda s:list(s)==sorted("ab"*len(s)//2)(Python 3)
Leaky Nun

lambda s:s=="a"*len(s)//2+"b"*len(s)//2(Python 3)
Leaky Nun

是的,我在发布时意识到了这一点。大声笑,明显的解决方案在Python 2中更短:
KarlKastor

1
您可以''<代替s and排除空白情况。
xnor
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.