Chuyển đổi số ít sang số nhiều


27

Có hai dạng danh từ, số ít và số nhiều. Việc chuyển đổi giữa hai điều này khá dễ dàng.

  1. Thông thường, bạn kết thúc nó với s. ví dụ car=> cars.

  2. Nếu nó kết thúc với s, x, z, chhay sh, kết thúc nó với es. ví dụ bus=> buses.

  3. Nếu nó kết thúc bằng ymột phụ âm ngay trước nó, hãy đổi ythành ies. ví dụ penny=> pennies.

  4. Nếu nó kết thúc bằng fhoặc fe, thay đổi nó thành ves. ví dụ knife=> knives.

  5. Nếu nó kết thúc bằng omột phụ âm ngay trước nó, hãy đổi nó thành oes. ví dụ potato=> potatoes.


Bài tập

Bạn sẽ được cung cấp một danh từ số ít. Bạn phải chuyển đổi danh từ đã cho thành số nhiều và xuất ra nó.


Quy tắc

  • Bạn sẽ không được cung cấp danh từ bất quy tắc, như mousemoose.

  • Bạn sẽ không được đưa ra ngoại lệ, chẳng hạn như safe( safes; vi phạm # 4), piano( pianos; vi phạm # 5) và o( oes, vi phạm # 5).

  • Bạn sẽ không được cung cấp các từ có hai hoặc nhiều dạng số nhiều có thể, chẳng hạn như mosquito( mosquitoshoặc mosquitoes) và roof( roofshoặc rooves).

  • Bạn sẽ không được cung cấp danh từ không đếm được.

  • y không được tính là nguyên âm.


Ví dụ

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

Chỉnh sửa câu hỏi cho rõ ràng. Hãy thoải mái để quay trở lại.
JungHwan Min

11
Ahh, tiếng Anh - một đống lớn các quy tắc tùy ý và các trường hợp đặc biệt :)
Esolanging Fruit

38
@ Challenger5 Yep, nhưng bạn có thể hiểu nó thông qua những suy nghĩ thấu đáo khó khăn, mặc dù. ;)
JungHwan Min

@MatthewRoh Tôi đã chỉnh sửa phụ âm ở quy tắc trước để làm cho nó rõ ràng hơn. Cũng thêm một vài trường hợp thử nghiệm cho cùng. Nếu tôi hiểu lầm, xin vui lòng chỉnh sửa nó để làm rõ.
ghosts_in_the_code

2
@ Challenger5 Nếu bạn so sánh tiếng Anh với tiếng Hà Lan thì hầu như không có bất kỳ quy tắc nào cả. ;)
Kevin Cruijssen

Câu trả lời:


46

Toán học, 9 byte

Pluralize

Vâng, có một tích hợp cho việc này!

Sản lượng mẫu

Pluralize["car"]

cars

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

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


6
Chờ đợi! Có một cái gì đó Mathicala không được tích hợp sẵn?
KeyWeeUsr

2
D: Các nhà xây dựng cũng đã tấn công thử thách này
Matthew Roh


18

Võng mạc , 57 53 56 55 58 57 byte

Cảm ơn MartinEnder cho một số gợi ý chơi golf

Cảm ơn BusinessCat vì đã chơi gôn 1 byte

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

Hãy thử trực tuyến!

Giải thích (lỗi thời)

([^aeiou])y$
$1ie

Thay đổi {consonant}y để{consonant}ie

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

Gắn thêm một eđến khi từ đầu với một {consonant}o, f, x, z, s, shhoặcch .

fe$
ve

Thay đổi một kết thúc fethànhve

$
s

Cuối cùng nối một s từ.

Chỉnh sửa

  • Đã thêm byte vì tôi quên quy tắc thứ hai
  • Đã thêm byte để cập nhật eyelàm ví dụ

1
Xin lỗi nếu đây là một câu hỏi ngu ngốc, tôi đã không sử dụng Retina. Tại sao dấu ngoặc tròn cần thiết trong dòng đầu tiên?
dùng2390246

Đừng bận tâm, tôi nghĩ rằng tôi đã trả lời câu hỏi của riêng tôi. Đó là vì tham chiếu xem lại trong dòng sau.
dùng2390246

Vâng, đó là vì chúng tôi muốn bắt nhân vật trước khi ysử dụng$1
Kritixi Lithos

Tôi nghĩ rằng tôi đã nhận được nó trong 57 byte: Dùng thử trực tuyến
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'

Hãy thử trực tuyến!


Tại sao bạn có một ()ở phía trước fe?
Kodos Johnson

1
@KodosJohnson Tất cả các replace()lần lặp bao gồm một tham chiếu đến nhóm khớp đầu tiên (với $1). Đó là lý do tại sao tôi cần một nhóm phù hợp trống ở đây.
Arnauld

Bạn đã thử (?<![aeiou])ychưa
Tít

@Titus Thật không may, JS không thực hiện các xác nhận lookbehind.
Arnauld

11

Mẻ, 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

Thế còn @echo offlúc đầu chứ không phải @ở khắp mọi nơi? Ngoài ra, @set/ps=có vẻ như một chút gỉ từ điện thoại. Sẽ không có người sbiến chấp nhận các giá trị cắt không?
KeyWeeUsr

@KeyWeeUsr @echo offđã có 9 byte mà không có dòng mới, vì vậy nó không tiết kiệm cho tôi bất cứ điều gì. Ngoài ra, @set/ps=là cần thiết để nhập giá trị ở vị trí đầu tiên.
Neil

7

Haskell, 216 207 205 byte

Cảm ơn @Lynn, @ user1472751 và @Laikoni vì sự giúp đỡ!

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"

Có thể đọc được

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"

Giải trình

import Data.Listcho chức năng isSuffixOf. endsWithOneOf( trong phiên bản được đánh gôn) trả về việc một trong các thành phần danh sách có phải là kết thúc của chuỗi hay không. consonants(c)chỉ là một danh sách của tất cả các phụ âm.

Cuối cùng, pluralize(p)kiểm tra các kết thúc và trả về số nhiều thích hợp.

Thí dụ:

p "potato" == "potatoes"

1
Giải pháp tốt đẹp! Đây là 216 ký tự , nhưng dài nhiều byte, làm cho giải pháp của bạn là 226 byte. (Các thử thách chơi gôn mã được ghi rõ ràng bằng byte, bởi vì việc đếm các ký tự đôi khi cho phép bạn gian lận.) Tuy nhiên, bạn chỉ có thể đổi tên thành !! Ngoài ra, words"s x z ch sh"tiết kiệm 5 byte. Loại bỏ parens xung quanh (map(:"o")c))(map(:"y")c))tiết kiệm thêm 4.
Lynn

Cảm ơn sự giúp đỡ, @Lynn! Tôi thực hiện các đề xuất của bạn.
Eisfunke

2
Bạn có thể lưu một byte bằng cách sử dụng c=['b'..'z']\\"eiou"'a'luôn bị loại bỏ.
dùng1472751

1
0<1là một byte ngắn hơn True. Ngoài ra các dòng mới có cùng số byte như ;nhưng làm cho mã golf dễ đọc hơn một chút.
Laikoni

5

Perl, 66 + 2 ( -plcờ) = 68 byte

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

Sử dụng:

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

Hãy thử nó trên Ideone.


5

Röda , 80 byte

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

Hàm sửa đổi đối số của nó. Cách sử dụng: main word { f word; print word }Đây là phiên bản sử dụng giá trị trả về (83 byte):

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

Và bên dưới là một hàm đọc vô số giá trị từ luồng đầu vào và đẩy các dạng số nhiều sang luồng đầu ra ( 87 83 byte):

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

Đây là một hàm ẩn danh, vì nó ngắn hơn so với việc tạo một hàm được đặt tên.


Làm thế nào để bạn có thể hiển thị kết quả của chức năng đầu tiên (bắt đầu bằng f&s)? Đơn giản f("word")là dường như không hiển thị bất cứ thứ gì
Kritixi Lithos

@KritixiLithos Tham số là tham chiếu, vì vậy đối số phải là biến.
fergusq

5

PHP, 103 100 byte

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

Hãy thử trực tuyến!

Các preg_replacechức năng mất trong một loạt các mô hình và thay thế.

  • Lưu được 2 byte nhờ Titus.
  • Đã lưu 1 byte nhờ Dewi Morgan.

2
Tôi nghĩ rằng bạn có thể lưu một byte với -R$argn. Và sử dụng một xác nhận với ylưu hai: (?<![aeiou])y$cho phép iethay thế: không \1, không có dấu ngoặc kép.
Tít

1
Một byte khác từ([^aeiou]o|sh?|x|z|ch)$
Dewi Morgan

@Titus Trên thực tế, có vẻ như có một hình phạt 1 byte khi sử dụng -R(nhưng không -r) vì vậy điều đó không làm thay đổi số lượng byte, thật không may. Nhưng gợi ý lookbehind hoạt động tuyệt vời. Cảm ơn.
Kodos Johnson

4

Python 3, 271 239 199 byte

Cảm ơn @ovs đã giảm 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"

Hãy thử trực tuyến!


1
Bạn có thể loại bỏ một số khoảng trắng không cần thiết và kết hợp đầu tiên và cuối cùng elif. Danh sách ký tự đơn có thể được thay thế bằng chuỗi. Chuyển sang python tiết kiệm thêm 3 byte. tio
trứng

@ovs Xong, cảm ơn! Tôi không kết hợp elifs Tuy nhiên, bởi vì điều đó có nghĩa potatotrở thành potaties.
numbermaniac

1
Tôi nhìn nhầm hàng;). Bạn có thể kết hợp nếu với elif cuối cùng. Để lưu thêm một số byte thay thế dòng cuối cùng print(s+"s")và loại bỏ trường hợp khác cũng như mọi s bạn đang nối vào từ. Tio
trứng

1
Khi bạn thay thế logic if / elif của mình bằng and/*or/+tạo một hàm lambda không tên, bạn có thể lấy nó dưới 200 byte (tôi đã tráo đổi các trường hợp một chút)
ovs

@ovs Ooh, thật print(s+"s")là thông minh. Tất cả đã thay đổi; bạn viết lại khá nhiều thứ lol. Cảm ơn! (Tôi thậm chí không biết bạn có thể làm True and "string"như vậy)
numbermaniac


2

Pip , 63 61 byte

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

Rất gần để bắt Retina! Nhưng nó có thể sẽ không xảy ra. :

Hãy thử trực tuyến!

Giải trình

Chiến lược cơ bản: Replace thực hiện nhiều lần thay thế lần lượt khi đưa ra danh sách các mẫu và thay thế. Chúng tôi muốn thực hiện các thay thế sau đây:

  • (sh?|x|z|ch)$ -> thêm một e
  • [^aeiou]y-> thay đổi ythành ivà thêm mộte
  • fe?-> thay đổi vvà thêm mộte
  • [^aeiou]o -> thêm một e

Sau đó, chúng tôi muốn giải quyết sbất kể.

Thủ thuật:

  • Các Cnhà điều hành, đưa ra một regex, kết thúc tốt đẹp nó trong một nhóm chụp; C`xyz`là một byte ngắn hơn `(xyz)`.
  • Một danh sách các biểu thức hoặc thay thế mà tất cả kết thúc với cùng một ký tự có thể được tạo bằng cách ghép các ký tự vào danh sách thay vì đưa nó vào tất cả các mục. Ghép một vô hướng (chuỗi) thành một mẫu (regex / thay thế) ép buộc thành một mẫu.
  • Thay vì ghép nối s(và phải xử lý thứ tự ưu tiên của R.), chúng ta chỉ cần Obỏ qua phần chính của từ và sau đó in sriêng.

Mã khoảng cách và nhận xét:

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

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

Có, một ngôn ngữ khác được tích hợp sẵn (mặc dù bạn cần thêm một tham chiếu đến System.Data.Entity.Design.dll)

Để sử dụng:

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

Đầu ra:

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

Chào mừng đến với trang web. Làm thế nào để tôi chạy mã này?
Phù thủy lúa mì

@WheatWizard được cập nhật. Tôi có nên đưa thêm chi tiết (sử dụng câu lệnh vv) vào số byte không?
RoadieRich

Một chút thú vị của những chuyện vặt vãnh, mặt trái của điều này (Singularize) thất bại khá nhiều trường hợp thử nghiệm đơn giản. Ví dụ, nó đã thuyết phục số ít của "khóa học" là "cours".
Morgan Thrapp

Tôi nghĩ rằng các không gian tên cần được bao gồm trong số byte này, đặc biệt là nó không phải là một trong những không gian 'bình thường'. Nhưng tôi nghĩ rằng bạn cũng cần ít nhất bọc cái này trong lambda, truyền đối số cho phương thức. Vì đây chỉ là một nhóm phương pháp
Pinkfloydx33

@ Pinkfloydx33 tốt hơn bây giờ?
RoadieRich

2

Python 199 187 176 byte

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

Người chạy Rails, 18 byte

$><<gets.pluralize

Thí dụ:

$ echo knife | rails r filename.rb
knives

Bây giờ đó là một ngôn ngữ bí truyền.
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')

0

Cổng trực tiếp của Retina:

Ruby , 111 byte

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

Hãy thử trực tuyến!

Gọi qua ruby -lpevà cung cấp một tệp như input.txtđối số CLI đầu tiên.


Có lẽ có thể là "chơi gôn" hơn. Btw.: Có thể thêm tập tin vào TIO không?
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;}

kiểm tra:

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

các kết quả:

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

Nó phải là wolveskhông wolfves.
mbomb007

@ceilingcat những gì về "tĩnh C r [256], / * Z =" aeiou ", i = 0, w, n;" ở vị trí "tĩnh C r [256]; C / * Z =" aeiou ", i = 0, w, n;"?
RosLuP


-1

Java 7, 408 byte

Chơi gôn

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

Về cơ bản kiểm tra phần cuối của Chuỗi là gì và thêm / thay thế các chữ cái tùy thuộc vào trường hợp của nó. Boolean và String ở đầu chỉ là để loại bỏ sự lặp lại trong các trường hợp thử nghiệm và làm cho mã nhỏ hơn.

Phiên bản dễ đọc:

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
Bạn không thể sử dụng một đoạn.
Okx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.