단수를 복수로 변환


27

단수형과 복수형의 두 가지 형태의 명사가 있습니다. 이 둘 사이의 변환은 매우 쉽습니다.

  1. 일반적으로으로 끝납니다 s. 전의. car=> cars.

  2. 그것으로 끝나는 경우 s, x, z, ch또는 sh, 그것을 끝 es. 전의. bus=> buses.

  3. 그것으로 끝나는 경우 y그냥 전에 자음으로의 변경 yies. 전의. penny=> pennies.

  4. f또는로 끝나는 경우로 fe변경하십시오 ves. 전의. knife=> knives.

  5. o바로 전에 자음으로 끝나는 경우로 변경하십시오 oes. 전의. potato=> potatoes.


태스크

단수 명사를 받게됩니다. 주어진 명사를 복수형으로 변환하여 출력해야합니다.


규칙

  • 당신은 같은 불규칙 명사를 제공하지 않습니다 mousemoose.

  • 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 영어와 네덜란드어를 비교하면 거의 모든 규칙이 거의 없습니다. 네덜란드어에는 규칙과 특수한 경우, 특수한 경우와 모순되는 특수한 경우가 있으며, 특별한 경우에는 모순되는 특수한 경우와 모순되는 경우도 있습니다. ;)
Kevin Cruijssen

답변:


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
D : Builtins도이 도전을 공격했습니다
Matthew Roh


18

레티 나 , 57 53 56 55 58 57 바이트

골프 제안에 대한 MartinEnder에게 감사드립니다.

1 바이트 골프를위한 BusinessCat 덕분에

([^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를 사용하지 않았습니다. 첫 번째 줄에 둥근 괄호가 필요한 이유는 무엇입니까?
user2390246

상관 없어요. 제 질문에 대답 한 것 같습니다. 다음 줄의 전환 참조 때문입니다.
user2390246

예, y사용 하기 전에 캐릭터를 캡처하고 싶기 때문입니다.$1
Kritixi Lithos

나는 57 바이트로 그것을 생각 : 온라인 시도
비즈니스 고양이

16

자바 스크립트 (ES6),  109  97 바이트

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

온라인으로 사용해보십시오!


()앞에 fe있습니까?
Kodos Johnson

1
@KodosJohnson 모든 replace()반복에는 첫 번째 일치하는 그룹에 대한 참조가 포함됩니다 (with $1). 그래서 여기에 빈 일치 그룹이 필요합니다.
Arnauld

당신은 시도 했습니까 (?<![aeiou])y?
Titus

@Titus 불행히도 JS는 lookbehind 어설 션을 구현하지 않습니다.
Arnauld

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=처음에 값을 입력해야합니다.
Neil

7

하스켈 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

도움을 주셔서 감사합니다, @Lynn! 나는 당신의 제안을 이행했습니다.
Eisfunke

2
항상 제거 c=['b'..'z']\\"eiou"되므로 사용하여 1 바이트를 저장할 수 있습니다 'a'.
user1472751

1
0<1보다 1 바이트 짧습니다 True. 또한 개행은 바이트 수와 동일 ;하지만 골프 코드를 좀 더 읽기 쉽게 만듭니다.
Laikoni


5

로다 , 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, 103100 바이트

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

온라인으로 사용해보십시오!

preg_replace기능은 다양한 패턴과 교체를받습니다.

  • Titus 덕분에 2 바이트를 절약했습니다.
  • Dewi Morgan 덕분에 1 바이트를 절약했습니다.

2
나는 당신이 한 바이트를 저장할 수 있다고 생각 -R하고 $argn. 그리고와 주장을 사용하여 y두 개의 저장하기 : (?<![aeiou])y$허용하지 않습니다 ie대체 : 아니 \1, 따옴표.
Titus

1
다른 바이트([^aeiou]o|sh?|x|z|ch)$
Dewi Morgan

@Titus 실제로 그것은 불행히도 바이트 수를 변경하지 않는 ( 사용 -R하지 않는 -r) 1 바이트 페널티 가있는 것처럼 보입니다 . 그러나 전망 제안은 훌륭하게 작동합니다. 감사.
Kodos Johnson

4

Python 3, 271 239 199 바이트

72 바이트만큼 줄인 @ovs에게 감사드립니다!

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 완료, 감사합니다! 나는 결합하지 않은 elif그 수단이 있기 때문에, 그러나의를 potato하게된다 potaties.
numbermaniac

1
나는 잘못된 줄을 보았다;). if와 마지막 elif를 결합 할 수 있습니다. 더 많은 바이트를 절약하려면 마지막 줄을 바꾸고 print(s+"s")else를 제거하고 단어에 추가하는 모든 것을 제거하십시오. Tio
ovs

1
당신이 당신의 경우 / ELIF 논리를 교체 할 때 and/*or/+및 익명의 람다 함수를 만드는 당신은 그것을 얻을 수있는 200 바이트에서 (나는 경우 조금 교환)
OVS

@ovs Ooh, print(s+"s")영리하다. 모두 바뀌었다. 당신은 롤 전체를 거의 다시 썼습니다. 감사! (나는 당신이 그렇게 할 수 있다는 것을 몰랐습니다 True and "string")
numbermaniac

2

sed, 70 79 바이트

(BSD) / (GNU) 플래그는 69 78 + 1-E-r

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->는 변경 yi하고 추가e
  • fe?-> 변경 v및 추가e
  • [^aeiou]o -> 추가 e

그런 다음 우리는 무관심에 시달리고 싶습니다 s.

트릭 :

  • C정규식 주어진 연산자는 캡처 그룹에서 랩; C`xyz`보다 1 바이트 짧습니다 `(xyz)`.
  • 모든 문자에 포함하는 대신 문자를 목록에 연결하여 모두 같은 문자로 끝나는 정규식 또는 대체 목록을 작성할 수 있습니다. 스칼라 (string)를 패턴 (regex / replacement)으로 연결하면 패턴으로 강제됩니다.
  • 대신을 연결의 s(그리고 우선 순위의 순서를 처리 할 필요가 R.), 우리는 간단하게 할 수 있습니다 O다음 단어의 주요 부분 utput과 인쇄 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)는 몇 가지 간단한 테스트 사례에 실패합니다. 예를 들어, "코스"라는 단수는 "쿠어"라고 확신합니다.
Morgan Thrapp

나는 네임 스페이스 가이 바이트 수에 포함되어야한다고 생각합니다. 특히 그것이 '정상적인'것이 아닌 것을 감안할 때입니다. 그러나 나는 적어도 이것을 람다로 감싸서 인수를 메소드에 전달해야한다고 생각합니다. 마찬가지로 이것은 단지 방법 그룹입니다
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

이제는 난해한 언어입니다.
Ven

2

파이썬, 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")'

온라인으로 사용해보십시오!

첫 번째 CLI 인수 ruby -lpe와 같이 파일을 통해 호출 하고 파일을 제공하십시오 input.txt.


아마도 더 '골프'될 수 있습니다. 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

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

기본적으로 문자열의 끝이 무엇인지 테스트하고 어떤 경우에 따라 문자를 추가 / 교체하십시오. 처음에 부울과 문자열은 테스트 사례에서 반복을 제거하고 코드를 더 작게 만들기위한 것입니다.

읽을 수있는 버전 :

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
스 니펫을 사용할 수 없습니다.
Okx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.