Кількість “a” s та “b” s має бути рівним. Ви придбали комп'ютер?


75

У популярній (і найважливішій) книзі з інформатики «Вступ до формальних мов та автоматів » Пітера Лінца часто зазначається така формальна мова:

визначення

головним чином через те, що цю мову не можна обробити автоматами з кінцевим станом. Цей вираз означає "Мова L складається з усіх рядків 'a', за якими 'b', в яких кількість 'a' і 'b' є рівними і не нульовими".

Виклик

Напишіть робочу програму / функцію, яка отримує рядок, що містить лише "a" і "b" s , як введення та повернення / виведення значення істинності , кажучи, що ця строка є дійсною формальною мовою L.

  • Ваша програма не може використовувати будь-які зовнішні інструменти обчислення, включаючи мережу, зовнішні програми тощо. Оболонки - виняток із цього правила; Bash, наприклад, може використовувати утиліти командного рядка.

  • Ваша програма повинна повернути / вивести результат "логічним" способом, наприклад: повернення 10 замість 0, "звуковий сигнал", виведення в режим stdout тощо. Докладніше тут.

  • Діють стандартні правила гольф-коду.

Це . Виграє найкоротший код у байтах. Удачі!

Пробні кейси Truthy

"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
Чи може вхід бути порожнім? (Ви говорите, що це не частина мови, але не те, чи потрібно це врахувати.)
Мартін Ендер

1
Що робити, якщо в нашій мові немає правди чи хибності? Було б empty string == truthyі non-empty string == falsyбуло б прийнятним?
DJMcMayhem

5
Хороший виклик, але я думаю, що заголовок може бути трохи менш неоднозначним (тобто згадка про a^n b^nподібне чи подібне, а не просто число as, що дорівнює кількості bs)
Sp3000

1
@ Sp3000 Я вибрав цю назву, тому що це виглядало весело. Я можу пізніше змінити це на щось інше ...

1
Я трохи здивований, що в 50+ відповідях я єдиний, хто використовує генератор пейзера. Щоб бути впевненим, це не дуже конкурентоспроможний за довжиною, але поставлена ​​проблема полягає в розборі простої, але нетривіальної мови. Я дуже хотів би бачити відповіді в інших синтаксисах компілятора-компілятора, тому що я не знайомий з широким вибором.
dmckee

Відповіді:


34

MATL , 5 4 байти

tSP-

Друкує не порожній масив розміром 1 с, якщо рядок належить до L , а порожній масив або масив з 0 с (обидва помилкові) в іншому випадку.

Дякуємо @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
Дивне визначення truthy та falesy: 'aabb' дає -1 -1 1 1 - це правда. 'aaabb' дає -1 -1 0 1 1 і є
фальшивим

3
@Etoplay Непорожній масив із усіма його значеннями, ненульовими, є правдою. Це визначення, яке використовується в Матлабі та Октаві
Луїс Мендо

145

Python 3, 32 байти

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

Вихідні дані за допомогою коду виходу : Помилка помилкової, помилки немає.

Рядок оцінюється як код 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один байт довше; завдяки isaacg за вказівку на це.


58
Гаразд, це розумно.
TLW

Що робить *128?
Ерік Аутгольфер

5
128може бути замінено на 50(або 99з цього приводу), щоб зберегти байт.
isaacg

@ Eʀɪᴋ ᴛʜᴇ Gᴏʟғᴇʀ: Я думаю, що це кількісний показник. Але я дійсно не знаю Python і не знайшов жодної документації на це.
Тит

4
@isaacg Спасибі, я не знав, що змінив для Python 3.
xnor

28

Сітківка , 12 байт

Подяка FryAmTheEggman, який знайшов це рішення самостійно.

+`a;?b
;
^;$

Друкує 1для дійсного введення та 0іншим чином.

Спробуйте в Інтернеті! (Перший рядок включає тестовий набір, відокремлений виведенням ліній.)

Пояснення

Групи врівноваження вимагають дорогого синтаксису, тому натомість я намагаюся зменшити допустимий вклад до простої форми.

1 етап

+`a;?b
;

+Каже Retina повторити цей етап в циклі , поки на виході не перестає змінюватися. Він відповідає abабо a;bзамінює його або замінює ;. Розглянемо кілька випадків:

  • Якщо as і bs в рядку не врівноважуються так, як (і )зазвичай потрібно, деякі aабо bзалишаться в рядку, оскільки baабо b;aне можуть бути вирішені, і окремі, aабо bсамостійно не можуть або. Щоб позбутися всіх as і bs, має бути один відповідний bправоруч від кожного a.
  • Якщо і aі bне всі вкладені (наприклад, якщо у нас є щось на кшталт ababабо aabaabbb), тоді ми закінчимося декількома ;(і, можливо, деякими as і bs), тому що в першій ітерації знайдеться декілька abs, щоб вставити їх, і подальші ітерації збережуть кількість ;рядка.

Отже, якщо і лише якщо вхід має форму , ми закінчимося одиничним у рядку.anbn;

Етап 2:

^;$

Перевірте, чи не містить отриманий рядок нічого, окрім крапки з комою. (Коли я кажу "перевірити", я фактично маю на увазі, підрахуйте кількість збігів даного регулярного виразу, але оскільки цей регулярний вираз може збігатися щонайменше за рахунок якорів, це дає або 0або 1.)


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)). Молодці.
Жуль

Нічого собі, я не знав, що хтось міг би відповідати постійним у розумінні списку!
rubik

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

Ви побудували цю мову?
Leaky Nun

@LaakyNun Так. Розвиток повільний, але триває.
Згарб

11

Брахілог , 23 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

2
Шукайте ненульовий пост у пості; це там :)
Лінн

@Lynn Невже специфіка не говорить лише "нуль" для дійсної мови? Не про введення.
Емінья

Правда. Думав, що там не так. Але ти все одно можеш зробити .M{J¹ÔQ0rза своє.
Емінья

@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ṚȦ

Друкує 1 або 0 . Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

Ṣ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'#~-:@#)

Це правильно працює для надання фальси для порожнього рядка. Помилка - фальсифікація.

Старі версії:

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

Доведення та пояснення

Основне дієслово - це виделка, що складається з цих трьох дієслів:

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

Це означає: "Менша <.довжина ( #) і результат правильного зубця ( (-:'ab'#~-:@#))".

Правий зубчик - це 4-поїзд , що складається з:

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

Нехай kпредставить наш вклад. Тоді це еквівалентно:

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

-:є оператором сірника, тому провідні -:тести на інваріантність під монадійною вилкою 'ab' #~ -:@#.

Оскільки лівий зубчик вилки є дієсловом, він стає постійною функцією. Отже, вилка еквівалентна:

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

Правий зубчик половини вилки ( -:) довжини ( #) k. Дотримуйтесь #:

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

Зараз це стосується kлише дійсних входів, тому ми тут зробили. #помилки для рядків непарної довжини, які ніколи не задовольняють мову, тому ми теж робимо це.

У поєднанні з меншою довжиною і цим порожній рядок, який не є частиною нашої мови, дає свою довжину 0, і ми все з цим робимо.


Я змінив його, 2&#-:'ab'#~#щоб уникнути помилок і просто виводити 0натомість, використовуючи ще 12 байт.
миль

@miles Захоплююче! Я ніколи про це не думав.
Conor O'Brien

Чи обробляє це порожній рядок?
Згарб

@Zgarb виправив це!
Conor O'Brien

9

Bison / YACC 60 (або 29) байт

(Ну, компіляція для програми YACC - це кілька кроків, тому, можливо, потрібно включити деякі для цього. Детальніше див. Нижче.)

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

Функція повинна бути досить очевидною, якщо ви знаєте її інтерпретувати з точки зору формальної граматики. Аналізатор приймає abабо aдотримується будь-яку прийнятну послідовність, за якою слідує 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. Він відповідає лише в тому випадку, якщо обидві довжини рівні.

Дякую Мартіну Ендеру, що вдвічі зменшив кількість байтів і навчив мене трохи про рекурсію в регулярних виразах: D

Він повертає весь рядок, якщо він відповідає, і нічого, якщо ні.

Спробуйте тут!


Найбільш близьким, яким я можу керувати, включаючи не порожній тестовий випадок, є 18 байт: $_&&=y/a//==y/b//(потрібно -p), без порожнього ви можете скинути значення &&16 Так близько ...
Дом Гастінгс

1
Тож я можу зробити ще 17 байт: echo -n 'aaabbb'|perl -pe '$_+=y/a//==y/b//'але я не можу змінити ще один байт ... Можливо, від цього потрібно відмовитися!
Дом Гастінгс

7

JavaScript, 54 55 44

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

Побудує простий регулярний вираз на основі довжини рядка і тестує його. Для довжини 4 рядка ( aabb) регулярний вигляд виглядає так:^a{2}b{2}$

Повертає значення truthy або falsey.

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

Функція - це дійсне подання.
Leaky Nun

@TimmyD Раніше повертав true, але тепер повертає false.
Scimonster

1
s=>s.match(`^a{${s.length/2}}b+$`)?
l4м2

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. 4.8.2 @Ubuntu

Дякую угорен за поради!

Спробуйте це на Ideone!


Оскільки я тут новий і не можу коментувати інші відповіді, я просто хочу зазначити, що рішення 62b від @Josh дає хибний позитив на рядках типу "aaabab".
Jasmes

Змініть (t+=2)на t++++-1 байт.
owacoder

@owacoder t++++не є дійсним кодом С.
Jasmes

Збережіть кілька за допомогою t+=*s%2*2і:*s*!1[s]
ugoren

Дуже розумна відповідь! На жаль, не вдається ввести "ba": ideone.com/yxixG2
Josh

4

Сітківка , 22 байти

Ще одна коротша відповідь тією ж мовою щойно прийшла ...

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

Спробуйте в Інтернеті!

Це демонстрація врівноважувальних груп у регексе, яку повністю пояснює Мартін Ендер .

Оскільки моє пояснення не наблизиться до його половини, я просто посилаюся на нього і не намагаюся пояснити, оскільки це буде шкодити славі його пояснення.


4

Befunge-93, 67 байт

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

Спробуйте тут! Можна пояснити, як це працює пізніше. Можна також спробувати пограти в гольф лише на трохи більше, тільки для ударів.


3

MATL , 9 байт

vHI$e!d1=

Спробуйте в Інтернеті!

Вихідний масив є truthy, якщо він не порожній, і всі його записи ненульові. Інакше це хибність. Ось кілька прикладів .

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
Це одне зручне визначення truthy. (Я знав про ненульову вимогу, але не про не порожню.)
Денніс

3

машинний код x86, 29 27 байт

Hexdump:

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перевернути прапор перенесення та salcвстановити AL у FFh або 0 залежно від того, встановлено прапор переносу чи ні. Економить 2 байти, хоча в кінцевому підсумку виходить 8-бітний результат, а не 32-розрядний.
Жуль

Те ж саме, використовуючи string ops, 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

@ninjalj Ви повинні опублікувати це у відповіді - вона досить відрізняється від моєї, і я підозрюю, що це значно коротше!
anatolyg

3

Рубін, 24 байти

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

(Це просто геніальна ідея Xnor у рубіновій формі. Інша моя відповідь - це рішення, яке я насправді придумав сам.)

Програма приймає вхідні дані , перетворює aі bдо [і , ]відповідно, і оцінює його.

Дійсний вхід сформує вкладений масив, і нічого не станеться. Неврівноважений вираз призведе до краху програми. У Ruby порожній вхід оцінюється як nil, який вийде з ладу, оскільки nilне визначив *метод.


3

Sed, 38 + 2 = 40 байт

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

Непорожній рядок виводу є truthy

Автомати кінцевих держав цього не можуть зробити, скажете ви? А як щодо автоматизованих кінцевих держав з петлями . : P

Бігайте з прапорами rта nпрапорами.

Пояснення

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"

Працює рекурсивно отгонку зовнішніх aі bі рекурсивно з використанням внутрішнього значення , обраним , але .+. Якщо ^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';

Використовується та ж концепція, що і відповідь YACC @ dmckee , лише трохи більше гольфу.

Щоб перевірити, виконайте кроки в підручнику " Початок роботи" ANTLR . Потім введіть вищезгаданий код у файл з іменем A.g4та запустіть ці команди:

$ antlr A.g4
$ javac A*.java

Потім тестуйте, подавши вхід на STDIN grun A rтак, щоб:

$ echo "aaabbb" | grun A r

Якщо вхід правильний, нічого не буде виведено; якщо він є недійсним, grunвидасть повідомлення про помилку (або token recognition error, extraneous input, mismatched 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, хоча. Ніби як використовувати фортран .
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 повертає вказівник на останнє виникнення символу

Велика подяка Тіту!


1
зберегти один байт, >97а не==98
Тит

2
61 байт рішення дає хибний позитив на рядках типу "aaabab". Дивіться ideone.com/nmT8rm
Jasmes

Ах, ви правильні Ясмесе, дякую. Мені доведеться трохи переосмислити це.
Джош

Повернувшись до 69-байтового рішення, не впевнений, чи зможу я скористатися таким підходом.
Джош

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(,''))))
    

    Знову НУЛЬ, якщо успіх, ще щось інакше.


Я не знаю, R, який твій результат для порожнього введення? (має бути помилковим)
Тит

Чи справді немає коротшого способу тестування на порожній ввід?
Тит

Версія 1: просто нічого (правильний вхід повертає тільки NULL), версія 2: просто нічого (правильний вхід повертає тільки TRUE), версія 3 (які передбачають порожні рядки в порядку, так як стан): NULL. R - це об'єктно-орієнтована мова статистики, яка набирає все просто в порядку, без будь-якого попередження.
Андрей Костирка

Цю відповідь (відповідь 1) можна покращити до 55 байт:if((y<-scan(,''))>'')eval(parse(t=chartr('ab','{}',y)))
Джузеппе

3

Japt , 11 байт

©¬n eȦUg~Y

Спробуйте в Інтернеті!

Дає trueабо false, за винятком того, що ""дає ""помилкове значення в 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

Прийнято з рішення 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 та прирости j на кожен b, а зменшення j - на будь-що інше. Перевіряється, чи попередній лист менше або рівний наступній букві, тому не дозволяйте абабі працювати

Правки

Додано чеки на випадки абаб.


Чи не буде чи це давати помилкових спрацьовувань на струнах , як 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

Повертає ERRORLEVEL0 на успіх, 1 на провал. Batch не любить робити заміну підрядків на порожніх рядках, тому нам доведеться перевірити це вперед; якщо порожній параметр був законним, рядок 6 не буде необхідним.


2

PowerShell v2 +, 61 52 байт

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

Приймає введення $nяк рядок, створює $xяк half the length. Конструкції -andЛогічне порівняння $nі -matchрегулярний вираз оператора проти регулярного виразу з рівного числа aх і bх років. Виходи Логічне $TRUEабо $FALSE. Це $n-andє для обліку ""= $FALSE.

Чергування, 35 байт

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

Для цього використовується регулярний вираз з відповіді Leaky на основі .NET-балансуючих груп, щойно укладених в -matchоператор PowerShell . Повертає рядок для truthy або порожню рядок для falsey.


У альтернативній версії, яку ви повинні оцінити -matchпроти $args[0], інакше -matchбуде працювати як фільтр
Mathias R. Jessen

@ MathiasR.Jessen У виробничому коді, так, але ми можемо гольфувати [0]тут, тому що нам дають лише один вхід, і нам потрібно лише одне значення truthy / falsey як вихід. Оскільки порожня рядок є фальсією, а непуста рядок - правдоподібною, ми можемо відфільтрувати масив і повернути вхідний рядок назад або нічого назад, що відповідає вимогам виклику.
AdmBorkBork

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

Хаскелл, 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

Пітон, 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")

-4 байти, використовуючи len / 2 (я отримую помилку, коли половина настає останньою)

тепер дає false для порожнього рядка

-3 байти завдяки xnor


Так, лямбдів не потрібно називати.
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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.