모호한 복수를 제거하십시오!


21

프로그래밍은 매우 엄격합니다. 프로그램에 "바나나 카운트 출력"을 지시 할 수는 없습니다 print(bananas).

그러나 그렇게하면 문제가 생깁니다. 미리 바나나가 몇 개인 지 모르므로 복수를 사용할지 여부를 알 수 없습니다.

때로는 프로그래머가 게으른 길을 간다. 확인하는 대신 그냥 인쇄 there are X banana(s)합니다.

그러나 그것은 추한 일 이므로이 문제를 해결하는 프로그램이 필요합니다.

방법

문자열에서 모호한 복수형을 제거하려면 다음 단계를 수행하십시오.

  1. 공백의 문자열을 단어 목록으로 나눕니다.

  2. 로 끝나는 모든 단어에 (s)대해 다음을 수행하십시오.

    • 위의 단어 인 경우 a, an, 1또는 one은을 제거 (s)단어의 끝에서.
    • 단어 첫 번째 단어가 문자열에 있거나 앞의 단어가 아닌 경우 그렇지 않으면, a, an, 1또는 one의 교체 (s)와 단어의 끝에서 s.
  3. 원래 공백을 유지하면서 단어 목록을 문자열로 다시 결합하십시오.

문자열을 보자 there's a banana(s) and three apple(s).

먼저 문자열을 단어 목록으로 나눕니다. ["there's", "a", "banana(s)", "and", "three", "apple(s)"]

두 번째 단계에서는 (s): 와로 끝나는 두 단어 banana(s)를 사용 apple(s)합니다.

이전의 단어 banana(s)a이므로을 제거하여 (s)만듭니다 banana. 이 단어는 전에 apple(s)이다 three우리가 변경할 수 있도록 (s)로를 s따라서가된다, apples.

우리는 지금이 ["there's", "a", "banana", "and", "three", "apples"]. 리스트를 다시 합치면을 얻습니다 there's a banana and three apples. 이것이 우리의 최종 결과입니다.

도전

모호한 문자열을 합리적인 형식 으로 가져 와서 해당 문자열의 명확한 버전을 반환 하는 프로그램이나 함수를 만듭니다 .

문자열에 줄 바꿈, 탭 또는 캐리지 리턴이 없다고 가정 할 수 있습니다.

챌린지를 게시 할 때 공간 또는 공간 그룹으로 분할할지 (즉 okay then, 두 공간이 있어야 하는지 ["okay", "then"]또는 ["okay", "", "then"])를 지정하지 않았으므로 분할 형식 중 하나를 가정 할 수 있습니다.

테스트 사례

Input                                         -> Output
there are two banana(s) and one leprechaun(s) -> there are two bananas and one leprechaun
there's a banana(s) and three apple(s)        -> there's a banana and three apples
apple(s)                                      -> apples
one apple(s)                                  -> one apple
1 banana(s)                                   -> 1 banana
banana                                        -> banana
preserve    original      whitespace(s)       -> preserve    original      whitespaces
11 banana(s)                                  -> 11 bananas
an apple(s)                                   -> an apple
this is a te(s)t                              -> this is a te(s)t
I am a (s)tranger(s)                          -> I am a (s)tranger

채점

이것이 이므로 최소 바이트를 가진 제출이 승리합니다!


이 질문은 샌드 박스 되었습니다 .
LyricLy

apple(s)테스트 케이스가 apples대신 생산 되어야합니까 ? 도전 과제에 따르면 Otherwise, if the word is the first word in the string . . . replace the (s) at the end of the word with s.이 사례는 apples처음 세 가지 개정판의 샌드 박스에서 생성 되었지만 네 번째 개정에서는 변경되었습니다.
fireflame241241

@ fireflame241 두 번째 규칙 초안을 작성할 때 문자열의 시작이 변경되지 않도록 규칙을 만들려고했습니다. 나중에 그 규칙을 변경했지만 테스트 사례는 변경하지 않았습니다. 잘 잡았습니다.
LyricLy

테스트 사례 제안 : There's a single banana(s)-> There's a single bananas.
Jonathan Allan

1
@JonathanAllan 당신은 할 수 없습니다. 몇 가지 테스트 사례를 추가하겠습니다.
LyricLy

답변:


6

매쓰, 151 148 바이트

StringReplace[j=" ";k=Except@j;j<>j<>#<>j,j~~a:k...~~s:j..~~w:k..~~"(s)"~~j:>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]~StringTake~{3,-2}&

설명

j=" ";k=Except@j

j공백 문자로 설정하십시오 . k"not j"(= 공백이 아닌 문자) 패턴으로 설정하십시오 .

j<>j<>#<>j

두 개의 공백을 앞에두고 입력에 하나의 공백을 추가하십시오.

j~~a:k...~~s:j..~~w:k..~~"(s)"~~j

패턴과 일치하는 하위 문자열의 경우 :

  1. 하나의 공백과 그 뒤에
  2. 공백이 아닌 문자 (정량 자)만으로 구성된 길이가 0보다 긴 하위 문자열 (이것을 호출 a)
  3. 공백 문자만으로 구성된 길이가 1 이상인 하위 문자열 (이것이라고 부름 s)
  4. 길이 - 하나 이상 하위 문자열 만 공백이 아닌 문자로 구성된 (들) (워드) (이 호출 w다음에)
  5. 문자열 "(s)"뒤에
  6. 공백
[FreeQ [a, "a"| "an"| "1"| "one"], "s", ""] 인 경우

a단수형이 아닌 경우 로 평가하고 "s"그렇지 않은 경우로 평가하십시오 "".

StringReplace[..., ... :>{j,a,s,w,If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""]}<>j]

와 일치하는 패턴이 교체 j, a, s, w, If[FreeQ[a,"a"|"an"|"1"|"one"],"s",""], 및 j접합한다.

... ~StringTake~{3,-2}

위치 3에서 위치 -2로 가져갑니다 (1 인덱스, 음수 인덱스는 끝부터 계산). 처음에 세 개의 공백을 추가했기 때문입니다.


3
복수형 S를 제거 할 때 내장을 사용하지 않는 이유는 무엇입니까?
토마스 웰러

5

파이썬 3 , 94 바이트

lambda s,r=re.sub:r(r"\(s\)( |$)","s",r(r"\b(an?|1|one)(\s+)(.+)\(s\)",r"\1\2\3",s))
import re

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

나는 cri critim 덕분에 -4 바이트


@JonathanAllan 감사합니다.
HyperNeutrino

1
__import__아마도 짧을 수는 없습니다 ... 예, 일반보다 4 바이트 짧습니다 import re.
완전히 인간적인

@icrieverytim 당신이 옳습니다 (단 3 바이트) 감사합니다
HyperNeutrino


@icrieverytim ._. 오 좋아요 감사!
HyperNeutrino


4

Mathematica, 313 바이트

(Table[If[StringLength@z[[i]]>3&&StringTake[z[[i]],-3]=="(s)",z[[i]]=StringDrop[z[[i]],-3];t=1;While[z[[i-t]]=="",t++];If[FreeQ[{"a","an","1","one"},z[[i-t]]],z[[i]]=z[[i]]<>"s"]],{i,2,Length[z=StringSplit[#," "]]}];If[StringTake[z[[1]],-3]=="(s)",z[[1]]=StringDrop[z[[1]],-3];z[[1]]=z[[1]]<>"s"];StringRiffle@z)&

3

Perl 5, 43 + 1 (-p) = 44 바이트

s/\b((one|1|an?) +)?\S+\K\(s\)\B/"s"x!$1/ge

(s)단어가 끝날 때마다 일치 하고 !$1(1 또는 0) 에세이로 대체하십시오 .


2

Pyth-53 바이트

알고리즘을 그대로 따릅니다.

K+kczdjdt.e?q"(s)"gb_2+<b_3*\s!}@Ktk[\a"an""one"\1)bK

여기에서 온라인으로 사용해보십시오 .


1
에 실패합니다 there are two banana(s) and one leprechaun(s)( one. 뒤에 두 공백 ). 원래 공백은 유지되지만 이전 공백은 leprechaun(s)무시합니다 one.
LyricLy

1
@LyricLy OP에서 명시 적으로 언급하지 않았습니다. (당신의 "방법 (들)", "단어의 목록에 공간에 문자열을 분할"섹션의 사용 (1))이 공백 사이에 실제로 빈 단어가 oneleprechaun(s)
조나단 앨런

2

젤리 ,  52 51  49 바이트

젤리는 하나의 정규식 원자를 가지고 있지 않습니다

Ṫ
Ñ;”s
Ṫḣ-3
UṪw“)s(”⁼1
“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘
⁶;ḲÇĿ2ƤK

문자열을 수락하고 (여러 줄을 포함하거나 따옴표를 포함하는 경우 Python 형식 사용) 출력을 인쇄하는 전체 프로그램.

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

방법?

Ṫ - Link 1, tail: two words (list of lists)
Ṫ - tail

Ñ;”s - Link 2, tail and replace last three chars with an 's': two words (list of lists)
Ñ    - call the next link (3) as a monad
  ”s - literal 's'
 ;   - concatenate

Ṫḣ-3 - Link 3, tail and remove the last three chars: two words (list of lists)
Ṫ    - tail
  -3 - literal minus three
 ḣ   - head from index (1-indexed and modular)

UṪw“)s(”⁼1 - Link 4, tail ends with "(s)"?: two words (list of lists)
U          - upend (reverse each word)
 Ṫ         - tail
   “)s(”   - literal [')', 's', '('] - that is "(s)" reversed
  w        - index of first sublist equal to that or 0 if not found
         1 - literal one
        ⁼  - equal?

“µḣ⁴µuʠg*»ḲċḢ‘×Ç‘ - Link 5, categorise: two words (list of lists)
“µḣ⁴µuʠg*»        - compression of string "a 1" + word " an" + word " one"
          Ḳ       - split on spaces = ["a", "1", "an", "one"]
            Ḣ     - head (the first word)
           ċ      - count occurrences (of head in the list - either 0 or 1)
             ‘    - increment
               Ç  - call the last link (4) as a monad - i.e. f(two words)
              ×   - multiply
                ‘ - increment - so we have: 1 for ["1", "blah"],
                  -             2 for ["blah", "blah(s)"] or 3 for ["1", "blah(s)"]

⁶;ḲÇĿ2ƤK - Main link: list of characters, the string
⁶        - literal space character
 ;       - concatenate (place a space at the beginning as we want to inspect pairs)
  Ḳ      - split on spaces (giving an empty list at the start)
     2Ƥ  - for all infixes of length two:
    Ŀ    -   call the link at the given index as a monad:
   Ç     -     call the last link (5) as a monad
       K - join the result with spaces
         - implicit print

왜 당신 이 별도의 링크로 사용했는지 궁금 합니다. 이렇게 하면 원래 목록에서 요소가 삭제 되지 않습니까?
HyperNeutrino

아니, 난 쌍의 꼬리를 가져와야 해
Jonathan Allan

아 알았어 고마워요, 해설이 있거나 그 이전에 골프를 발견하려고 노력할 것입니다!
HyperNeutrino

따라서 링크 1, 2 및 3은 모든 꼬리와 링크 5는 호출 할 전화를 선택하고 사용하는 링크를 선택 Ŀ하지만 링크 4 내부에 꼬리를 치는 짧은 방법은 보이지 않지만있을 수 있습니다. 링크 4의 꼬리를 거기에 넣을 수도 있습니다!
Jonathan Allan

@HyperNeutrino Ŀ첫 번째 링크를 호출 할 수 있다고 생각합니다. 이것이 바로 자체 링크입니다.
Outgolfer Erik


1

Perl 5 , 56 + 1 ( -p) = 57 바이트

s/\b(an?|1|one) +\S+\K\(s\)(?= |$)//g;s/\(s\)( |$)/s$1/g

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


1
테스트 사례는 아니지만 이것이 실패한다고 생각합니다 a hel(s)lo.
Neil

테스트 사례에 제공된대로 제대로 작동합니다. 내 TIO 링크에서 테스트 사례의 맨 아래에 있습니다.
Xcali

글쎄, 난 그냥 a hel(s)lo테스트 케이스에 추가하고 코드를 고칠 것입니다 ...
Neil

0

자바 스크립트 (ES6), 88 87 바이트

a=>a.replace(/(\S+)( +)(\S+)\(s\)/g,(m,f,s,w)=>f+s+w+(/^(a|an|1|one)$/.exec(f)?'':'s'))

곧 설명하겠습니다.


1
\s"문자열에 줄 바꿈, 탭 또는 캐리지 리턴이 없다고 가정 할 수 있습니다."에 따라``로 바꿀 수 있습니다.
SuperStormer

"이것은 te (s) t"입니다. (\s|$)정규식 끝에 추가 하여 수정할 수 있습니다 .
Birjolaxew

"apple (s)"에서도 실패합니다. 이 TIO에서 수정되었습니다
Birjolaxew

감사합니다 @Birjolaxew, 내가 할 수있을 때 변경 사항을 편집합니다 ...
XavCo7

0

자바 스크립트 (ES6), 84 바이트

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+(/^(1|an?|one) /.test(a)?'':'s'))

마지막 부분을 재정렬하는 재미있는 방법이 있습니다. 슬프게도 2 바이트가 더 깁니다.

s=>s.replace(/((^|\S+ +)\S+)\(s\)(?!\S)/g,(_,a)=>a+'s'.slice(/^(1|an?|one) /.test(a)))

0

자바 스크립트 (SpiderMonkey) , 82 바이트

s=s.replace(/(\S+ +(\S+))\(s\)\B/g,(_,a)=>a+("s"[+/^(1|one|an?)\b/i.test(a)]||""))

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

78 바이트 버전 (강하지 않음)

s=s.replace(/(\S+ +(\S*))\(s\)/g,(_,a)=>a+("s"[+/^(1|one|an?)/i.test(a)]||""))

이것은 ETHproductions의 수정 된 버전입니다. '(50 명의 담당자는 없습니다.)

설명

  • /(\S+ +(\S+))\(s\)/g-찾을 실제 패턴 ( amount object(s))
  • (_,a)=>a- _모든 변수를 포착합니다 a.(\S+ +(\S+))
  • "s"[+/^(1|one|an?)/i.test(a)]||"" -배열을 자르는 대신 더미 배열을 만들고 색인을 얻으십시오 (+/.../.test 숫자를 반환)
    • "s"[+/^(1|one|an?)/i.test(a)]반환 해야합니다 undefined( true또는 1테스트 용).""
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.