Konwertuj liczbę pojedynczą na liczbę mnogą


27

Istnieją dwie formy rzeczowników: pojedyncza i mnoga. Konwersja między tymi dwoma jest dość łatwa.

  1. Zwykle kończysz to s. dawny. car=> cars.

  2. Jeśli kończy się s, x, z, chlub sh, zakończ go es. dawny. bus=> buses.

  3. Jeśli kończy ysię spółgłoską tuż przed nim, zmień ysię ies. dawny. penny=> pennies.

  4. Jeśli kończy się na flub fe, zmień na ves. dawny. knife=> knives.

  5. Jeśli kończy osię tuż przed nim spółgłoską, zmień ją na oes. dawny. potato=> potatoes.


Zadanie

Otrzymasz rzeczownik w liczbie pojedynczej. Musisz przekonwertować rzeczownik na liczbę mnogą i wyprowadzić go.


Zasady

  • Nie otrzymasz rzeczowników nieregularnych, takich jak mousei moose.

  • Nie otrzymasz wyjątków, takich jak safe( safes; naruszenie # 4), piano( pianos; naruszenie # 5) i o( oes, naruszenie # 5).

  • Nie otrzymasz słów, które mają dwie lub więcej możliwych form liczby mnogiej, takich jak mosquito( mosquitoslub mosquitoes) i roof( roofslub rooves).

  • Nie otrzymasz rzeczowników niepoliczalnych.

  • y nie liczy się jako samogłoska.


Przykłady

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

Edytowane pytanie dla jasności. Zapraszam do wycofania.
— JungHwan Min

11
Ahh, angielski - ogromny stos arbitralnych zasad i specjalnych przypadków :)
— Esolanging Fruit

38
@ Challenger5 Tak, ale możesz to zrozumieć poprzez trudne, gruntowne przemyślenia. ;)
— JungHwan Min

@MatthewRoh Zredagowałem regułę spółgłoski z przodu, aby była bardziej przejrzysta. Dodano również kilka przypadków testowych dla tego samego. Jeśli źle zrozumiałem, edytuj go, aby wyjaśnić.
— ghosts_in_the_code

2
@ Challenger5 Jeśli porównasz angielski do holenderskiego, prawie nie ma żadnych reguł. W holenderskim obowiązują zasady i specjalne przypadki, a także specjalne przypadki sprzeczne z tymi szczególnymi przypadkami, aw niektórych przypadkach nawet specjalne przypadki, które są sprzeczne z tymi szczególnymi przypadkami, które są sprzeczne z tymi szczególnymi przypadkami. ;)
— Kevin Cruijssen

Odpowiedzi:


46

Mathematica, 9 bajtów

Pluralize

Tak, jest do tego wbudowany!

Próbka wyjściowa

Pluralize["car"]

cars

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

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


6
Waaaaaat! Czy jest coś, dla czego Mathematica nie ma wbudowanego?
— KeyWeeUsr

2
D: Wbudowane również zaatakowały to wyzwanie
— Matthew Roh


18

Retina , 57 53 56 55 58 57 bajtów

Dzięki MartinEnder za sugestie dotyczące gry w golfa

Dzięki BusinessCat za grę w golfa 1 bajt

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

Wypróbuj online!

Wyjaśnienie (nieaktualne)

([^aeiou])y$
$1ie

Zmiany {consonant}yna{consonant}ie

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

Dołącza edo tego, kiedy kończy się słowo z {consonant}o, f, x, z, s, shlub ch.

fe$
ve

Zmienia zakończenie fenave

$
s

Na koniec dodaj sdo słowa.

Edycje

  • Dodano bajty, ponieważ zapomniałem drugiej reguły
  • Dodano bajty do aktualizacji eyejako przykład

1
Przepraszam, jeśli to głupie pytanie, nie użyłem Retiny. Dlaczego nawiasy okrągłe są potrzebne w pierwszej linii?
— user2390246

Nieważne, myślę, że odpowiedziałem na własne pytanie. Jest to spowodowane odwołaniem wstecznym w poniższym wierszu.
— user2390246

Tak, ponieważ chcemy uchwycić postać przed yużyciem$1
— Kritixi Lithos

Myślę, że mam go w 57 bajtach: Wypróbuj online
— Business Cat

16

JavaScript (ES6),  109  97 bajtów

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

Wypróbuj online!


Dlaczego masz ()przed sobą fe?
— Kodos Johnson

1
@KodosJohnson Wszystkie replace()iteracje zawierają odniesienie do pierwszej pasującej grupy (z $1). Dlatego potrzebuję tutaj pustej pasującej grupy.
— Arnauld,

Próbowałeś (?<![aeiou])y?
— Tytus

@Titus Niestety JS nie implementuje twierdzeń lookbehind.
— Arnauld

11

Partia, 325 bajtów

@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

A może @echo offna początku, a nie @wszędzie? Poza tym @set/ps=wydaje się trochę zardzewiały z telefonu. Czy szmienna i tak nie zaakceptuje wartości krojenia?
— KeyWeeUsr

@KeyWeeUsr @echo offma już 9 bajtów bez nowej linii, więc nic mnie nie oszczędza. Ponadto @set/ps=konieczne jest, aby wprowadzić wartość w pierwszej kolejności.
— Neil

7

Haskell, 216 207 205 bajtów

Dzięki @Lynn, @ user1472751 i @Laikoni za pomoc!

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"

Czytelny

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"

Wyjaśnienie

import Data.Listdla funkcji isSuffixOf. endsWithOneOf( €w wersji golfowej) zwraca informację, czy jeden z elementów listy jest końcem ciągu. consonants(c)to tylko lista wszystkich spółgłosek.

Na koniec pluralize(p)sprawdza zakończenia i zwraca odpowiednią liczbę mnogą.

Przykład:

p "potato" == "potatoes"

1
Fajne rozwiązanie! Ma 216 znaków , ale €ma wiele bajtów, co czyni rozwiązanie 226 bajtami. (Wyzwania związane z golfem kodowym są jednoznacznie punktowane w bajtach, ponieważ zliczanie znaków pozwala czasem oszukiwać.) Możesz jednak zmienić jego nazwę !! Ponadto words"s x z ch sh"oszczędza 5 bajtów. Usuwając parens (map(:"o")c))i (map(:"y")c))oszczędzasz 4 kolejne.
— Lynn,

Dzięki za pomoc, @Lynn! Wdrożyłem twoje sugestie.
— Eisfunke

2
Możesz zapisać jeden bajt, c=['b'..'z']\\"eiou"ponieważ 'a'jest zawsze usuwany.
— user1472751

1
0<1jest o jeden bajt krótszy niż True. Również nowe wiersze mają tę samą liczbę bajtów, ;ale sprawiają, że kod w golfa jest nieco lepiej czytelny.
— Laikoni

5

Perl, 66 + 2 ( -plflaga) = 68 bajtów

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

Za pomocą:

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

Wypróbuj na Ideone.


5

Röda , 80 bajtów

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

Funkcja modyfikuje swój argument. Użycie: main word { f word; print word }Oto wersja, która używa wartości zwracanej (83 bajty):

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

Poniżej znajduje się funkcja, która odczytuje nieskończenie wiele wartości ze strumienia wejściowego i wypycha liczbę mnogą do strumienia wyjściowego ( 87 83 bajtów):

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

Jest to funkcja anonimowa, ponieważ jest krótsza niż tworzenie funkcji nazwanej.


Jak wyświetlić wynik pierwszej funkcji (tej rozpoczynającej się od f&s)? Po prostu f("word")nic nie wyświetla
— Kritixi Lithos

@KritixiLithos Parametr jest odwołaniem, więc argument musi być zmienną.
— fergusq

5

PHP, 103 100 bajtów

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

Wypróbuj online!

preg_replaceFunkcja wykonuje się w szeregu wzorów i wymiany.

  • Zaoszczędzono 2 bajty dzięki Tytusowi.
  • Zaoszczędzono 1 bajt dzięki Dewi Morganowi.

2
Myślę, że możesz zapisać jeden bajt za pomocą -Ri $argn. A użycie twierdzenia z yzapisem dwa: (?<![aeiou])y$pozwala iena zastąpienie: nie \1, bez cudzysłowów.
— Tytus

1
Kolejny bajt od([^aeiou]o|sh?|x|z|ch)$
— Dewi Morgan

@Titus W rzeczywistości wygląda na to, że istnieje 1 bajtowa kara za użycie -R(ale nie -r), więc nie zmienia to liczby bajtów, niestety. Ale sugestia wyglądu działa świetnie. Dzięki.
— Kodos Johnson

4

Python 3, 271 239 199 bajtów

Dzięki @ovs za zmniejszenie go o 72 bajty!

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"

Wypróbuj online!


1
Możesz usunąć niepotrzebne białe znaki i połączyć pierwszą i ostatnią elif. Listy pojedynczych znaków można zastąpić ciągami. Przejście na Python oszczędza dodatkowe 3 bajty. tio
— ovs

@ovs Gotowe, dziękuję! Nie połączyłem elifjednak s, ponieważ to oznacza, że potatostaje się potaties.
— numbermaniac

1
Patrzyłem w niewłaściwą linię;). Możesz połączyć if z ostatnim elifem. Aby zaoszczędzić trochę więcej bajtów, zamień ostatni wiersz na print(s+"s")i usuń także literę else oraz każdą dołączaną do słowa. Tio
— ovs

1
Kiedy zamienisz logikę if / elif na and/*i or/+wykonasz nienazwaną funkcję lambda, możesz uzyskać ją poniżej 200 bajtów (nieco zamieniłem skrzynki)
— dniu

@ovs Ooh, print(s+"s")to sprytne. Wszystko zmienione; napisałeś prawie wszystko, lol. Dzięki! (Nawet nie wiedziałem, że możesz to zrobić True and "string")
— numermaniak

2

sed, 70 79 bajtów

69 78 + 1 dla flagi -E(BSD) / -r(GNU)

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

Bezpośredni port odpowiedzi siatkówki .


2

Pip , 63 61 bajtów

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

Tak blisko złapania siatkówki! Ale prawdopodobnie tak się nie stanie. :(

Wypróbuj online!

Wyjaśnienie

Podstawowa strategia: Replace wykonuje kilka zamian jedna po drugiej, gdy podane są listy wzorców i zamienników. Chcemy dokonać następujących zamienników:

  • (sh?|x|z|ch)$ -> dodaj e
  • [^aeiou]y-> zmienić ysię ii dodaje
  • fe?-> zmień vi dodaje
  • [^aeiou]o -> dodaj e

Następnie chcemy zająć się s niezależnie.

Wydziwianie:

  • COperatora, ponieważ wyrażenie regularne, zawija się w grupie chwytu; C`xyz`jest o jeden bajt krótszy niż`(xyz)` .
  • Listę wyrażeń regularnych lub zamienników, które kończą się tym samym znakiem, można utworzyć, łącząc znak z listą zamiast umieszczać go we wszystkich elementach. Łączenie skalarnego (łańcucha) ze Wzorem (wyrażenia regularne / zamiana) wymusza Wzorzec.
  • Zamiast łączyć s(i zajmować się kolejnością pierwszeństwa Ri .), możemy po prostu Owypowiedzieć główną część słowa, a następnie wydrukować sosobno.

Kod z odstępami i komentarzami:

                  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 bajty:

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

Tak, inny język z wbudowanym (choć musisz dodać odniesienie System.Data.Entity.Design.dll)

Używać:

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

Wydajność:

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

Witamy na stronie. Jak uruchomić ten kod?
— Kreator pszenicy,

@WheatWizard zaktualizowane. Czy powinienem zawrzeć więcej szczegółów (używając instrukcji itp.) W liczbie bajtów?
— RoadieRich

Ciekawa ciekawostka, na odwrót tego (Singularize) zawodzi kilka prostych przypadków testowych. Na przykład jest przekonany, że liczba pojedyncza „kursów” to „cours”.
— Morgan Thrapp

Myślę, że przestrzenie nazw muszą być uwzględnione w tym bajcie, szczególnie biorąc pod uwagę, że nie jest to jeden z „normalnych”. Ale myślę, że musisz także zawinąć to w lambda, przekazując argument do metody. Jest to tylko grupa metod
— pinkfloydx33

@ pinkfloydx33 lepiej teraz?
— RoadieRich

2

Python 199 187 176 bajtów

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

Runner Rails, 18 bajtów

$><<gets.pluralize

Przykład:

$ echo knife | rails r filename.rb
knives

To jest ezoteryczny język.
— Ven

2

Python, 296 bajtów

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

Bezpośredni port Retina:

Rubin , 111 bajtów

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

Wypróbuj online!

Wywołaj przez ruby -lpei podaj plik jak input.txtdla pierwszego argumentu CLI.


Prawdopodobnie może być bardziej „golfowy”. Btw .: Czy można dodawać pliki do TIO?
— stephanmg

0

C, 321 bajtów

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

wyniki:

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

Powinno być wolvesnie wolfves.
— mbomb007

@ceilingcat co z "static C r [256], / * Z =" aeiou ", i = 0, w, n;" zamiast „static C r [256]; C / * Z =„ aeiou ”, i = 0, w, n;"?
— RosLuP,


-1

Java 7, 408 bajtów

Gra w golfa:

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

Zasadniczo testowanie końca łańcucha i dodawanie / zastępowanie liter w zależności od przypadku. Wartości boolean i String na początku służą do usuwania powtórzeń w przypadkach testowych i zmniejszania kodu.

Wersja do odczytu:

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
Nie możesz użyć fragmentu.
— Okx,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.