あいまいな複数形を削除してください!


21

プログラミングは非常に厳格です。「バナナカウントを出力する」ようにプログラムに指示することはできませんprint(bananas)

しかし、それを行うと、問題が発生します。バナナの数が事前にわからないため、複数形を使用するかどうかわかりません。

時々、プログラマーは怠zyなやり方をします。チェックする代わりに、単に印刷しますthere are X banana(s)

しかし、それは見苦しいため、これを修正するプログラムが必要です。

メソッド

文字列のあいまいな複数形を削除するには、次の手順を実行します。

  1. スペース上の文字列を単語のリストに分割します。

  2. で終わる単語ごとに(s)、次の操作を行います。

    • 前の単語である場合aan1またはone、削除(s)単語の終わりに。
    • 単語が最初の単語が文字列であるか、先行する単語がない場合はそれ以外の場合は、aan1またはone、交換する(s)と単語の終わりにs
  3. 単語のリストを結合して文字列に戻し、元の空白を保持します。

文字列を取りましょうthere's a banana(s) and three apple(s)

まず、文字列を単語のリストに分割します。 ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

2番目のステップでは、(s)banana(s)とで終わる2つの単語を使用し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

得点

これはであるため、バイト数が最小の提出が勝ちです!



代わりに、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最初の3つのリビジョンではサンドボックスで生成されましたが、4番目のリビジョンでは変更されたと述べています。
fireflame241

@ fireflame241ルールの2番目のドラフトを作成するとき、文字列の先頭が変更されないようにするつもりでした。このルールは後で変更しましたが、テストケースは変更しませんでした。良いキャッチ。
LyricLy

テストケースの提案:There's a single banana(s)-> There's a single bananas
ジョナサンアラン

1
@JonathanAllanできません。いくつかのテストケースを追加します。
LyricLy

回答:


6

Mathematica、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パターン「not j」に設定します(=非空白文字)。

j<>j<>#<>j

2つの空白を先頭に追加し、1つの空白を入力に追加します。

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

パターンに一致する部分文字列の場合:

  1. 1つの空白、続いて
  2. 空白以外の文字(量指定子)のみで構成される長さ0以上の部分文字列(これを呼び出すa)、その後に続く
  3. 空白文字のみで構成される長さ1以上の部分文字列(これを呼び出すs)、その後に続く
  4. 空白以外の文字(単語)(これを呼び出す)のみで構成される長さ1以上の部分文字列w、その後に続く
  5. 文字列"(s)"、その後に
  6. 空白
If [FreeQ [a、 "a" | "an" | "1" | "one"]、 "s"、 ""]

aが単数形の単語の1つではない場合、に評価され"s"ます""

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

マッチングパターンを置き換えjaswIf[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]、とj一緒に参加しました。

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

位置3から位置-2(1インデックス付き、負のインデックスは最後から数えます)になります。これは、最初に3つのスペースを追加したためです。


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

オンラインでお試しください!

i cri everytimのおかげで-4バイト(これは許容範囲だと思います)


@JonathanAllan修正、ありがとう。
-HyperNeutrino

1
__import__短くすることはできません...うん、それは通常のように4バイト短くなりますimport re
完全に人間

@icrieverytimええ、正しい(3バイトだけです)ありがとう
-HyperNeutrino


@icrieverytim ._。いいね。ありがとう!
ハイパーニュートリノ


4

Mathematica、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)essesに置き換えます。


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)(の後の2つのスペースone)。元の空白は保持されますが、leprechaun(s)そのone前の空白は無視されます。
LyricLy

1
@LyricLyは、OPでこれを明示的に指定していません。空の単語の間、実際にそこにある(あなたの「メソッド(S)」「単語のリストに空白の文字列を分割」のセクションの使用(1))2つのスペースでoneleprechaun(s)
ジョナサン・アラン

2

ゼリー 52 51  49 バイト

Jellyには正規表現が1つもありません

Ṫ
Ñ;”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

なぜ別のリンクとして使用したのか興味があります。これにより、元のリストから要素が削除されなくなりますか?
ハイパーニュートリノ

いいえ、私はペアのテールを取得する必要があります...コードの解説を書きます。多分あなたはそれを見たらゴルフを見つけることができます。
ジョナサンアラン

あ、そう。おかげで、コメントがあれば(またはそれより前に)ゴルフを見つけようとします!
ハイパーニュートリノ

したがって、リンク1、2、および3はすべてテールであり、リンク5はどちらを呼び出すかを選択しĿ、そうするために使用しますが、リンク4内でテールへの短い道はありませんが、あるかもしれません。リンク4のテールをそこに入れる方法もあるかもしれません!
ジョナサンアラン

@HyperNeutrinoものごとĿが最初のリンクを呼び出すかもしれないと思うので、それ自体がリンクです。
エリックアウトゴルファー


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

「これはte(s)tです」で失敗します。(\s|$)正規表現の最後に追加することで修正できます。
ビルジョラクセ

「リンゴ」でも失敗します。このTIOで修正済み
ビルジョラクセ

@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)]返すundefinedtrueまたは1テストのために)復帰""
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.