Перетворити однину в множину


27

Існує дві форми іменників, однина та множина. Перетворення між цими двома є досить простим.

  1. Зазвичай ви закінчуєте це s. колишній car=> cars.

  2. Якщо вона закінчується s, x, z, chабо sh, в кінці його es. колишній bus=> buses.

  3. Якщо він закінчується yприголосним безпосередньо перед ним, змініть yна ies. колишній penny=> pennies.

  4. Якщо він закінчується fабо fe, змініть його на ves. колишній knife=> knives.

  5. Якщо він закінчується oприголосним безпосередньо перед ним, змініть його на oes. колишній potato=> potatoes.


Завдання

Вам буде дано іменник однини. Ви повинні перетворити даний іменник у множину та вивести його.


Правила

  • Вам не дадуть нерегулярні іменники, як mouseі moose.

  • Вам не дадуть винятків, таких як safe( safes; порушення №4), piano( pianos; порушення №5) та o( oes, порушення №5).

  • Вам не дадуть слова, які мають дві або більше можливих множинних форм, таких як mosquito( mosquitosабо mosquitoes) та roof( roofsабо rooves).

  • Вам не дадуть незлічуваних іменників.

  • y не вважається голосною.


Приклади

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios

Відредаговане питання для наочності. Не соромтеся відкатати.
JungHwan Min

11
Ах, англійська - величезна купа довільних правил та особливих випадків :)
Esolanging Fruit

38
@ Challenger5 Так, але ви можете зрозуміти це через жорсткі ретельні думки. ;)
JungHwan Min

@MatthewRoh Я відредагував приголосний попереду правило, щоб зробити його зрозумілішим. Також додали пару тестових випадків для того ж. Якщо я неправильно зрозумів, будь ласка, відредагуйте його для уточнення.
ghosts_in_the_code

2
@ Challenger5 Якщо порівнювати англійську з голландською мовами, майже немає правил. У голландській мові є правила та особливі випадки, і спеціальні випадки суперечать цим особливим випадкам, а в деяких випадках навіть особливі випадки, які суперечать тим особливим випадкам, яким ці особливі випадки суперечать. ;)
Кевін Круїссен

Відповіді:


46

Математика, 9 байт

Pluralize

Так, для цього є вбудований!

Вибірка зразка

Pluralize["car"]

cars

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

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


6
Ваааааат! Чи є щось, для чого Mathematica не має вбудованого?
KeyWeeUsr

2
Д: Бульдіні також атакували цей виклик
Меттью Ро


18

Сітківка , 57 53 56 55 58 57 байт

Дякую MartinEnder за декілька пропозицій щодо гольфу

Завдяки BusinessCat за гольф на 1 байт

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

Спробуйте в Інтернеті!

Пояснення (застаріле)

([^aeiou])y$
$1ie

Зміни {consonant}yв{consonant}ie

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

Приєднує e, коли слово закінчується {consonant}o, f, x, z, s, shабо ch.

fe$
ve

Змінює закінчення feнаve

$
s

Нарешті додайте sслово до слова.

Правки

  • Додано байтів, тому що я забув друге правило
  • Додано байти для оновлення eyeв якості прикладу

1
Вибачте, якщо це дурне питання, я не використовував Retina. Чому круглі дужки потрібні в першому рядку?
користувач2390246

Неважливо, я думаю, що я відповів на власне запитання. Це пов'язано з посиланням на ретроспективу в наступному рядку.
користувач2390246

Так, це тому, що ми хочемо захопити персонажа перед yвикористанням$1
Kritixi Lithos

Я думаю, я отримав це в 57 байтах: Спробуйте в Інтернеті
Business Cat

16

JavaScript (ES6),  109  97 байт

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

Спробуйте в Інтернеті!


Чому у вас ()перед fe?
Кодос Джонсон

1
@KodosJohnson Усі replace()ітерації включають посилання на першу групу, що відповідає (з $1). Ось чому мені тут потрібна порожня відповідна група.
Арнольд

Ви пробували (?<![aeiou])y?
Тит

@Titus На жаль, JS не реалізовує погляд за твердженнями.
Арнольд

11

Пакетна, 325 байт

@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

А @echo offяк на початку, а не @скрізь? Також, @set/ps=здається, трохи заржавіла від телефону. Невже sзмінна не прийме значення нарізки?
KeyWeeUsr

@KeyWeeUsr @echo off- це вже 9 байт без нового рядка, тому це нічого не врятує мене. Також @set/ps=потрібно ввести значення в першу чергу.
Ніл

7

Haskell, 216 207 205 байт

Дякуємо @Lynn, @ user1472751 та @Laikoni за допомогу!

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"

Читабельна

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"

Пояснення

import Data.Listдля функції isSuffixOf. endsWithOneOf( у версії для гольфу) повертає, чи є одним із елементів списку закінчення рядка. consonants(c)- це лише список усіх приголосних.

Нарешті, pluralize(p)перевіряє закінчення та повертає належну плюралізацію.

Приклад:

p "potato" == "potatoes"

1
Приємне рішення! Це 216 символів , але в кілька байтів, що робить ваше рішення 226 байтами. (Проблеми з кодом для гольфу явно набираються в байтах, тому що підрахунок символів дозволяє вам іноді обманювати.) !Хоча ви можете просто перейменувати його на ! Також words"s x z ch sh"зберігається 5 байт. Видалення паренів навколо (map(:"o")c))та (map(:"y")c))економить ще 4.
Лінн

Дякую за допомогу, @Lynn! Я реалізував ваші пропозиції.
Eisfunke

2
Ви можете зберегти один байт, використовуючи, c=['b'..'z']\\"eiou"оскільки 'a'він завжди видаляється.
користувач1472751

1
0<1на один байт коротший за True. Також нові рядки - це те саме число байтів, ;що й код, але роблять поле для гольфу трохи легше для читання.
Лайконі


5

Roda , 80 байт

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

Функція змінює свій аргумент. Використання: main word { f word; print word }Ось версія, яка використовує повернене значення (83 байти):

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

А нижче - функція, яка зчитує нескінченно багато значень із вхідного потоку та підштовхує множинні форми до вихідного потоку ( 87 83 байти):

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

Це анонімна функція, оскільки вона коротша, ніж створення іменованої функції.


Як ви можете відобразити результат першої функції (тієї, що починається з f&s)? Просто f("word")здається, що нічого не відображається
Kritixi Lithos

@KritixiLithos Параметр є посиланням, тому аргумент повинен бути змінною.
fergusq

5

PHP, 103 100 байт

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

Спробуйте в Інтернеті!

The preg_replaceФункція приймає масив шаблонів і заміни.

  • Збережено 2 байти завдяки Титу.
  • Збережено 1 байт завдяки Dewi Morgan.

2
Я думаю, ви можете зберегти один байт за допомогою -Rі $argn. І використання твердження із yзбереженням двох: (?<![aeiou])y$дозволяє ieв якості заміни: ні \1, немає лапок.
Тит

1
Ще один байт від([^aeiou]o|sh?|x|z|ch)$
Деві Морган

@Titus Насправді, схоже, існує 1 байт покарання за використання -R(але ні -r), так що, на жаль, не змінюється кількість байтів. Але припущення про перспективу чудово працює. Спасибі.
Кодос Джонсон

4

Пітон 3, 271 239 199 байт

Дякуємо @ovs, що зменшили його на 72 байти!

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
Можна видалити кілька непотрібних пробілів і поєднати перший і останній elif. Окремі списки символів можуть бути замінені рядками. Перехід на пітон економить додаткові 3 байти. tio
ovs

@ovs Готово, дякую! Я не поєднав elifs, однак, тому що це potatoстає potaties.
numbermaniac

1
Я дивився в неправильну лінію;). Ви можете комбінувати if із останнім еліфом. Щоб зберегти ще кілька байтів, замініть останній рядок print(s+"s")і видаліть інший регістр, а також кожне, що додаєте до цього слова. Tio
ovs

1
Якщо ви заміните свою логіку if / elif на and/*та or/+зробите функцію безіменної лямбда, ви можете отримати її під 200 байт (я трохи поміняв справи)
ов

@ovs Оо, print(s+"s")це розумно. Все змінилося; ви майже переписали всю справу, хаха. Спасибі! (Я навіть не знав, що ти можеш так зробити True and "string")
numbermaniac

2

sed, 70 79 байт

69 78 + 1 для -E(BSD) / -r(GNU) прапора

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

Прямий порт відповіді сітківки .


2

Піп , 63 61 байт

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

Так близько до того, щоб зловити Retina! Але це, мабуть, не відбудеться. :(

Спробуйте в Інтернеті!

Пояснення

Основна стратегія: Replace виконує декілька замін одна за одною, коли задаються списки шаблонів та замін. Ми хочемо зробити наступні заміни:

  • (sh?|x|z|ch)$ -> додати e
  • [^aeiou]y-> змінити , yщоб iі додатиe
  • fe?-> змінити vта додатиe
  • [^aeiou]o -> додати e

Тоді ми хочемо братися за sнезалежно.

Прийоми:

  • CОператор, враховуючи регулярний вираз, загортає в групі захоплення; C`xyz`на один байт коротший за `(xyz)`.
  • Список регексів або замін, які всі закінчуються одним і тим же символом, можна створити шляхом приєднання символу до списку замість включення його до всіх елементів. Об'єднання скаляр (рядок) з шаблоном (регулярний вираз / заміна) примушує до шаблону.
  • Замість того, щоб поєднувати s(і мати справу з порядком пріоритетності Rта .), ми можемо просто Oвимовити основну частину слова, а потім надрукувати sокремо.

Розміщений та коментований код:

                  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

2

C #, 73 163 байти:

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

Так, інша мова з вбудованою в нього (хоча вам потрібно додати посилання на System.Data.Entity.Design.dll )

Використовувати:

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}");
}

Вихід:

car => cars
bus => buses
potato => potatoes
knife => knives
penny => pennies
exception => exceptions
wolf => wolves
eye => eyes
decoy => decoys
radio => radios

Ласкаво просимо на сайт. Як запустити цей код?
Пшеничний майстер

@WheatWizard оновлено. Чи повинен я включити більш детальну інформацію (з використанням операторів тощо) у кількість байтів?
RoadieRich

Цікавий біт дрібниць, зворотній бік цього (Singularize) не дає достатньо кількох простих тестових випадків. Наприклад, переконаний, що особливість "курсів" - "кур".
Морган Трапп

Я думаю, що простори імен повинні бути включені до цього числа байтів, особливо враховуючи, що це не один із "нормальних". Але я думаю, вам також потрібно принаймні загортати це в лямбда, передаючи аргумент методу. Оскільки це лише метод групи
pinkfloydx33

@ pinkfloydx33 краще зараз?
RoadieRich

2

Пітон 199 187 176 байт

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'

2

Рейка бігун, 18 байт

$><<gets.pluralize

Приклад:

$ echo knife | rails r filename.rb
knives

Тепер це езотерична мова.
Вен

2

Python, 296 байт

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')

0

Прямий порт Retina:

Рубін , 111 байт

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

Спробуйте в Інтернеті!

Викликати через ruby -lpeта надати файл, як input.txtдля першого аргументу CLI.


Можливо, може бути більше "в гольф". Btw .: Чи можна додати файли до TIO?
stephanmg

0

C, 321 байт

#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;}

тест:

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

результати:

[car] [cars]
[bus] [buses]
[potato] [potatoes]
[knife] [knives]
[penny] [pennies]
[exception] [exceptions]
[wolf] [wolves]
[eye] [eyes]
[decoy] [decoys]
[radio] [radios]
[radio] [radios]

Вона повинна бути wolvesНЕ wolfves.
mbomb007

@ceilingcat як щодо "статичного C r [256], / * Z =" aeiou ", i = 0, w, n;" на місці "статичного C r [256]; C / * Z =" aeiou ", i = 0, w, n;"?
RosLuP


-1

Java 7, 408 байт

Гольф:

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";

В основному тестування того, що є кінцем рядка, та додавання / заміна літер залежно від того, в якому випадку це. Булевий і String на початку - це лише видалення повторень у тестових випадках та зменшення коду.

Читаема версія:

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";
}

6
Ви не можете використовувати фрагмент.
Окс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.