무한대 단어를 찾아라! 모두 소문자로

(참고 : 이것은 이전 도전 과제의 분사입니다 . 소용돌이 치는 단어를 찾으십시오! )

무한대 단어의 정의 :

  1. 알파벳 (AZ)에서 무한대 단어 의 모든 문자를 곡선으로 연결 하면 아래 다이어그램과 같이 무한대 기호 ∞가 표시됩니다.
  2. 모든 짝수 연결이 작동 중지 되어야 하고 모든 홀수 연결이 작동해야 합니다 .
  3. 대문자 / 소문자를 무시하거나 모두 대문자 또는 모두 소문자로 간주 / 변환 할 수 있습니다.
  4. 입력 단어는 AZ의 알파벳 범위에있는 문자, 공백, 문장 부호 또는 기호가 아닙니다.
  5. 각 단어는 정확히 5 자 여야합니다. > 5 또는 <5 단어는 유효하지 않습니다.
  6. 단어에 연속 된 두 문자가 있으면 “FLOOD”또는 “QUEEN”과 같이 해당 단어가 유효하지 않습니다.
  7. 모든 무한대 단어 는 같은 문자로 시작하고 끝납니다.

몇 가지 예가 있습니다 :

태스크:

표준 입력에서 단어를 가져 와서 무한대 단어 인지 여부를 출력하는 전체 프로그램 또는 함수를 작성하십시오 . 출력은 true / false, 1/0, 1 / Null 등이 될 수 있습니다.

테스트 사례 :

Infinity Words:
ALPHA, EAGLE, HARSH, NINON, PINUP, RULER, THEFT, WIDOW

NOT Infinity Words:
CUBIC, ERASE, FLUFF, LABEL, MODEM, RADAR, RIVER, SWISS, TRUST,
KNEES, QUEEN, GROOVE, ONLY, CHARACTER, OFF, IT, ORTHO

규칙 :

  1. 가장 짧은 코드가 승리합니다.

선택적 작업 :

영어 사전에서 가능한 한 많은 무한대 단어 를 목록으로 찾으십시오 . 당신은 참조로 예를 들면 영어 단어의 전체 목록을 취할 수 있습니다 여기에 .



답변

젤리 , 43 41 40 25 24 23 22 21 14 13 바이트

fireflame241 덕분에 -7 바이트 ( 0ị=1ị$-> =ṚḢIIA⁼2,24 회전 테스트에 사용 )

-1 Kevin Cruijssen 덕분에 (이전에 사용할 수 없었던 nilad Ø2를 사용하여 [2,2])

=ṚḢȧOIṠIIA⁼Ø2

TryItOnline
또는 모든 테스트 사례 (및 “RULES”)

어떻게?

무한 단어는 다음과 같습니다.

  1. 첫 글자와 마지막 글자;
  2. 길이 5;
  3. 서로 옆에 같은 글자가 없습니다.
  4. 4 개의 알파벳 델타의 합은 0과 같습니다.
  5. 4 개의 알파벳 델타 부호의 합은 0과 같습니다.
  6. 두 개의 양의 알파벳 델타 또는 두 개의 음의 알파벳 델타가 연속으로 나타납니다.

(1)과 (동등하게) (4)를 제외한 모든 문자는 알파벳 델타 부호가 [1,1,-1,-1](의 부호 00)

fireflame241은 이것이 알파벳 델타 부호의 델타 델타와 [[2,2],[2,-2],[-2,2],[-2,-2]]동일하며 절대 값이 같은 값으로 테스트 될 수 있음을 지적했다 [2,2].

어떻게?

=ṚḢȧOIṠIIA⁼Ø2 - Main link: word
 Ṛ            - reverse word
=             - equals? (vectorises)
  Ḣ           - head (is the first character equal to the last?)
   ȧ          - and
    O         - cast word to ordinals
     I        - increments - the alphabet deltas (or just [] if 1st != last)
      Ṡ       - sign (vectorises)
       I      - increments - deltas of those signs
        I     - increments - deltas of those
         A    - absolute value (vectorises)
           Ø2 - literal [2,2]
          ⁼   - equals? (non-vectorising version)

답변

자바 (8) 231 193 185 122 103 78 바이트

s->s.length==5&&(s[1]-s[0])*(s[3]-s[2])<0&(s[2]-s[1])*(s[4]-s[3])<0&s[4]==s[0]

여기에서 시도하십시오.

대신 사용하도록 상기시켜 준 @ dpa97 덕분에 -38 바이트 . @KarlNapf 의 파생 공식
덕분에 -63 바이트 .
-7 바이트를 Java 7에서 Java 8로 변환하여 정수 대신 부울을 리턴합니다.char[]String

193 바이트 답변 :

int c(char[]s){if(s.length!=5)return 0;int a=s[0],b=s[1],c=s[2],d=s[3],e=s[4],z=b-a,y=c-b,x=d-c,w=e-d;return e!=a?0:(z>0&y>0&x<0&w<0)|(z<0&y>0&x>0&w<0)|(z>0&y<0&x<0&w>0)|(z<0&y<0&x>0&w>0)?1:0;}

설명:

  • 문자열의 길이가 5가 아닌 경우 false
  • 첫 번째 문자가 마지막 문자와 같지 않으면 false
  • 그런 다음 유효한 4 가지 사례를 하나씩 확인하고 (5 개 문자를 1 ~ 5로 표시), true해당하는 경우 (또는 false그렇지 않은 경우)를 반환합니다.
    1. 다섯 개 문자를 같이 배포하는 경우 : 1<2<3>4>5(예 ALPHA)
    2. 다섯 개 문자를 같이 배포하는 경우 : 1>2<3<4>5(예 : EAGLE, HARSH, NINON, PINUP)
    3. 다섯 개 문자를 같이 배포하는 경우 : 1<2>3>4<5(예 RULER)
    4. 다섯 개 개의 문자가 같은 분산 경우 1>2>3<4<5(즉 THEFT, WIDOW)

이 네 가지 규칙을 단순화 할 수 있습니다 1*3<0 and 2*4<0( @KarlNapf 의 Python 2 answer 덕분에 ).


답변

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

Ismael Miguel 덕분에 2 바이트 절약

s=>(k=0,[...s].reduce((p,c,i)=>(k+=p>c?1<<i:0/(p<c),c)),k?!(k%3)&&!s[5]&&s[0]==s[4]:!1)

작동 원리

k문자열의 5 개 문자 사이에서 4 개의 전환을 나타내는 4 비트 비트 마스크를 만듭니다 .

k += p > c ? 1<<i : 0 / (p < c)
  • 이전 문자가 다음 문자보다 높으면 비트가 설정됩니다
  • 이전 문자가 다음 문자보다 낮 으면 비트가 설정되지 않습니다
  • 이전 문자가 다음 문자와 동일하면 전체 비트 마스크가 강제로 NaN단어가 거부됩니다 (규칙 # 6 준수).

유효한 비트 마스크는 정확히 두 개의 연속 1전환 이있는 마스크입니다 (첫 번째 및 마지막 비트도 연속적인 것으로 간주 됨 ).

Binary | Decimal
-------+--------
0011   | 3
0110   | 6
1100   | 12
1001   | 9

다시 말해 다음과 같은 조합입니다.

  • k? : 0보다 큼
  • !(k%3): 0 모듈로 3에 합치
  • 15 이하

다른 조건은 다음과 같습니다.

  • !s[5] : 5 자 이하 여야합니다
  • s[0]==s[4] : 첫 번째와 다섯 번째 문자가 동일

주의 : 우리는 k != 15그러한 패턴을 따르는 단어는이 마지막 조건에 의해 거부되기 때문에 명시 적으로 확인하지 않습니다 .

테스트 사례

let f =

s=>(k=0,[...s].reduce((p,c,i)=>(k+=p>c?1<<i:0/(p<c),c)),k?!(k%3)&&!s[5]&&s[0]==s[4]:!1)

console.log("Testing truthy words...");
console.log(f("ALPHA"));
console.log(f("EAGLE"));
console.log(f("HARSH"));
console.log(f("NINON"));
console.log(f("PINUP"));
console.log(f("RULER"));
console.log(f("THEFT"));
console.log(f("WIDOW"));

console.log("Testing falsy words...");
console.log(f("CUBIC"));
console.log(f("ERASE"));
console.log(f("FLUFF"));
console.log(f("LABEL"));
console.log(f("MODEM"));
console.log(f("RADAR"));
console.log(f("RIVER"));
console.log(f("SWISS"));
console.log(f("TRUST"));
console.log(f("KNEES"));
console.log(f("QUEEN"));
console.log(f("ORTHO"));
console.log(f("GROOVE"));
console.log(f("ONLY"));
console.log(f("CHARACTER"));
console.log(f("OFF"));
console.log(f("IT"));
console.log(f("ORTHO"));

초기 버전

레코드의 초기 버전은 63 바이트였습니다. 모든 테스트 사례를 성공적으로 통과했지만 연속적인 동일한 문자를 감지하지 못합니다.

([a,b,c,d,e,f])=>!f&&a==e&&!(((a>b)+2*(b>c)+4*(c>d)+8*(d>e))%3)

다음은 의견에서 Neil이 제안한 53 바이트 버전으로, 동일하게 작동하며 실패합니다.

([a,b,c,d,e,f])=>!f&&a==e&&!((a>b)-(b>c)+(c>d)-(d>e))

편집 : 위 코드의 수정 / 완료 버전은 Neil의 답변 을 참조하십시오 .


답변

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

([a,b,c,d,e,f])=>a==e&&!(f||/(.)\1/.test(a+b+c+d+e)||(a>b)-(b>c)+(c>d)-(d>e))

@Arnauld의 잘못된 코드를 기반으로하지만 골프를 치고 수정했습니다. 첫 번째 문자가 다섯 번째 문자와 동일하고 (5 자 보장) 문자열 길이가 5자를 넘지 않는지 먼저 확인하여 작동합니다. 연속적인 중복 문자를 확인한 후에는 문자열의 물결 모양을 확인합니다. 여기에는 1 개의 피크와 1 개의 2 개의 문자가 있어야합니다.

  • 피크와 최저점이 중간 및 첫 / 마지막 문자이면 처음 두 비교와 마지막 두 비교가 취소됩니다.
  • 최고점과 최저점이 두 번째와 네 번째 문자이면 중간 두 비교와 외부 두 비교는 취소됩니다.
  • 그렇지 않으면, 무언가가 취소되지 않고 전체 표현식이 false를 리턴합니다.

편집 : @ KarlNapf의 답변을 기반으로 한 대체 78 바이트 솔루션 :

([a,b,c,d,e,f],g=(a,b)=>(a<b)-(a>b))=>a==e&&!f&&g(a,b)*g(c,d)+g(b,c)*g(d,e)<-1

답변

Python 2 종료 코드, 56 바이트

s=input()
v,w,x,y,z=map(cmp,s,s[1:]+s[0])
v*x+w*y|z>-2>_

종료 코드를 통한 출력 : False의 오류, True의 성공적인 실행

문자열 s을 문자 abcde로 가져 와서로 회전하고 bcdea해당 문자를 요소별로 비교 한 다음 5 개의 변수에 지정합니다 v,w,x,y,z. 길이가 잘못되면 오류가 발생합니다.

무한 단어는 모두

v*x == -1
w*y == -1
z == 0

로 같이 확인할 수 있습니다 v*x+w*y|z == -2. 이 경우 체인 비교는 v*x+w*y|z>-2>_단락되고 그렇지 않으면 -2>_이름 오류가 발생하는 평가 를 계속합니다.


답변

파이썬 2, 110 87 60 바이트

Neil 덕분에 1 바이트 절약

따옴표로 묶은 입력이 필요합니다. 예 : 'KNEES'

True무한 단어 인 False경우 길이가 5이고 길이가 잘못된 경우 오류 메시지를 인쇄합니다.

s=input()
a,b,c,d,e=map(cmp,s,s[1:]+s[0])
print a*c+b*d|e<-1

xnor 의 답변을 사용하여 영감을 얻었습니다.map(cmp...

s=input()
e=map(cmp,s,s[1:]+s[0])
print e[4]==0and e[0]*e[2]+e[1]*e[3]==-2and 5==len(s)

이전 솔루션 :

s=input()
d=[ord(x)-ord(y)for x,y in zip(s,s[1:])]
print s[0]==s[4]and d[0]*d[2]<0and d[1]*d[3]<0and 4==len(d)

Kevin Cruijssen 의 최적화 된 로직 사용


답변

PHP, 102 바이트

for(;$i<strlen($w=$argv[1]);)$s.=($w[$i++]<=>$w[$i])+1;echo preg_match("#^(2200|0022|2002|0220)#",$s);