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


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.