Loại bỏ số nhiều mơ hồ (s)!


21

Lập trình rất cứng nhắc. Bạn không thể nói với một chương trình "xuất số đếm chuối", bạn phải nói với nó print(bananas).

Nhưng khi bạn làm điều đó, bạn sẽ gặp phải một vấn đề: bạn không biết trước mình có bao nhiêu quả chuối, vì vậy bạn không biết có nên sử dụng số nhiều hay không.

Đôi khi, lập trình viên đi theo con đường lười biếng. Thay vì kiểm tra, họ chỉ in there are X banana(s).

Nhưng điều đó thật xấu xí, vì vậy chúng tôi cần một chương trình để khắc phục điều này.

Các phương pháp)

Để loại bỏ các số nhiều mơ hồ trong một chuỗi, hãy làm theo các bước sau:

  1. Chia chuỗi trên khoảng trắng thành một danh sách các từ.

  2. Đối với mỗi từ kết thúc bằng (s), hãy làm như sau:

    • Nếu từ trước là a, an, 1hoặc one, loại bỏ các (s)vào cuối của từ.
    • Nếu không, nếu từ đó là từ đầu tiên trong chuỗi hoặc từ trước không phải là a, an, 1hoặc one, thay thế (s)vào cuối của từ với s.
  3. Tham gia danh sách các từ trở lại với nhau thành một chuỗi, giữ nguyên khoảng trắng ban đầu.

Ví dụ

Hãy lấy một chuỗi there's a banana(s) and three apple(s).

Đầu tiên, chúng tôi chia chuỗi thành một danh sách các từ: ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

Đối với bước thứ hai, chúng tôi lấy hai từ kết thúc bằng (s): banana(s)apple(s).

Từ trước banana(s)a, vì vậy chúng tôi loại bỏ (s), làm cho nó banana. Từ trước apple(s)three, vì vậy chúng tôi thay đổi (s)thành s, do đó nó trở thành apples.

Bây giờ chúng ta có ["there's", "a", "banana", "and", "three", "apples"]. Tham gia danh sách trở lại với nhau, chúng tôi nhận được there's a banana and three apples. Đây là kết quả cuối cùng của chúng tôi.

Những thách thức)

Tạo một chương trình hoặc hàm lấy một chuỗi mơ hồ ở bất kỳ định dạng hợp lý nào và trả về phiên bản không mơ hồ của chuỗi đó.

Bạn có thể giả sử chuỗi không chứa dòng mới, tab hoặc trả về vận chuyển.

Tôi đã quên chỉ định phân chia theo nhóm không gian hoặc khoảng trắng (nghĩa là có nên okay thencó hai khoảng trắng ["okay", "then"]hay không ["okay", "", "then"]) khi đăng thử thách, vì vậy bạn có thể giả sử một trong hai hình thức phân tách.

Trường hợp thử nghiệm

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

Chấm điểm

Vì đây là , bài nộp có ít byte nhất sẽ thắng!


Câu hỏi này đã được sandbox .
LyricLy

Có nên thay thế apple(s)trường hợp thử nghiệm apples? Thách thức nêu rõ Otherwise, if the word is the first word in the string . . . replace the (s) at the end of the word with s.tôi lưu ý rằng trường hợp này mang lại applestrong hộp cát cho ba lần sửa đổi đầu tiên nhưng đã thay đổi ở lần thứ tư.
fireflame241

@ fireflame241 Khi viết bản thảo thứ hai của các quy tắc, tôi sẽ làm cho nó để bắt đầu chuỗi không thay đổi. Tôi đã thay đổi quy tắc đó sau đó, nhưng không phải là trường hợp thử nghiệm. Nắm bắt tốt.
LyricLy

Đề nghị trường hợp thử nghiệm: There's a single banana(s)-> There's a single bananas.
Jonathan Allan

1
@Jonathan ALLan Bạn không thể. Tôi sẽ thêm một vài trường hợp thử nghiệm.
LyricLy

Câu trả lời:


6

Toán học, 151 148 byte

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

Giải trình

j=" ";k=Except@j

Đặt jthành một ký tự khoảng trắng. Đặt kthành mẫu "không j" (= ký tự không phải khoảng trắng).

j<>j<>#<>j

Chuẩn bị hai khoảng trắng và nối thêm một khoảng trắng vào đầu vào.

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

Đối với (các) chuỗi con phù hợp với mẫu:

  1. Một khoảng trắng, theo sau là
  2. một chuỗi con có độ dài bằng 0 hoặc dài hơn chỉ bao gồm (các) ký tự không phải khoảng trắng (bộ định lượng) (gọi đây a), theo sau là
  3. một chuỗi con có độ dài một hoặc dài hơn chỉ bao gồm (các) ký tự khoảng trắng (gọi cái này s), theo sau là
  4. một chuỗi con có độ dài một hoặc dài hơn chỉ bao gồm (các) ký tự không phải khoảng trắng (từ) (gọi cái này w), theo sau là
  5. chuỗi "(s)", theo sau là
  6. một khoảng trắng
Nếu [FreeQ [a, "a" | "an" | "1" | "một"], "s", ""]

Nếu akhông phải là một trong những từ số ít, hãy đánh giá "s", nếu không "".

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

Thay thế các mô hình phù hợp với j, a, s, w, If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""], và jliên kết với nhau.

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

Lấy từ vị trí 3 đến vị trí -2 (được lập chỉ mục 1; chỉ số âm tính từ cuối). Điều này là do chúng tôi đã thêm ba không gian vào đầu.


3
Tại sao không sử dụng nội dung để loại bỏ số nhiều-S?
Thomas Weller

5

Python 3 , 94 byte

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

Hãy thử trực tuyến!

-4 byte nhờ i cri everytim (Tôi nghĩ điều này có thể chấp nhận được)


@Jonathan ALLan Đã sửa, cảm ơn.
HyperNeutrino

1
__import__không thể ngắn hơn ... Yup, nó ngắn hơn 4 byte như bình thường import re.
hoàn toàn là

@icrieverytim huh bạn đúng (chỉ 3 byte) cảm ơn
HyperNeutrino


@icrieverytim ._. ồ tốt đẹp cảm ơn!
HyperNeutrino


4

Toán học, 313 byte

(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 byte

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

Phù hợp với mọi (s) từ cuối của từ, thay thế nó bằng !$1(1 hoặc 0) bài luận.


2

Pyth - 53 byte

Theo các thuật toán khá nhiều như nó là.

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

Hãy thử trực tuyến tại đây .


1
Thất bại trên there are two banana(s) and one leprechaun(s)(hai khoảng trắng sau one). Khoảng trắng ban đầu được bảo tồn, nhưng leprechaun(s)bỏ qua onetrước đó.
LyricLy

1
@LyricLy bạn chưa nói rõ điều này trong OP. Với hai khoảng trắng (sử dụng (1) phần "phương thức" của bạn, "chia chuỗi trên khoảng trắng thành một danh sách các từ") thực sự có một từ trống giữa oneleprechaun(s)
Jonathan Allan

2

Thạch ,  52 51  49 byte

Jelly không có một nguyên tử regex (s)

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

Một chương trình đầy đủ chấp nhận một chuỗi (sử dụng định dạng Python nếu đa dòng hoặc chứa dấu ngoặc kép) và in đầu ra.

Hãy thử trực tuyến! hoặc xem bộ thử nghiệm .

Làm sao?

Ṫ - 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

Tôi tò mò về lý do tại sao bạn sử dụng như một liên kết riêng biệt. Điều này có ngăn cản việc xóa phần tử khỏi danh sách ban đầu không?
HyperNeutrino

Không, tôi cần lấy đuôi của cặp ... viết bình luận mã, có thể bạn có thể phát hiện ra một quả golf khi bạn thấy điều đó.
Jonathan Allan

À được rồi. Cảm ơn, tôi sẽ cố gắng phát hiện ra golf khi có một bài bình luận (hoặc trước đó)!
HyperNeutrino

Vì vậy, liên kết 1, 2 và 3 tất cả đuôi và liên kết 5 chọn cách gọi và sử dụng Ŀđể làm như vậy, nhưng tôi không thấy một cách ngắn để nối đuôi trong liên kết 4, nhưng có thể có. Thậm chí có thể có một cách để có được đuôi của liên kết 4 trong đó!
Jonathan Allan

@HyperNeutrino Tôi nghĩ rằng điều đó Ŀcó thể gọi liên kết đầu tiên, đó là lý do tại sao nó là một liên kết riêng.
Erik the Outgolfer


1

Perl 5 , 56 + 1 ( -p) = 57 byte

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

Hãy thử trực tuyến!


1
Không phải trên các trường hợp thử nghiệm, nhưng tôi nghĩ rằng điều này không thành công a hel(s)lo.
Neil

Đó là hoạt động đúng như được cung cấp trong trường hợp thử nghiệm. Nó ở gần cuối của các trường hợp thử nghiệm trong liên kết TIO của tôi.
Xcali

Chà, tôi sẽ chỉ cần được a hel(s)lothêm vào các trường hợp thử nghiệm, và sau đó có thể bạn sẽ sửa mã của mình ...
Neil

0

JavaScript (ES6), 88 87 byte

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

Giải thích đến sớm.


1
bạn có thể thay thế \sbằng `` theo "Bạn có thể giả sử chuỗi không chứa dòng mới, tab hoặc trả về vận chuyển."
SuperStormer

Thất bại trong "đây là một te (s) t". Bạn có thể khắc phục bằng cách thêm (\s|$)vào cuối regex.
Birjolaxew

Cũng thất bại trên "apple (s)". Đã sửa lỗi trong TIO này
Birjolaxew

Cảm ơn @Birjolaxew, sẽ chỉnh sửa các thay đổi khi tôi có thể ...
XavCo7

0

JavaScript (ES6), 84 byte

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

Đây là một cách thú vị để sắp xếp lại phần cuối cùng, đáng buồn là dài hơn 2 byte:

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

0

JavaScript (SpiderMonkey) , 82 byte

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

Hãy thử trực tuyến!

Phiên bản 78 Byte (kém mạnh mẽ hơn)

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

Đây là phiên bản sửa đổi của ETHproductions '(Tôi không có 50 đại diện.)

Giải trình

  • /(\S+ +(\S+))\(s\)/g - mô hình thực tế để tìm kiếm (amount object(s) )
  • (_,a)=>a- _là một biến tất cả, a(\S+ +(\S+))
  • "s"[+/^(1|one|an?)/i.test(a)]||"" - thay vì cắt mảng, chỉ cần tạo một mảng giả và lấy chỉ mục (+/.../.test trả về một số)
    • nên "s"[+/^(1|one|an?)/i.test(a)]trả lại undefined( truehoặc 1cho bài kiểm tra)""
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.