There are two forms of nouns, singular and plural. The conversion between these two is quite easy.
Normally, you end it with
s. ex.car=>cars.If it ends with
s,x,z,chorsh, end it withes. ex.bus=>buses.If it ends with
ywith a consonant just before it, change theytoies. ex.penny=>pennies.If it ends with
forfe, change it toves. ex.knife=>knives.If it ends with
owith a consonant just before it, change it tooes. 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
mouseandmoose.You will not be given exceptions, such as
safe(safes; violating #4),piano(pianos; violating #5) ando(oes, violating #5).You will not be given words which have two or more possible plural forms, such as
mosquito(mosquitosormosquitoes) androof(roofsorrooves).You will not be given uncountable nouns.
ydoesn'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
-
\$\begingroup\$ Edited question for clarity. Feel free to rollback. \$\endgroup\$JungHwan Min– JungHwan Min2017年03月05日 17:03:31 +00:00Commented Mar 5, 2017 at 17:03
-
12\$\begingroup\$ Ahh, English - a huge pile of arbitrary rules and special cases :) \$\endgroup\$Esolanging Fruit– Esolanging Fruit2017年03月05日 23:16:15 +00:00Commented Mar 5, 2017 at 23:16
-
42\$\begingroup\$ @Challenger5 Yep, but you can understand it through tough thorough thoughts, though. ;) \$\endgroup\$JungHwan Min– JungHwan Min2017年03月05日 23:20:56 +00:00Commented Mar 5, 2017 at 23:20
-
3\$\begingroup\$ @Challenger5 If you compare English to Dutch there are barely any rules at all.. Dutch has rules and special cases, and special cases contradicting those special cases, and in some cases even special cases that contradict those special cases that those special cases contradict. ;) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年03月06日 08:13:47 +00:00Commented Mar 6, 2017 at 8:13
-
1\$\begingroup\$ @KevinCruijssen you guys should see French... \$\endgroup\$Quentin– Quentin2017年03月07日 12:32:39 +00:00Commented Mar 7, 2017 at 12:32
20 Answers 20
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"}
-
7\$\begingroup\$ Waaaaaat! Is there something Mathematica has no built-in for? \$\endgroup\$KeyWeeUsr– KeyWeeUsr2017年03月06日 20:28:13 +00:00Commented Mar 6, 2017 at 20:28
-
2\$\begingroup\$ D: Builtins have attacked this challenge too \$\endgroup\$Matthew Roh– Matthew Roh2017年03月15日 13:18:02 +00:00Commented Mar 15, 2017 at 13:18
-
1\$\begingroup\$ @KeyWeeUsr codegolf.stackexchange.com/a/71680/56033 \$\endgroup\$Æzor Æhai -him-– Æzor Æhai -him-2017年08月25日 23:42:07 +00:00Commented Aug 25, 2017 at 23:42
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)$
1ドルe
fe?$
ve
([^aeiou])y$
1ドルie
$
s
Explanation (outdated)
([^aeiou])y$
1ドルie
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
eyeas an example
-
1\$\begingroup\$ Sorry if this is a stupid question, I've not used Retina. Why are the round brackets needed in the first line? \$\endgroup\$user2390246– user23902462017年03月06日 07:21:47 +00:00Commented Mar 6, 2017 at 7:21
-
\$\begingroup\$ Never mind, I think I've answered my own question. It's because of the lookback reference in the following line. \$\endgroup\$user2390246– user23902462017年03月06日 08:45:48 +00:00Commented Mar 6, 2017 at 8:45
-
\$\begingroup\$ Yeah, it's because we want to capture the character before the
yusing1ドル\$\endgroup\$user41805– user418052017年03月06日 11:00:29 +00:00Commented Mar 6, 2017 at 11:00 -
\$\begingroup\$ I think I got it in 57 bytes: Try it online \$\endgroup\$Business Cat– Business Cat2017年03月06日 15:56:02 +00:00Commented Mar 6, 2017 at 15:56
JavaScript (ES6), (削除) 109 (削除ここまで) 97 bytes
s=>s[R='replace'](/([^aeiou])y$/,'1ドルie')[R](/fe?$/,'ve')[R](/([^aeiou]o|[sxz]|[cs]h)$/,'1ドルe')+'s'
-
\$\begingroup\$ Why do you have a
()in front offe? \$\endgroup\$Cave Johnson– Cave Johnson2017年03月05日 19:05:17 +00:00Commented Mar 5, 2017 at 19:05 -
1\$\begingroup\$ @KodosJohnson All
replace()iterations include a reference to the first matching group (with1ドル). That's why I need an empty matching group here. \$\endgroup\$Arnauld– Arnauld2017年03月05日 19:11:36 +00:00Commented Mar 5, 2017 at 19:11 -
\$\begingroup\$ Have you tried
(?<![aeiou])y? \$\endgroup\$Titus– Titus2017年03月06日 09:25:09 +00:00Commented Mar 6, 2017 at 9:25 -
\$\begingroup\$ @Titus Unfortunately, JS doesn't implement lookbehind assertions. \$\endgroup\$Arnauld– Arnauld2017年03月06日 11:45:18 +00:00Commented Mar 6, 2017 at 11:45
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
-
\$\begingroup\$ What about
@echo offat the beginning rather than@everywhere? Also,@set/ps=seems a little bit rusty from a phone. Won't thesvariable accept the slicing values anyway? \$\endgroup\$KeyWeeUsr– KeyWeeUsr2017年03月09日 07:44:33 +00:00Commented Mar 9, 2017 at 7:44 -
\$\begingroup\$ @KeyWeeUsr
@echo offis already 9 bytes without the newline, so it doesn't save me anything. Also,@set/ps=is needed to input the value in the first place. \$\endgroup\$Neil– Neil2017年03月09日 08:46:38 +00:00Commented Mar 9, 2017 at 8:46
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"
-
1\$\begingroup\$ Nice solution! This is 216 characters, but
€is multiple bytes long, making your solution 226 bytes. (Code golf challenges are explicitly scored in bytes, because counting characters lets you cheat sometimes.) You can just rename it to!, though! Also,words"s x z ch sh"saves 5 bytes. Removing parens around(map(:"o")c))and(map(:"y")c))saves 4 more. \$\endgroup\$lynn– lynn2017年03月06日 09:58:08 +00:00Commented Mar 6, 2017 at 9:58 -
\$\begingroup\$ Thanks for the help, @Lynn! I implemented your suggestions. \$\endgroup\$Eisfunke– Eisfunke2017年03月06日 14:56:05 +00:00Commented Mar 6, 2017 at 14:56
-
2\$\begingroup\$ You can save one byte by using
c=['b'..'z']\\"eiou"since'a'is always removed. \$\endgroup\$colossus16– colossus162017年03月06日 15:59:20 +00:00Commented Mar 6, 2017 at 15:59 -
1\$\begingroup\$
0<1is one byte shorter thanTrue. Also newlines are the same byte count as;but make the golfed code a bit better readable. \$\endgroup\$Laikoni– Laikoni2017年03月07日 19:13:35 +00:00Commented Mar 7, 2017 at 19:13
Perl, 66 + 2 (-pl flag) = 68 bytes
$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/1ドルi/+s/fe?$/v/?es:"s"
Using:
perl -ple '$_.=/(ch|sh?|x|z|[^aeiou]o)$/+s/([^aeiou])y$/1ドルi/+s/fe?$/v/?es:"s"' <<< car
Röda, 80 bytes
f&s{s~="([^aeiou])y$","1ドルie","([sxz]|[cs]h|[^aeiuo]o)$","1ドルe","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$","1ドルie","([sxz]|[cs]h|[^aeiuo]o)$","1ドルe","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$","1ドルie","([sxz]|[cs]h|[^aeiuo]o)$","1ドルe","fe?$","ve","$","s"}
It's an anonymous function, as that is shorter than creating a named function.
-
\$\begingroup\$ How do you get to display the result of the first function (the one starting with
f&s)? Simplyf("word")doesn't seem to display anything \$\endgroup\$user41805– user418052017年03月05日 19:02:10 +00:00Commented Mar 5, 2017 at 19:02 -
\$\begingroup\$ @KritixiLithos The parameter is a reference, so the argument must be a variable. \$\endgroup\$fergusq– fergusq2017年03月05日 19:04:02 +00:00Commented Mar 5, 2017 at 19:04
PHP, (削除) 103 (削除ここまで) 100 bytes
<?=preg_replace(['/([^aeiou]o|sh?|x|z|ch)$/','/(?<![aeiou])y$/','/fe?$/'],['1円e',ie,ve],$argv[1]).s;
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.
-
2\$\begingroup\$ I think You can save one byte with
-Rand$argn. And using an assertion withysaves two:(?<![aeiou])y$allowsieas replacement: no1円, no quotes. \$\endgroup\$Titus– Titus2017年03月06日 09:17:36 +00:00Commented Mar 6, 2017 at 9:17 -
1\$\begingroup\$ Another byte from
([^aeiou]o|sh?|x|z|ch)$\$\endgroup\$Dewi Morgan– Dewi Morgan2017年03月06日 17:54:53 +00:00Commented Mar 6, 2017 at 17:54 -
\$\begingroup\$ @Titus Actually it looks like there is a 1 byte penalty for using
-R(but not-r) so that doesn't change the byte count, unfortunately. But the lookbehind suggestion works great. Thanks. \$\endgroup\$Cave Johnson– Cave Johnson2017年03月06日 19:32:29 +00:00Commented Mar 6, 2017 at 19:32
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"
-
1
-
\$\begingroup\$ @ovs Done, thanks! I didn't combine the
elifs however, because that meanspotatobecomespotaties. \$\endgroup\$numbermaniac– numbermaniac2017年03月06日 06:47:17 +00:00Commented Mar 6, 2017 at 6:47 -
1\$\begingroup\$ I looked in the wrong line ;). You can combine the if with the last elif. To save some more bytes replace the last line with
print(s+"s")and remove the else case as well every s you are appending to the word. Tio \$\endgroup\$ovs– ovs2017年03月06日 07:06:22 +00:00Commented Mar 6, 2017 at 7:06 -
1\$\begingroup\$ When you replace your if/elif logic with
and/*andor/+and make an unnamed lambda function you can get it under 200 bytes (I swapped the cases a little bit) \$\endgroup\$ovs– ovs2017年03月06日 07:35:08 +00:00Commented Mar 6, 2017 at 7:35 -
\$\begingroup\$ @ovs Ooh, that
print(s+"s")is clever. All changed; you pretty much rewrote the whole thing lol. Thanks! (I didn't even know you could doTrue and "string"like that) \$\endgroup\$numbermaniac– numbermaniac2017年03月06日 07:51:06 +00:00Commented Mar 6, 2017 at 7:51
Python 3, (削除) 131 (削除ここまで) (削除) 125 (削除ここまで) (削除) 118 (削除ここまで) 121 bytes
Thanks to The Thonnu for -6 bytes!
Golfed 7 bytes!
Fixed an issue for +3 bytes!
lambda x:S("([sc]h?|x|z)$","\1円e",S(V+"y$","ie",S("fe?$","ve",S(V+"o$","oe",x))))+"s"
import re;S,V=re.sub,"(?<![aeiou])"
My first submission on here! Let me know if I did anything wrong.
-
1\$\begingroup\$ Hi there, welcome to code golf! Very impressive first answer! \$\endgroup\$2023年04月05日 11:05:11 +00:00Commented Apr 5, 2023 at 11:05
-
1\$\begingroup\$ Welcome to Code Golf, and amazing first answer! You can save 5 bytes by assigning
re.subto a variable: Try it online! \$\endgroup\$The Thonnu– The Thonnu2023年04月05日 11:05:27 +00:00Commented Apr 5, 2023 at 11:05 -
1\$\begingroup\$ And you can save another one by assigning the regex for a consonant to a variable: Try it online! \$\endgroup\$The Thonnu– The Thonnu2023年04月05日 11:10:50 +00:00Commented Apr 5, 2023 at 11:10
-
1\$\begingroup\$ @The Thonnu Thanks a lot! \$\endgroup\$Creative Name– Creative Name2023年04月05日 11:19:13 +00:00Commented Apr 5, 2023 at 11:19
-
\$\begingroup\$ @lyxal Thank you! \$\endgroup\$Creative Name– Creative Name2023年04月05日 11:19:26 +00:00Commented Apr 5, 2023 at 11:19
sed, 70 (削除) 79 (削除ここまで) bytes
69 (削除) 78 (削除ここまで) + 1 for -E (BSD)/-r (GNU) flag
s/([^aeiou])y$/1円ie/
s/([^aeiou]o|[fxzs]|[sc]h)$/&e/
s/fe/ve/
s/$/s/
Direct port of the retina answer.
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. :(
Explanation
Basic strategy: Replace 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 ane[^aeiou]y-> change theytoiand add anefe?-> change tovand add ane[^aeiou]o-> add ane
Then we want to tack on an s regardless.
Tricks:
- The
Coperator, 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 ofRand.), we can simplyOutput the main part of the word and then print thesseparately.
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
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
-
\$\begingroup\$ Welcome to the site. How do I run this code? \$\endgroup\$2017年03月06日 16:06:50 +00:00Commented Mar 6, 2017 at 16:06
-
\$\begingroup\$ @WheatWizard updated. Should I have included more detail (using statements etc) in the byte count? \$\endgroup\$RoadieRich– RoadieRich2017年03月06日 18:28:51 +00:00Commented Mar 6, 2017 at 18:28
-
\$\begingroup\$ Interesting bit of trivia, the reverse of this (Singularize) fails quite a few simple test cases. For example, it's convinced the singular of "courses" is "cours". \$\endgroup\$Morgan Thrapp– Morgan Thrapp2017年03月06日 21:42:27 +00:00Commented Mar 6, 2017 at 21:42
-
\$\begingroup\$ I think the namespaces needs to be included in this one's byte count, especially given that it's not one of the 'normal' ones. But I think you also need to at least wrap this in a lambda, passing the argument to the method. As is this is just a method group \$\endgroup\$pinkfloydx33– pinkfloydx332017年03月07日 00:34:45 +00:00Commented Mar 7, 2017 at 0:34
-
\$\begingroup\$ @pinkfloydx33 better now? \$\endgroup\$RoadieRich– RoadieRich2017年03月07日 16:18:57 +00:00Commented Mar 7, 2017 at 16:18
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'
Rails runner, 18 bytes
$><<gets.pluralize
Example:
$ echo knife | rails r filename.rb
knives
-
\$\begingroup\$ Now that's an esoteric language. \$\endgroup\$Ven– Ven2017年03月09日 09:24:07 +00:00Commented Mar 9, 2017 at 9:24
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')
Lexurgy, 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
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";
}
-
7\$\begingroup\$ You can't use a snippet. \$\endgroup\$Okx– Okx2017年03月06日 10:10:18 +00:00Commented Mar 6, 2017 at 10:10
Direct port of Retina:
Ruby, 111 bytes
'sub(/([^aeiou])y/){"#{1ドル}ie"};sub(/(.*)([^aeiou]o|[fxzs]|[sc]h)$/){"#{1ドル}#{2ドル}e"};sub(/fe/,"ve");sub(/$/,"s")'
Invoke via ruby -lpe and supply a file as input.txt for first CLI argument.
-
\$\begingroup\$ Can probably be more 'golfed'. Btw.: Can one add files to TIO? \$\endgroup\$stephanmg– stephanmg2019年12月03日 13:31:52 +00:00Commented Dec 3, 2019 at 13:31
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]
-
\$\begingroup\$ It should be
wolvesnotwolfves. \$\endgroup\$mbomb007– mbomb0072017年04月06日 18:07:20 +00:00Commented Apr 6, 2017 at 18:07 -
\$\begingroup\$ @ceilingcat what about "static C r[256],/*Z="aeiou",i=0,w,n;" in the place of "static C r[256];C/*Z="aeiou",i=0,w,n;"? \$\endgroup\$user58988– user589882019年12月04日 11:08:15 +00:00Commented Dec 4, 2019 at 11:08
-
1\$\begingroup\$ 260 bytes \$\endgroup\$ceilingcat– ceilingcat2019年12月05日 09:54:44 +00:00Commented Dec 5, 2019 at 9:54