[Question]
  [
There are two forms of nouns, singular and plural. The conversion between these two is quite easy.
1. Normally, you end it with `s`. ex. `car` => `cars`.
2. If it ends with `s`,`x`,`z`,`ch` or `sh`, end it with `es`. ex. `bus`=>`buses`.
3. If it ends with `y` with a consonant just before it, change the `y` to `ies`. ex. `penny` => `pennies`.
4. If it ends with `f` or `fe`, change it to `ves`. ex. `knife` => `knives`.
5. If it ends with `o` with a consonant just before it, change it to `oes`. ex.`potato` => `potatoes`.
---
# Task
You will be given a singular noun. You have to convert the given noun to plural and output it.
---
# Rules
* You will not be given irregular nouns, like `mouse` and `moose`.
* You will not be given exceptions, such as `safe` (`safes`; violating #4), `piano` (`pianos`; violating #5) and `o` (`oes`, violating #5).
* You will not be given words which have two or more possible plural forms, such as `mosquito` (`mosquitos` or `mosquitoes`) and `roof` (`roofs` or `rooves`).
* You will not be given uncountable nouns.
* `y` doesn't count as a vowel.
---
# Examples
```
car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios
```
  
[Answer]
# Mathematica, 9 bytes
```
Pluralize
```
Yes, there is a built-in for this!
**Sample output**
```
Pluralize["car"]
```
> 
> `cars`
> 
> 
> 
```
Pluralize /@ {"bus", "potato", "knife", "penny", "exception", "wolf", "eye"}
```
> 
> `{"buses", "potatoes", "knives", "pennies", "exceptions", "wolves", "eyes"}`
> 
> 
> 
[Answer]
# [Retina](https://github.com/m-ender/retina), ~~57~~ ~~53~~ ~~56~~ ~~55~~ ~~58~~ 57 bytes
*Thanks to MartinEnder for some golfing suggestions*
*Thanks to BusinessCat for golfing 1 byte*
```
([^aeiou]o|sh?|ch|z|x)$
$1e
fe?$
ve
([^aeiou])y$
$1ie
$
s
```
[Try it online!](https://tio.run/nexus/retina#PcoxDsIwEETRfs5hpKTkBCk5BAJhNhPZirRrYQfFke9uoKH41fun4fLow/XuGW27WcthahLa0fbRwZ2JhZPDm/g/Y/1BJBxy7@JfeG4Zs@nKilXjQiQrvhgSVSu4C1OJpmAl5m9iXsIH "Retina – TIO Nexus")
### Explanation (outdated)
```
([^aeiou])y$
$1ie
```
Changes `{consonant}y` to `{consonant}ie`
```
([^aeiou]o|[fxzs]|[sc]h)$
$&e
```
Appends an `e` to when the word ends with an `{consonant}o`, `f`,`x`,`z`,`s`,`sh` or `ch`.
```
fe$
ve
```
Changes an ending `fe` to `ve`
```
$
s
```
Finally append an `s` to the word.
### Edits
* Added bytes because I forgot the second rule
* Added bytes to update with `eye` as an example
[Answer]
# JavaScript (ES6), ~~109~~ 97 bytes
```
s=>s[R='replace'](/([^aeiou])y$/,'$1ie')[R](/fe?$/,'ve')[R](/([^aeiou]o|[sxz]|[cs]h)$/,'$1e')+'s'
```
[Try it online!](https://tio.run/##bdDRbsIgFIDhe5@iMSaUzK3x2tS9g7ekSxg9KNpwmp5a7eK7dyhbNT1yx88HAQ6602QaV7fvHksYbD5QviG1zUUDdaUNiCLNUvWlweGpkP0iW4rFyoGQahtWLHzeSvc/HyVeFV1@iqsyVOxl3BXQmyAxGPSEFXxUuEttOje6mUu5Tv5GliX5JgmRZhP4fSIOQwQma2x1iyOOMkaOj95ZeBwccYjdi3PB@35Kb9FxCxcDdevQRx/tGBk/Y2WfXhd5iC9uAT3wfwiRwRIMsuveI6ONLh1O6T3S8As "JavaScript (Node.js) – Try It Online")
[Answer]
## Batch, 325 bytes
```
@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
```
[Answer]
# Haskell, 216 207 205 bytes
Thanks to @Lynn, @user1472751 and @Laikoni for the help!
```
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"
```
## Readable
```
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"
```
## Explanation
`import Data.List` for the function `isSuffixOf`.
`endsWithOneOf` (`€` in the golfed version) returns whether one of the list elements is an ending of the string.
`consonants(c)` is just a list of all consonants.
Finally, `pluralize(p)` checks for the endings and returns the proper pluralization.
Example:
```
p "potato" == "potatoes"
```
[Answer]
# Perl, 66 + 2 (`-pl` flag) = 68 bytes
```
$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/$1i/+s/fe?$/v/?es:"s"
```
Using:
```
perl -ple '$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/$1i/+s/fe?$/v/?es:"s"' <<< car
```
[Try it on Ideone.](http://ideone.com/LIMaEo)
[Answer]
# [Röda](https://github.com/fergusq/roda), 80 bytes
```
f&s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve"s.="s"}
```
The function modifies its argument. Usage: `main word { f word; print word }` Here's a version that uses a return value (83 bytes):
```
f s{s~="([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve";[s.."s"]}
```
And below is a function that reads infinitely many values from the input stream and pushes plural forms to the output stream (~~87~~ 83 bytes):
```
{replace"([^aeiou])y$","$1ie","([sxz]|[cs]h|[^aeiuo]o)$","$1e","fe?$","ve","$","s"}
```
It's an anonymous function, as that is shorter than creating a named function.
[Answer]
# PHP, ~~103~~ 100 bytes
```
<?=preg_replace(['/([^aeiou]o|sh?|x|z|ch)$/','/(?<![aeiou])y$/','/fe?$/'],['\1e',ie,ve],$argv[1]).s;
```
[Try it online!](https://tio.run/nexus/php#JclbCoAgEEDRtQSBCUPRd4YLmSwkJhUCxR5UuHcL@rvck4XsQyQzRQqrnqlC1lQ4anL@UD5tVqYrPWm2vGwYfCZFgb/y@18LyS8UIBtaYuAITlJQ6mhObBWvty7nHPyud/8C "PHP – TIO Nexus")
The `preg_replace` function takes in an array of patterns and replacements.
* Saved 2 bytes thanks to Titus.
* Saved 1 byte thanks to Dewi Morgan.
[Answer]
# Python 3, ~~271~~ ~~239~~ 199 bytes
Thanks to @ovs for reducing it by 72 bytes!
```
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"
```
[Try it online!](https://tio.run/nexus/python3#bY/BbsIwDIbP21NE/ylZyyQ4Viov0uUQ2kRYg7hqQkdBPHtJugrtsJPtX5/9ya7@mk/mfOiMCOVYw1jiCyoZms2u0nUNZ2F8J0JTbXa6wGjBwzJtdSEzts3UtEKJ8RwFeTGqD9AK/zIuM68Df/bJI1xva5ys5Bu0R5QIR2hVvCT8jyRZLJQqEDC7dIFynNbNgFLgcAm59BxN5Nx9e0oP5ch6P@XGXlvbR2Kfhx8@uSWcFqizLS/QYDpi6Or9rR/IR4n7Q9R7cX/gM0nPJkoqnSSl1PwE "Python 3 – TIO Nexus")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~131~~ ~~125~~ ~~118~~ 121 bytes
*Thanks to [The Thonnu](https://codegolf.stackexchange.com/users/114446/the-thonnu) for -6 bytes!  
Golfed 7 bytes!  
Fixed an issue for +3 bytes!*
```
lambda x:S("([sc]h?|x|z)$","\\1e",S(V+"y$","ie",S("fe?$","ve",S(V+"o$","oe",x))))+"s"
import re;S,V=re.sub,"(?<![aeiou])"
```
[Try it online!](https://tio.run/##NclBTsMwEEDRPacYRixs1VRC7Aohh4jUTdOFk4zVUVOPZTskRr17aJD4u6cfSr6If19d1a6jvXWDheXQKFSn1J8v9X25/@gXNNi2b4SmUccdls38J3RUb/r@f7JJHlr0ox0mfOJbkJgh0kdjjlWkfZo6g6r@fD5ZYpnOGlcnEWZgD9jbCN2UIEi2WeDq2REE8r4ALT2FzOJhltEBFYKBeikQ7cCC@xRGzkofQmSf1WycmrVJFCqE1y9Avf4C "Python 3 – Try It Online")
My first submission on here! Let me know if I did anything wrong.
[Answer]
# sed, 70 ~~79~~ bytes
69 ~~78~~ + 1 for `-E` (BSD)/`-r` (GNU) flag
```
s/([^aeiou])y$/\1ie/
s/([^aeiou]o|[fxzs]|[sc]h)$/&e/
s/fe/ve/
s/$/s/
```
Direct port of the [retina answer](https://codegolf.stackexchange.com/a/112080/).
[Answer]
# [Pip](https://github.com/dloscutoff/pip), ~~63~~ 61 bytes
```
Y`[^aeiou]`OaR[C`sh?|x|z|ch`Cy.'y`fe?`y.'o].'$[_B.'i'v_].'e's
```
*So close* to catching Retina! But it's probably not going to happen. :(
[Try it online!](https://tio.run/nexus/pip#JYpBDoIwFET3nqIhJtUNVyCRxK3GnWmQfsuvNGJLoChFPDv@hs28mZc5gkgUdAlL7kO/Zk3QZpoIHkbKZrAqyhc8jFqtIbTOg3dUntZojAKtDUQcFbbeOEv94xodVYiHCpWLhw4q45Jiw85s912uUtwAjRsKeYKLyGVfZ/M4T7OqZR5SHqTGTFJxRcq3ojyk3PB3SQN5v7Afg/3yBw "Pip – TIO Nexus")
### Explanation
Basic strategy: `R`eplace performs several replacements one after the other when given lists of patterns and replacements. We want to make the following replacements:
* `(sh?|x|z|ch)$` -> add an `e`
* `[^aeiou]y` -> change the `y` to `i` and add an `e`
* `fe?` -> change to `v` and add an `e`
* `[^aeiou]o` -> add an `e`
Then we want to tack on an `s` regardless.
Tricks:
* The `C` operator, given a regex, wraps it in a capturing group; `C`xyz`` is one byte shorter than ``(xyz)``.
* A list of regexes or replacements that all end with the same character can be created by concatenating the character to the list instead of including it in all the items. Concatenating a Scalar (string) to a Pattern (regex/replacement) coerces to a Pattern.
* Instead of concatenating the `s` (and having to deal with the precedence ordering of `R` and `.`), we can simply `O`utput the main part of the word and then print the `s` separately.
Spaced and commented code:
```
                  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
```
[Answer]
## C#, ~~73~~ 163 bytes:
```
Func<string,string>p=System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(System.Globalization.CultureInfo.CurrentCulture).Pluralize
```
Yes, another language with it built-in (although you need to add a reference to `System.Data.Entity.Design.dll`)
To use:
```
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}");
}
```
Output:
> 
> 
> ```
> car => cars
> bus => buses
> potato => potatoes
> knife => knives
> penny => pennies
> exception => exceptions
> wolf => wolves
> eye => eyes
> decoy => decoys
> radio => radios
> 
> ```
> 
> 
[Answer]
# 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'
```
[Answer]
## Rails runner, 18 bytes
```
$><<gets.pluralize
```
Example: 
```
$ echo knife | rails r filename.rb
knives
```
[Answer]
**Python,** **296** **bytes**
```
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')
```
[Answer]
# [Lexurgy](https://www.lexurgy.com/sc), 102 bytes
```
Class v {a,e,i,o,u}
p:
*=>es/{s,x,z,ch,zh,!@v o} _ $
y=>ies/!@v _ $
f e?=>ves/_ $
Else:
*=>s/_ $
```
Ungolfed explanation:
```
# define vowels
Class vowel {a,e,i,o,u}
plural:
*=>es/{s,x,z,ch,zh,!@vowel o} _ $ # 2,5
y=>ies/!@vowel _ $                # 3
{f,fe}=>ves/_ $                   # 4
Else:                             # Run the rules below if the above rules don't apply
*=>s/_ $                          # 1
```
[Answer]
## Java 7, 408 bytes
**Golfed:**
```
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";
```
Basically testing what the end of the String is and adding / replacing letters depending on what case it is. The boolean and String at the beginning are just for removing repetition in the test cases and making the code smaller.
**Readable version:**
```
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";
}
```
[Answer]
Direct port of Retina:
# [Ruby](https://www.ruby-lang.org/), 111 bytes
```
'sub(/([^aeiou])y/){"#{$1}ie"};sub(/(.*)([^aeiou]o|[fxzs]|[sc]h)$/){"#{$1}#{$2}e"};sub(/fe/,"ve");sub(/$/,"s")'
```
[Try it online!](https://tio.run/##KypNqvz/X724NElDXyM6LjE1M780VrNSX7NaSblaxbA2M1Wp1hoiq6elCVeRXxOdVlFVHFsTXZwcm6GpAlcPJIxq4XrSUvV1lMpSlTQhXBUgr1hJU/3/f67///ILSjLz84r/6@YUpAIA "Ruby – Try It Online")
Invoke via `ruby -lpe` and supply a file as `input.txt` for first CLI argument.
[Answer]
# C, 321 bytes
```
#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;}
```
test:
```
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;
}
```
results:
```
[car] [cars]
[bus] [buses]
[potato] [potatoes]
[knife] [knives]
[penny] [pennies]
[exception] [exceptions]
[wolf] [wolves]
[eye] [eyes]
[decoy] [decoys]
[radio] [radios]
[radio] [radios]
```
]