Belirsiz çoğulları kaldırın!


21

Programlama çok katıdır. Bir programa "muz sayısını hesaplamak" diyemezsiniz, bunu söylemelisiniz print(bananas).

Ancak bunu yaptığınızda, bir sorunla karşılaşırsınız: önceden kaç tane muzunuz olduğunu bilmiyorsunuz, bu yüzden çoğul kullanıp kullanmayacağınızı bilmiyorsunuz.

Bazen, programcılar tembel yoldan gider. Kontrol etmek yerine, sadece yazdırırlar there are X banana(s).

Ama bu çirkin, bu yüzden bunu düzeltmek için bir programa ihtiyacımız var.

Metodlar)

Bir dizedeki belirsiz çoğulları kaldırmak için aşağıdaki adımları izleyin:

  1. Boşluklardaki dizgiyi bir sözcük listesine bölün.

  2. İle biten her kelime (s)için, aşağıdakileri yapın:

    • Yukarıdaki kelime ise a, an, 1ya da one, kaldırma (s)kelime sonunda.
    • Kelimesi ilk kelime dizesini veya önceki kelime değilse Aksi a, an, 1veya one, yerine (s)ile kelimenin sonundaki s.
  3. Orijinal boşlukları koruyarak kelime listesine tekrar bir dizgede katılın.

Örnek (lar)

Bir ip atalım there's a banana(s) and three apple(s).

İlk olarak, dizgiyi bir sözcük listesine böldük: ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

İkinci adım için biten iki kelimeyi alıyoruz (s): banana(s)ve apple(s).

Önce kelime banana(s)olduğunu a, bu yüzden kaldırmak (s)yapma, banana. Kelimesi daha önce apple(s)olduğu threedeğiştirmemiz yüzden (s)hiç sböylece olur apples.

Şimdi bizde var ["there's", "a", "banana", "and", "three", "apples"]. Listeye tekrar katıldığımızda, anlaştık there's a banana and three apples. Bu bizim son sonucumuz.

Mücadeleler)

Herhangi bir makul biçimde belirsiz bir dize alan ve bu dize belirsiz halini döndüren bir program veya işlev oluşturun .

Dizenin yeni satırlar, sekmeler veya satırbaşları içermediğini varsayabilirsiniz.

Mücadeleyi gönderirken boşluk gruplarına mı yoksa boşluklara mı ayrılacağımı (yani okay theniki boşlukla mı yoksa olacağına ["okay", "then"]["okay", "", "then"]) belirtmeyi unuttum , böylelikle ayrılmanın her iki şeklini de kabul edebilirsiniz.

Test durumları

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

puanlama

Bu , en az bayt olan gönderim kazanır!


Bu soru sanal alan olmuştur .
LyricLy

apple(s)Test durumu applesyerine vermeli mi? Otherwise, if the word is the first word in the string . . . replace the (s) at the end of the word with s.Zorluk, bu davanın applesilk üç revizyon için kum havuzunda ortaya çıktığını ancak dördüncü olarak değiştiğini belirtiyor .
fireflame241

@ fireflame241 Kuralların ikinci taslağını yazarken, dizenin başlangıcı değişmeyecek şekilde yapacağım. Bu kuralı daha sonra değiştirdim, ancak test vakasını değiştirmedim. İyi yakalama.
LyricLy

Test durumu önerisi: There's a single banana(s)-> There's a single bananas.
Jonathan Allan,

1
@ JonathanAllan Yapamazsınız. Birkaç test durumu ekleyeceğim.
LyricLy

Yanıtlar:


6

Mathematica, 151 148 bayt

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

açıklama

j=" ";k=Except@j

jBir boşluk karakterlerine ayarlayın . k"Not j" şablonuna ayarlayın (= boşluk olmayan karakter).

j<>j<>#<>j

İki boşluk bırakın ve girişe bir boşluk bırakın.

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

Desene uyan alt dilimler için:

  1. Bir boşluk (lar), ardından
  2. uzunluk sıfır ya da daha fazla substring sadece boşluk olmayan karakter (ler) (nicelik) 'den oluşan (bu çağrı a), ve sonra
  3. sadece boşluk karakterlerinden oluşan bir uzunluk-uzun veya uzun alt dizini ( sbunu söyle)
  4. uzunluk, bir ya da daha fazla substring sadece boşluk olmayan karakter içeren (ler) i (kelime) (bu çağrı wardından),
  5. dize "(s)", ardından
  6. bir boşluk
Eğer [FreeQ [a, "bir" | "Bir" | "1" | "bir"], "s", ""]

Eğer atek bir kelime (ler) i, değerlendirmek biri değildir "s", aksi takdirde "".

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

İle eşleştirme kalıbını değiştirin j, a, s, w, If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""], ve jbirlikte katıldı.

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

3. pozisyondan 2. pozisyona (1 indeksli; negatif endeksler sondan sayılır) alın. Bunun nedeni, başlangıçta üç boşluk ekledik.


3
Yerleşik çoğul-S'yi kaldırmak için neden kullanılmıyor?
Thomas Weller

5

Python 3 , 94 bayt

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

Çevrimiçi deneyin!

-4 bayt teşekkürler her zaman cri (bunun kabul edilebilir olduğunu düşünüyorum)


@JonathanAllan Sabit, teşekkürler.
HyperNeutrino,

1
__import__daha kısa olamaz ... Evet, normal olarak 4 bayt daha kısa import re.
tamamen insanlık

@icrieverytim huh haklısın (sadece 3 byte olsa) teşekkürler
HyperNeutrino


@icrieverytim ._. Oh iyi. Teşekkürler!
HyperNeutrino


4

Mathematica, 313 bayt

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

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

(s)Kelimenin sonundaki her eşleştir, yerine koy!$1 eşleştirin (1 veya 0) eserler ile değiştirin.


2

Pyth - 53 bayt

Algoritmayı olduğu gibi takip eder.

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

Burada çevrimiçi deneyin .


1
Başarısız there are two banana(s) and one leprechaun(s)(ondan sonra iki boşluk one). Orijinal boşluk korunur, ancak leprechaun(s)öncekini görmezden gelir one.
LyricLy

1
@LyricLy bunu OP'de açıkça belirtmediniz. İki boşlukla ("yöntem (ler) in" bölümünü ("dizeleri boşluklar üzerinde bir kelime listesine ayırın") kullanarak) kullanarak aslında oneve arasında boş bir kelime varleprechaun(s)
Jonathan Allan

2

Jelly ,  52 51  49 bayt

Jöle bir regex atomuna sahip değil

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

Bir dizeyi kabul eden tam bir program (çok satırlıysa veya tırnak içeriyorsa Python biçimlendirmesini kullanarak) ve çıktıyı yazdırmak.

Çevrimiçi deneyin! veya test odasına bakın .

Nasıl?

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

Neden ayrı bir bağlantı olarak kullanıldığını merak ediyorum . Bu , öğeyi orijinal listesinden silmeyi engelliyor mu ?
HyperNeutrino

Hayır, çiftin kuyruğuna ihtiyacım var ... bir yorum yazarak, belki bir kere gördüğünüzde bir golf göreceksiniz.
Jonathan Allan,

Ah tamam. Teşekkürler, bir yorum (veya daha önce) olduğunda golfü anlamaya çalışacağım!
HyperNeutrino

Bu nedenle, 1, 2 ve 3 numaralı linkler tüm kuyrukları ve 5 numaralı link çağırmayı seçer ve Ŀbunu kullanır , ama ben 4 numaralı linkte kuyruk yapmanın kısa bir yolunu göremiyorum, ama olabilir. Bağlantı 4'ün kuyruğunu oradan da almanın bir yolu bile olabilir!
Jonathan Allan,

@HyperNeutrino Bence o Ŀşey ilk bağlantıyı arayabilir, bu yüzden kendi başına bir bağlantıdır.
Outgolfer Erik


1

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

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

Çevrimiçi deneyin!


1
Test durumlarında değil ama bunun başarısız olduğunu düşünüyorum a hel(s)lo.
Neil

Bu, test durumunda sağlandığı şekilde çalışıyor. TIO bağlantımdaki test senaryolarının altına yakın.
Xcali

Tamam, sadece a hel(s)lotest senaryosuna eklenmem gerekecek , ve sonra belki kodunuzu düzeltebilirsiniz ...
Neil

0

JavaScript (ES6), 88 87 bayt

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

Açıklama çok yakında.


1
Eğer yerine \s`` e göre olan "Sen dize hiçbir yeni satır, sekme veya başları içeren varsayabiliriz."
SuperStormer

"Bu bir te (s) t" ifadesiyle başarısız olur. (\s|$)Regex'in sonuna ekleyerek düzeltebilirsiniz .
Birjolaxew

Ayrıca "elma (lar)" da başarısız olur. Bu
TIO'da

Thanks @Birjolaxew, elimden geldiğince değişiklikleri değiştirecek ...
XavCo7

0

JavaScript (ES6), 84 bayt

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

Ne yazık ki 2 byte uzunluğunda olan son kısmı yeniden düzenlemenin ilginç bir yolu:

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

0

JavaScript (SpiderMonkey) , 82 bayt

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

Çevrimiçi deneyin!

78 Bayt versiyonu (daha az sağlam)

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

Bu ETHproductions'un değiştirilmiş bir versiyonudur '(50 temsilcim yok)

açıklama

  • /(\S+ +(\S+))\(s\)/g- aranacak gerçek desen ( amount object(s))
  • (_,a)=>a- _tüm değişkenleri bir yakalama a,(\S+ +(\S+))
  • "s"[+/^(1|one|an?)/i.test(a)]||""- diziyi dilimlemek yerine, sadece sahte bir dizi yapın ve dizini alın ( +/.../.testbir sayı döndürür)
    • gereken "s"[+/^(1|one|an?)/i.test(a)]geri undefined( trueya da 1deney için) geri""
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.