Konversi tunggal ke jamak

27

Ada dua bentuk kata benda, tunggal dan jamak. Konversi antara keduanya cukup mudah.

  1. Biasanya, Anda mengakhirinya dengan s. ex. car=> cars.

  2. Jika berakhir dengan s, x, z, chatau sh, berakhir dengan es. ex. bus=> buses.

  3. Jika diakhiri dengan ykonsonan tepat sebelum itu, ubah yke ies. ex. penny=> pennies.

  4. Jika diakhiri dengan fatau fe, ubah ke ves. ex. knife=> knives.

  5. Jika diakhiri dengan okonsonan tepat sebelum itu, ubah ke oes. ex. potato=> potatoes.


Tugas

Anda akan diberi kata benda tunggal. Anda harus mengonversi kata benda yang diberikan ke jamak dan mengeluarkannya.


Aturan

  • Anda tidak akan diberi kata benda tidak beraturan, seperti mousedan moose.

  • Anda tidak akan diberikan pengecualian, seperti safe( safes; melanggar # 4), piano( pianos; melanggar # 5) dan o( oes, melanggar # 5).

  • Anda tidak akan diberikan kata-kata yang memiliki dua atau lebih bentuk jamak yang mungkin, seperti mosquito( mosquitosatau mosquitoes) dan roof( roofsatau rooves).

  • Anda tidak akan diberi kata benda yang tak terhitung jumlahnya.

  • y tidak dihitung sebagai vokal.


Contohnya

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios
Matthew Roh
sumber
Pertanyaan yang diedit untuk kejelasan. Jangan ragu untuk mengembalikan.
JungHwan Min
11
Ahh, Bahasa Inggris - tumpukan besar aturan arbitrer dan kasus-kasus khusus :)
Esolanging Fruit
38
@ Challenger5 Yap, tetapi Anda bisa memahaminya melalui pikiran yang saksama dan saksama. ;)
JungHwan Min
@ MatthewRoh Saya telah mengedit konsonan di aturan depan untuk membuatnya lebih jelas. Juga menambahkan beberapa test case untuk hal yang sama. Jika saya salah paham, harap edit untuk menjelaskan.
ghosts_in_the_code
2
@ Challenger5 Jika Anda membandingkan bahasa Inggris dengan Belanda, hampir tidak ada aturan sama sekali. Belanda memiliki aturan dan kasus khusus, dan kasus khusus yang bertentangan dengan kasus khusus tersebut, dan dalam beberapa kasus bahkan kasus khusus yang bertentangan dengan kasus khusus yang bertentangan dengan kasus khusus tersebut. ;)
Kevin Cruijssen

Jawaban:

46

Mathematica, 9 byte

Pluralize

Ya, ada built-in untuk ini!

Output sampel

Pluralize["car"]

cars

Pluralize /@ {"bus", "potato", "knife", "penny", "exception", "wolf", "eye"}

{"buses", "potatoes", "knives", "pennies", "exceptions", "wolves", "eyes"}

JungHwan Min
sumber
6
Waaaaaat! Apakah ada sesuatu yang tidak dimiliki Mathematica di dalamnya?
KeyWeeUsr
2
D: Orang Builtin juga telah menyerang tantangan ini
Matius Roh
18

Retina , 57 53 56 55 58 57 byte

Terima kasih kepada MartinEnder untuk beberapa saran bermain golf

Terima kasih kepada BusinessCat untuk bermain golf 1 byte

([^aeiou]o|sh?|ch|z|x)$
$1e
fe?$
ve
([^aeiou])y$
$1ie
$
s

Cobalah online!

Penjelasan (kedaluwarsa)

([^aeiou])y$
$1ie

Perubahan {consonant}yke{consonant}ie

([^aeiou]o|[fxzs]|[sc]h)$
$&e

Menambahkan sebuah eketika kata berakhir dengan {consonant}o, f, x, z, s, shatau ch.

fe$
ve

Mengubah akhiran femenjadive

$
s

Akhirnya tambahkan skata.

Suntingan

  • Menambahkan byte karena saya lupa aturan kedua
  • Menambahkan byte untuk diperbarui dengan eyesebagai contoh
Kritixi Lithos
sumber
1
Maaf jika ini pertanyaan bodoh, saya belum pernah menggunakan Retina. Mengapa kurung bundar dibutuhkan di baris pertama?
user2390246
Sudahlah, saya pikir saya sudah menjawab pertanyaan saya sendiri. Itu karena referensi lookback di baris berikut.
user2390246
Ya, itu karena kami ingin menangkap karakter sebelum ymenggunakan$1
Kritixi Lithos
Saya rasa saya mendapatkannya dalam 57 byte: Cobalah secara online
Business Cat
16

JavaScript (ES6),  109  97 byte

s=>s[R='replace'](/([^aeiou])y$/,'$1ie')[R](/fe?$/,'ve')[R](/([^aeiou]o|[sxz]|[cs]h)$/,'$1e')+'s'

Cobalah online!

Arnauld
sumber
Mengapa Anda punya ()di depan fe?
Kodos Johnson
1
@KodosJohnson Semua replace()iterasi menyertakan referensi ke grup yang cocok pertama (dengan $1). Itu sebabnya saya perlu grup pencocokan kosong di sini.
Arnauld
Sudahkah Anda mencoba (?<![aeiou])y?
Titus
@Titus Sayangnya, JS tidak menerapkan pernyataan lookbehind.
Arnauld
11

Batch, 325 byte

@set/ps=
@for %%v in (a e i o u)do @(
for %%e in (o y)do @if %s:~-2%==%%v%%e goto s
if %s:~-2%==%%vf set s=%s:~,-1%ve&goto s
if %s:~-3%==%%vfe set s=%s:~,-2%ve&goto s
)
@if %s:~-1%==y set s=%s:~,-1%ie
@for %%e in (o s x z)do @if %s:~-1%==%%e set s=%s%e
@for %%e in (c s)do @if %s:~-2%==%%eh set s=%s%e
:s
@echo %s%s
Neil
sumber
Bagaimana dengan @echo offdi awal daripada di @mana - mana? Juga, @set/ps=sepertinya sedikit berkarat dari telepon. Bukankah svariabel akan menerima nilai slicing?
KeyWeeUsr
@KeyWeeUsr @echo offsudah 9 byte tanpa baris baru, jadi itu tidak menyelamatkan saya apa pun. Juga, @set/ps=diperlukan untuk memasukkan nilai di tempat pertama.
Neil
7

Haskell, 216 207 205 byte

Terima kasih kepada @Lynn, @ user1472751 dan @Laikoni untuk bantuannya!

import Data.List
(!)s=or.map(\x->x`isSuffixOf`s)
c=['b'..'z']\\"eiou"
p s|s!(words"s x z ch sh"++map(:"o")c)=s++"es"|s!map(:"y")c=init s++"ies"|s!["f"]=init s++"ves"|s!["fe"]=(init.init)s++"ves"|0<1=s++"s"

Dapat dibaca

import Data.List;

endsWithOneOf :: String -> [String] -> Bool
endsWithOneOf str ends = (or . map (\end -> end `isSuffixOf` str)) ends 

consonants :: [Char]
consonants = ['a'..'z'] \\ "aeiou"

pluralize :: String -> String
pluralize str
    | str `endsWithOneOf` (words "s x z ch sh" ++ (map (:"o") consonants)) = str ++ "es"
    | str `endsWithOneOf` (map (:"y") consonants) = init str ++ "ies"
    | str `endsWithOneOf` ["f"] = init str ++ "ves"
    | str `endsWithOneOf` ["fe"] = (init.init) str ++ "ves"
    | otherwise = str ++ "s"

Penjelasan

import Data.Listuntuk fungsinya isSuffixOf. endsWithOneOf( dalam versi golf) mengembalikan apakah salah satu elemen daftar adalah akhir dari string. consonants(c)hanyalah daftar semua konsonan.

Akhirnya, pluralize(p)periksa ujung-ujungnya dan kembalikan pluralisasi yang tepat.

Contoh:

p "potato" == "potatoes"
Eisfunke
sumber
1
Solusi bagus! Ini adalah 216 karakter , tetapi panjangnya beberapa byte, membuat solusi Anda menjadi 226 byte. (Tantangan golf code secara eksplisit dicetak dalam byte, karena menghitung karakter membuat Anda kadang-kadang curang.) Namun, Anda dapat mengubah nama saja menjadi !! Juga, words"s x z ch sh"menghemat 5 byte. Menghapus parens di sekitar (map(:"o")c))dan (map(:"y")c))menyimpan 4 lagi.
Lynn
Terima kasih atas bantuannya, @Lynn! Saya menerapkan saran Anda.
Eisfunke
2
Anda dapat menyimpan satu byte dengan menggunakan c=['b'..'z']\\"eiou"karena 'a'selalu dihapus.
user1472751
1
0<1lebih pendek satu byte dari True. Juga baris baru adalah jumlah byte yang sama ;tetapi membuat kode golf sedikit lebih mudah dibaca.
Laikoni
5

Perl, 66 + 2 ( -plbendera) = 68 byte

$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/$1i/+s/fe?$/v/?es:"s"

Menggunakan:

perl -ple '$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/$1i/+s/fe?$/v/?es:"s"' <<< car

Cobalah di Ideone.

Denis Ibaev
sumber
5

Röda , 80 byte

f&s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve"s.="s"}

Fungsi memodifikasi argumennya. Penggunaan: main word { f word; print word }Berikut adalah versi yang menggunakan nilai pengembalian (83 byte):

f s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve";[s.."s"]}

Dan di bawah ini adalah fungsi yang membaca banyak nilai tanpa batas dari aliran input dan mendorong bentuk jamak ke aliran output ( 87, 83 byte):

{replace"([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve","$","s"}

Ini adalah fungsi anonim, karena lebih pendek daripada membuat fungsi bernama.

fergusq
sumber
Bagaimana Anda bisa menampilkan hasil dari fungsi pertama (yang dimulai dengan f&s)? Cukup f("word")tampaknya tidak menampilkan apa-apa
Kritixi Lithos
@KritixiLithos Parameter adalah referensi, jadi argumen harus berupa variabel.
fergusq
5

PHP, 103 100 byte

<?=preg_replace(['/([^aeiou]o|sh?|x|z|ch)$/','/(?<![aeiou])y$/','/fe?$/'],['\1e',ie,ve],$argv[1]).s;

Cobalah online!

The preg_replaceFungsi mengambil dalam berbagai pola dan penggantian.

  • Disimpan 2 byte berkat Titus.
  • Disimpan 1 byte berkat Dewi Morgan.
Kodos Johnson
sumber
2
Saya pikir Anda dapat menyimpan satu byte dengan -Rdan $argn. Dan menggunakan pernyataan dengan ymenghemat dua: (?<![aeiou])y$memungkinkan iesebagai pengganti: tidak \1, tidak ada kutipan.
Titus
1
Byte lain dari([^aeiou]o|sh?|x|z|ch)$
Dewi Morgan
@Titus Sebenarnya sepertinya ada penalti 1 byte untuk menggunakan -R(tetapi tidak -r) sehingga tidak mengubah jumlah byte, sayangnya. Tapi saran di balik itu berfungsi dengan baik. Terima kasih.
Kodos Johnson
4

Python 3, 271 239 199 byte

Terima kasih kepada @ovs karena menguranginya sebesar 72 byte!

lambda s,v="aeiou":(s[-2:]=="fe"and s[:-2]+"ve"or s[:-1]+((s[-1]=="y"and s[-2]not in v)*"ie"or s[-1]=="f"and"ve"or s[-1]+((s[-1]in"sxz"or s[-2:]in["ch","sh"])+(s[-1]=="o"and s[-2]not in v))*"e"))+"s"

Cobalah online!

numbermaniac
sumber
1
Anda dapat menghapus beberapa spasi putih yang tidak perlu dan menggabungkan yang pertama dan terakhir elif. Daftar karakter tunggal dapat diganti dengan string. Beralih ke python menyimpan 3 byte tambahan. tio
ovs
@ovs Selesai, terima kasih! Namun saya tidak menggabungkannya elif, karena itu artinya potatomenjadi potaties.
numbermaniac
1
Saya melihat di baris yang salah;). Anda dapat menggabungkan if dengan elif terakhir. Untuk menyimpan lebih banyak byte, ganti baris terakhir dengan print(s+"s")dan lepaskan case lain dan juga setiap Anda menambahkan kata. Tio
ovs
1
Ketika Anda mengganti logika if / elif Anda dengan and/*dan or/+dan membuat fungsi lambda tanpa nama, Anda bisa mendapatkannya di bawah 200 byte (saya menukar
casingnya
@ovs Ooh, itu print(s+"s")pintar. Semua berubah; Anda cukup banyak menulis ulang semuanya lol. Terima kasih! (Saya bahkan tidak tahu Anda bisa melakukan True and "string"itu)
numbermaniac
2

sed, 70 79 byte

69 78 +1 untuk bendera -E(BSD) / -r(GNU)

s/([^aeiou])y$/\1ie/
s/([^aeiou]o|[fxzs]|[sc]h)$/&e/
s/fe/ve/
s/$/s/

Port langsung dari jawaban retina .

Kevin
sumber
2

Pip , 63 61 byte

Y`[^aeiou]`OaR[C`sh?|x|z|ch`Cy.'y`fe?`y.'o].'$[_B.'i'v_].'e's

Begitu dekat dengan menangkap Retina! Tapi itu mungkin tidak akan terjadi. :(

Cobalah online!

Penjelasan

Strategi dasar: Replace melakukan beberapa penggantian satu demi satu ketika diberikan daftar pola dan penggantian. Kami ingin melakukan penggantian berikut:

  • (sh?|x|z|ch)$ -> tambahkan e
  • [^aeiou]y-> ubah yto idan tambahkane
  • fe?-> ubah menjadi vdan tambahkane
  • [^aeiou]o -> tambahkan e

Lalu kami ingin memakukan pada sterlepas.

Trik:

  • The Coperator, diberikan regex, membungkusnya dalam kelompok menangkap; C`xyz`lebih pendek satu byte dari `(xyz)`.
  • Daftar regex atau penggantian yang semuanya diakhiri dengan karakter yang sama dapat dibuat dengan menggabungkan karakter ke daftar alih-alih memasukkannya ke dalam semua item. Menggabungkan Skalar (string) ke Pola (regex / penggantian) memaksa ke Pola.
  • Alih-alih menyatukan s(dan harus berurusan dengan urutan diutamakan dari Rdan .), kita dapat dengan mudah Omengucapkan bagian utama kata dan kemudian mencetaknya ssecara terpisah.

Kode spasi dan komentar:

                  a is 1st cmdline input (implicit)
Y`[^aeiou]`       Yank the consonant regex into the y variable
O a R             Output (without newline): a, with the following replacements:
 [                List of regexes to replace:
  C `sh?|x|z|ch`    (sh?|x|z|ch)
  Cy . 'y           ([^aeiou])y
  `fe?`             fe?
  y . 'o            [^aeiou]o
 ] . '$           End of list; concatenate $ to each item
 [                List of replacements:
  _                 Identity function (replace with whole match)
  B                 B is short for {b}, a function returning its second argument; as a
                    callback function for regex replacement, the second argument is
                    the value of capturing group 1 (the consonant before y)
    . 'i            To that, concatenate i
  'v                Scalar literal v
  _                 Identity function
 ] . 'e           End of list; concatenate e to each item
's                Return Scalar literal s, which is autoprinted
DLosc
sumber
2

C #, 73 163 byte:

Func<string,string>p=System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(System.Globalization.CultureInfo.CurrentCulture).Pluralize

Ya, bahasa lain dengan itu built-in (meskipun Anda perlu menambahkan referensi ke System.Data.Entity.Design.dll)

Menggunakan:

var words = new[] { "car", "bus", "potato", "knife", "penny", "exception", "wolf", "eye", "decoy", "radio" };
foreach (var word in words)
{
    var plural = p(word);
    Console.Out.WriteLine($"{word} => {plural}");
}

Keluaran:

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios
RoadieRich
sumber
Selamat datang di situs ini. Bagaimana saya menjalankan kode ini?
Wheat Wizard
@WheatWizard diperbarui. Haruskah saya memasukkan lebih detail (menggunakan pernyataan dll) dalam jumlah byte?
RoadieRich
Sedikit hal menarik, kebalikan dari ini (Singularize) gagal beberapa kasus uji sederhana. Sebagai contoh, yakin bahwa "kursus" tunggal adalah "cours".
Morgan Thrapp
Saya pikir ruang nama harus dimasukkan dalam hitungan byte yang satu ini, terutama mengingat bahwa itu bukan salah satu yang 'normal'. Tapi saya pikir Anda juga perlu setidaknya membungkus ini dalam lambda, melewati argumen ke metode. Seperti ini hanya grup metode
pinkfloydx33
@ pinkfloydx33 lebih baik sekarang?
RoadieRich
2

Python 199 187 176 Bytes

lambda s:s+'\bve'*(s[-1]=='f')+'\b\bve'*(s[-2:]=='fe')+'e'*(s[-1]in'sxz'or s[-2:]in('ch','sh')or s[-1]=='o'and s[-2]not in'aiueo')+'\bie'*(s[-1]=='y'and s[-2]not in'aiueo')+'s'
Felipe Nardi Batista
sumber
2

Pelari rel, 18 byte

$><<gets.pluralize

Contoh:

$ echo knife | rails r filename.rb
knives
SztupY
sumber
Nah, itu bahasa esoteris.
Ven
2

Python, 296 byte

z = input()
if z[-1]in['s','x','z','ch','sh']:print(z+'es')
elif z[-1]=='y'and z[-2]not in['a','e','i','o','u']:print(z[:-1]+'ies')
elif z[-2:]=='fe':print(z[:-2]+'ves')
elif z[-1]=='f':print(z[:-1]+'ves')
elif z[-1]=='o'and z[-2]not in['a','e','i','o','u']:print(z[:-1]+'oes')
else:print(z+'s')
just_floating
sumber
0

Pelabuhan langsung Retina:

Ruby , 111 byte

'sub(/([^aeiou])y/){"#{$1}ie"};sub(/(.*)([^aeiou]o|[fxzs]|[sc]h)$/){"#{$1}#{$2}e"};sub(/fe/,"ve");sub(/$/,"s")'

Cobalah online!

Meminta melalui ruby -lpedan menyediakan file input.txtuntuk argumen CLI pertama.

stephanmg
sumber
Mungkin bisa lebih 'golf'. Btw .: Bisakah seseorang menambahkan file ke TIO?
stephanmg
0

C, 321 byte

#define E else if(
#define C unsigned char
C*p(C*b){static C r[999],i,w,n,m;for(n=w=i=0;r[i]=b[i];n=w,w=b[i++]);m=!strchr("aeiou",n);if(strchr("sxz",w)||(w=='h'&&strchr("cs",n))||(w=='o'&&m))r[i++]='e';E'y'==w&&m)r[i-1]='i',r[i++]='e';E'f'==w)r[i-1]='v',r[i++]='e';E'f'==n&&w=='e')r[i-2]='v';r[i++]='s';r[i]=0;return r;}

uji:

C*mx[]={"car","bus","potato","knife","penny","exception","wolf","eye","decoy","radio",0};

main()
{unsigned i;
 for(i=0;mx[i];++i)
    printf("[%s] [%s]\n", mx[i], p(mx[i]));
 return 0;
}

hasil:

[car] [cars]
[bus] [buses]
[potato] [potatoes]
[knife] [knives]
[penny] [pennies]
[exception] [exceptions]
[wolf] [wolves]
[eye] [eyes]
[decoy] [decoys]
[radio] [radios]
[radio] [radios]
RosLuP
sumber
Seharusnya wolvestidak wolfves.
mbomb007
@ceilingcat bagaimana dengan "static C r [256], / * Z =" aeiou ", i = 0, w, n;" di tempat "static C r [256]; C / * Z =" aeiou ", i = 0, w, n;"?
RosLuP
1
260 bytes
ceilingcat
-1

Java 7, 408 byte

Golf:

boolean b="bcdfghjklmnpqrstvwxyzs".contains(String.valueOf(s.charAt(s.length()-2))); String x=s.substring(0,s.length()-1);if(s.endsWith("s")||s.endsWith("x")||s.endsWith("z")||s.endsWith("ch")||s.endsWith("sh"))return s+"es";if(s.endsWith("y")&&b)return x+"ies";if(s.endsWith("f")) return x+"ves";if(s.endsWith("fe"))return s.substring(0,s.length()-2)+"ves";if(s.endsWith("o")&&b)return s+"es";return s+="s";

Pada dasarnya menguji apa akhir dari String dan menambahkan / mengganti huruf tergantung pada kasusnya. Boolean dan String pada awalnya hanya untuk menghapus pengulangan dalam kasus uji dan membuat kode lebih kecil.

Versi yang dapat dibaca:

public static String pluralize(String s){

// Consonant at the 2nd last position?
boolean b = "bcdfghjklmnpqrstvwxyzs".contains(String.valueOf(s.charAt(s.length()-2))); 

// Substring for cases where last letter needs to be replaced
String x = s.substring(0,s.length()-1);

if(s.endsWith("s") || s.endsWith("x") || s.endsWith("z") || s.endsWith("ch") || s.endsWith("sh"))
    return s + "es";
if(s.endsWith("y") && b)
    return x + "ies";
if(s.endsWith("f")) 
    return x + "ves";
if(s.endsWith("fe"))
    return s.substring(0,s.length()-2) + "ves";
if(s.endsWith("o") && b)
    return s + "es";

return s += "s";
}
Nick
sumber
6
Anda tidak dapat menggunakan cuplikan.
Okx