Видаліть неоднозначні множини!


21

Програмування дуже жорстке. Ви не можете сказати програмі "вивести кількість бананів", ви повинні сказати це print(bananas).

Але коли ви це зробите, у вас виникає проблема: ви не знаєте, скільки бананів у вас заздалегідь, тож ви не знаєте, чи вживати множину.

Іноді програмісти йдуть ледачим шляхом. Замість перевірки вони просто друкують there are X banana(s).

Але це потворно, тому нам потрібна програма, щоб це виправити.

Метод (и)

Щоб видалити неоднозначні множини в рядку, виконайте наступні дії:

  1. Розділіть рядок на пробіли на список слів.

  2. Для кожного слова, що закінчується (s), виконайте наступне:

    • Якщо попередній слово a, an, 1або one, видалити (s)в кінці слова.
    • В іншому випадку, якщо слово є першим словом в рядку або попереднє слова не a, an, 1або one, замінити (s)в кінці слова з s.
  3. З’єднайте список слів разом разом у рядок, зберігши початковий пробіл.

Приклад (и)

Візьмемо рядок there's a banana(s) and three apple(s).

Спочатку ми розділили рядок на список слів: ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

Для другого кроку ми беремо два слова, що закінчуються на (s): banana(s)і apple(s).

Слово раніше banana(s)є a, тому ми видаляємо (s), виготовляючи його banana. Слово раніше apple(s)є three, тому ми змінюємо (s)на s, таким чином воно стає apples.

Зараз у нас є ["there's", "a", "banana", "and", "three", "apples"]. Приєднавшись до списку разом, ми отримуємо there's a banana and three apples. Це наш кінцевий результат.

Виклик (и)

Створіть програму або функцію, яка приймає неоднозначну рядок у будь-якому розумному форматі і повертає неамбіційну версію цього рядка.

Ви можете припустити, що рядок не містить нових рядків, вкладок або повернень каретки.

Я забув вказати, чи слід розділяти на групи пробіли чи пробіли (тобто, чи okay thenмає бути два пробіли ["okay", "then"]або ["okay", "", "then"]) під час публікації виклику, тому ви можете прийняти будь-яку форму поділу.

Тест (и)

Input                                         -> Output
there are two banana(s) and one leprechaun(s) -> there are two bananas and one leprechaun
there's a banana(s) and three apple(s)        -> there's a banana and three apples
apple(s)                                      -> apples
one apple(s)                                  -> one apple
1 banana(s)                                   -> 1 banana
banana                                        -> banana
preserve    original      whitespace(s)       -> preserve    original      whitespaces
11 banana(s)                                  -> 11 bananas
an apple(s)                                   -> an apple
this is a te(s)t                              -> this is a te(s)t
I am a (s)tranger(s)                          -> I am a (s)tranger

Оцінка балів

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


Це питання пісочне .
— LyricLy

Чи повинен замість цього apple(s)отримати тестовий випадок apples? Проблема констатує, що Otherwise, if the word is the first word in the string . . . replace the (s) at the end of the word with s.я зазначив, що цей випадок піддався applesпісочниці протягом перших трьох змін, але змінився на четвертому.
— fireflame241

@ fireflame241 Під час написання другого проекту правил я збирався зробити так, щоб початок рядка був незмінним. Пізніше я змінив це правило, але не тестовий випадок. Хороший улов.
— LyricLy

Пропозиція тестового випадку: There's a single banana(s)-> There's a single bananas.
— Джонатан Аллан

1
@JonathanAllan Ви не можете. Додам кілька тестових випадків.
— LyricLy

Відповіді:


6

Математика, 151 148 байт

StringReplace[j=" ";k=Except@j;j<>j<>#<>j,j~~a:k...~~s:j..~~w:k..~~"(s)"~~j:>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]~StringTake~{3,-2}&

Пояснення

j=" ";k=Except@j

Встановіть jсимволи пробілів. Встановіть kшаблон "не j" (= символ, який не є пробілом).

j<>j<>#<>j

Додайте два пробіли та додайте одну пробіл до вводу.

j~~a:k...~~s:j..~~w:k..~~"(s)"~~j

Для підрядків, що відповідають шаблону:

  1. Один пробіл (и), після якого
  2. підрядка довжини-нуля або довше, що складається лише з символів (пробілів), які не містять пробілів (викликайте це a), а потім
  3. підрядка довжиною - одна чи довша, що складається лише з символів пробілу (викликати це s), за якими слід
  4. підрядка довжиною одна чи довша, що складається лише з символів (пробілів), які не містять пробілів (викликайте це w), а потім
  5. рядок "(s)", за яким
  6. пробіл (и)
Якщо [FreeQ [a, "a" | "a" | "1" | "one"], "s", ""]

Якщо aне належить до однини однини (слів), оцініть, щоб "s"це було інакше "".

StringReplace[..., ... :>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]

Замінити шаблон узгодження з j, a, s, w, If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""], і jз'єднані один з одним.

... ~StringTake~{3,-2}

Перейдіть з позиції 3 до позиції -2 (1-індексований; від'ємні показники рахуються з кінця). Це тому, що ми на початку додали три місця.


3
Чому б не використовувати вбудований для видалення множини-S?
— Томас Веллер

5

Python 3 , 94 байти

lambda s,r=re.sub:r(r"\(s\)( |$)","s",r(r"\b(an?|1|one)(\s+)(.+)\(s\)",r"\1\2\3",s))
import re

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

-4 байти завдяки i cri everytim (я вважаю, що це прийнятно)


@JonathanAllan Виправлено, дякую.
— HyperNeutrino

1
__import__не може бути коротше ... Так, це 4 байти коротше, ніж звичайні import re.
— totalhuman

@icrieverytim так, ти маєш рацію (хоча лише 3 байти) дякую
— HyperNeutrino


@icrieverytim ._. о, гарно. Спасибі!
— HyperNeutrino


4

Математика, 313 байт

(Table[If[StringLength@z[[i]]>3&&StringTake[z[[i]],-3]=="(s)",z[[i]]=StringDrop[z[[i]],-3];t=1;While[z[[i-t]]=="",t++];If[FreeQ[{"a","an","1","one"},z[[i-t]]],z[[i]]=z[[i]]<>"s"]],{i,2,Length[z=StringSplit[#," "]]}];If[StringTake[z[[1]],-3]=="(s)",z[[1]]=StringDrop[z[[1]],-3];z[[1]]=z[[1]]<>"s"];StringRiffle@z)&

3

Perl 5, 43 + 1 (-p) = 44 байти

s/\b((one|1|an?) +)?\S+\K\(s\)\B/"s"x!$1/ge

Відповідайте кожному (s) в кінці слова, замініть його на !$1(1 або 0) ессе.


2

Pyth - 53 байти

Дотримується алгоритму, як і є.

K+kczdjdt.e?q"(s)"gb_2+<b_3*\s!}@Ktk[\a"an""one"\1)bK

Спробуйте його онлайн тут .


1
Не вдалося there are two banana(s) and one leprechaun(s)(два пробіли після one). Початковий пробіл збережений, але leprechaun(s)ігнорується oneраніше.
— LyricLy

1
@LyricLy Ви прямо не заявили це в ОП. З двома пробілами (використовуючи (1) вашого розділу "метод (и)" "розділити рядок на пробіли на список слів") насправді є порожнє слово між oneіleprechaun(s)
— Джонатан Аллан

2

Желе ,  52 51  49 байт

Желе не має жодного атома виразки

Ṫ
Ñ;”s
Ṫḣ-3
UṪw“)s(”⁼1
“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘
⁶;ḲÇĿ2ƤK

Повна програма, що приймає рядок (використовуючи формат Python, якщо багаторядковий або містить лапки) і друкує вихід.

Спробуйте в Інтернеті! або побачити набір тестів .

Як?

Ṫ - Link 1, tail: two words (list of lists)
Ṫ - tail

Ñ;”s - Link 2, tail and replace last three chars with an 's': two words (list of lists)
Ñ    - call the next link (3) as a monad
  ”s - literal 's'
 ;   - concatenate

Ṫḣ-3 - Link 3, tail and remove the last three chars: two words (list of lists)
Ṫ    - tail
  -3 - literal minus three
 ḣ   - head from index (1-indexed and modular)

UṪw“)s(”⁼1 - Link 4, tail ends with "(s)"?: two words (list of lists)
U          - upend (reverse each word)
 Ṫ         - tail
   “)s(”   - literal [')', 's', '('] - that is "(s)" reversed
  w        - index of first sublist equal to that or 0 if not found
         1 - literal one
        ⁼  - equal?

“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘ - Link 5, categorise: two words (list of lists)
“µḣ⁴µuʠg*»        - compression of string "a 1" + word " an" + word " one"
          Ḳ       - split on spaces = ["a", "1", "an", "one"]
            Ḣ     - head (the first word)
           ċ      - count occurrences (of head in the list - either 0 or 1)
             ‘    - increment
               Ç  - call the last link (4) as a monad - i.e. f(two words)
              ×   - multiply
                ‘ - increment - so we have: 1 for ["1", "blah"],
                  -             2 for ["blah", "blah(s)"] or 3 for ["1", "blah(s)"]

⁶;ḲÇĿ2ƤK - Main link: list of characters, the string
⁶        - literal space character
 ;       - concatenate (place a space at the beginning as we want to inspect pairs)
  Ḳ      - split on spaces (giving an empty list at the start)
     2Ƥ  - for all infixes of length two:
    Ŀ    -   call the link at the given index as a monad:
   Ç     -     call the last link (5) as a monad
       K - join the result with spaces
         - implicit print

Мені цікаво, чому ви використовували Ṫяк окреме посилання. Чи заважає це Ṫвидалити елемент із початкового списку?
— HyperNeutrino

Ні, мені потрібно отримати хвіст пари ... написати коментар до коду, можливо, ви можете помітити гольф, як тільки це побачите.
— Джонатан Аллан

Ага гаразд. Дякую, я спробую помітити гольф, коли з’явиться коментар (або до цього часу)!
— HyperNeutrino

Отже, посилання 1, 2 і 3 весь хвіст, а посилання 5 вибирає, до якого дзвонити і використовує Ŀце, але я не бачу короткого шляху до хвоста всередині посилання 4, але це може бути. Тут навіть може бути спосіб потрапити хвіст посилання 4!
— Джонатан Аллан

@HyperNeutrino Я думаю, що Ŀріч може зателефонувати на першу посилання, ось чому Ṫце посилання самостійно.
— Erik the Outgolfer


1

Perl 5 , 56 + 1 ( -p) = 57 байт

s/\b(an?|1|one) +\S+\K\(s\)(?= |$)//g;s/\(s\)( |$)/s$1/g

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


1
Не на тестових випадках, але я думаю, що це не вдається a hel(s)lo.
— Ніл

Це працює належним чином, як це передбачено в тестовому випадку. Це внизу тестових випадків у моєму посиланні TIO.
— Xcali

Ну, мені просто доведеться a hel(s)loдодати до тестових справ, і тоді, можливо, ви виправите свій код ...
— Ніл

0

JavaScript (ES6), 88 87 байт

a=>a.replace(/(\S+)( +)(\S+)\(s\)/g,(m,f,s,w)=>f+s+w+(/^(a|an|1|one)$/.exec(f)?'':'s'))

Пояснення найближчим часом.


1
ви можете замінити \sна `` відповідно до "Ви можете припустити, що рядок не містить нових рядків, вкладок або повернень каретки."
— SuperStormer

Не вдалося "це те (и) t". Ви можете виправити, додавши (\s|$)до кінця регулярний вираз.
— Birjolaxew

Також виходить з ладу на "яблуко (и)". Виправлено в цьому
— ТІО

Дякую @Birjolaxew, редагую зміни, коли зможу ...
— XavCo7

0

JavaScript (ES6), 84 байти

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+(/^(1|an?|one) /.test(a)?'':'s'))

Ось цікавий спосіб переставити останню частину, яка, на жаль, на 2 байти довше:

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+'s'.slice(/^(1|an?|one) /.test(a)))

0

JavaScript (SpiderMonkey) , 82 байти

s=s.replace(/(\S+ +(\S+))\(s\)\B/g,(_,a)=>a+("s"[+/^(1|one|an?)\b/i.test(a)]||""))

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

78-байтна версія (менш надійна)

s=s.replace(/(\S+ +(\S*))\(s\)/g,(_,a)=>a+("s"[+/^(1|one|an?)/i.test(a)]||""))

Це модифікована версія ETHproductions '(у мене немає 50 повторень)

Пояснення

  • /(\S+ +(\S+))\(s\)/g - фактичну схему, яку потрібно шукати (amount object(s) )
  • (_,a)=>a- _це вся переменная, що aє(\S+ +(\S+))
  • "s"[+/^(1|one|an?)/i.test(a)]||"" - замість того, щоб нарізати масив, просто зробіть фіктивний масив і отримайте індекс (+/.../.test повертає число)
    • повинен "s"[+/^(1|one|an?)/i.test(a)]повернути undefined( trueабо 1для тесту) повернути""
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.