스 와이프 패턴이 합법적입니까?


154

대부분의 Android 스마트 폰에서는 사용자가 스 와이프 패턴을 사용하여 휴대 전화를 열 수 있습니다.

패턴 잠금

어떤 패턴은 합법적이며 다른 패턴은 불가능합니다. 입력 스 와이프 패턴이 주어지면 주어진 입력 패턴이 합법적인지 아닌지를 나타내는 진실하거나 거짓을 반환하십시오.

입력

그리드는 1에서 9까지 행 방향으로 레이블이 지정됩니다.

1 2 3   
4 5 6   
7 8 9

입력은 처음부터 마지막으로 방문한 노드로 구성된 숫자입니다. 예를 들어 위의 스 와이프 패턴은 12357입니다.

입력은 10 진수, 문자열 또는 숫자 목록이 될 수 있습니다. 노드 0이 없으므로 0을 포함하지 않습니다.

수정 : 많은 언어가 0부터 색인되기 때문에 색인 0-8이 허용됩니다. 0-8을 사용하는 경우 답변 시작 부분에 해당 내용을 표시하고 그에 따라 테스트 사례를 조정해야합니다.

규칙

  • 모든 노드는 처음에 방문하지 않은 것으로 시작하며 한 번만 방문 할 수 있습니다. 노드를 두 번 이상 방문하는 패턴은 허위입니다.

  • 진지한 패턴에는 스 와이프가 하나 이상 있어야하므로 최소 2 개의 노드가 있습니다.

  • 방문하지 않은 노드를 다른 노드와 직접 연계하여 건너 뛸 수는 없습니다. 예를 들어, 2는 방문하지 않고 직접 연결되어 있기 때문에 13은 거짓입니다.

  • 방문한 노드 만 건너 뛸 수 있습니다. 42631이 이에 대한 예입니다.

  • 그렇지 않으면 선이 교차 할 수 있습니다. 예를 들어 1524는 진실입니다.

  • 노드 너비가 중요하지 않으며 실제 문제 (손가락 두께 등)를 무시한다고 가정합니다. 16은 현실적으로 달성하기가 다소 어려울지라도 진실입니다.

테스트 사례

1 -> false     
12 -> true   
13 -> false   
16 -> true  
31 -> false   
33 -> false  
137 -> false   
582 -> true  
519 -> true  
1541 -> false  
12357 -> true    
15782 -> true   
19735 -> false  
42631 -> true   
157842 -> true  
167294385 -> true   
297381645 -> false   
294381675 -> true

이것은 이므로 가장 적은 수의 바이트가 이깁니다.




입력 목록이 비어 있지 않습니까?
Zgarb

@Zgarb 예. 비어 있지 않습니다.
stanri 2019

답변:


69

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

숫자 배열로 입력을받습니다. 거짓 값은 0 또는 NaN 입니다. 진실 값은 엄격하게 양의 정수입니다.

a=>a[p=1]*a.every(n=>a[p=a[n&p&p*n%5<0|~(p-=n)==9&&p/2]&&-n]^=p)

테스트 사례

어떻게?

전문

다음과 같은 경우 두 자리 숫자가 수직, 수평 또는 대각선으로 반대됩니다.

  • 그들은 이상하고 서로 다르며 5와 다릅니다 (그림 1)
  • 또는 둘 다 짝수이고 합계가 10입니다 (그림 2).

    반대 자리

또한, 두 대립 숫자 np 사이에 서있는 숫자 는 (n + p) / 2와 같습니다 .

형식화 된 소스 코드

a =>
  // force a falsy result if a[1] is undefined
  a[p = 1] *
  // walk through all values n in a[]
  a.every(n =>
    // access either a[-n] or a[undefined]
    a[
      // set p to either -n or undefined
      p =
        // read either a[0] or a[in_between_digit]
        a[
          n & p & p * n % 5 < 0 | ~(p -= n) == 9
          && p / 2
        ]
        && -n
    ]
    // toggle the flag
    ^= p
  )

이전 자릿수 추적

방문 숫자에 대한 플래그는 입력 배열 a 의 음수 인덱스에 저장 되므로 원래 요소와 충돌하지 않습니다.

  • p-n 으로 설정된 경우 :

    현재 숫자 n 이 이전에 선택되지 않은 a[-n] ^= -n경우 플래그를 설정 every()하고 다음 반복으로 루프를 진행시킵니다. 그렇지 않으면 플래그를 지우고 루프가 즉시 실패하게됩니다.

  • pundefined 로 설정된 경우 :

    a[undefined] ^= undefined결과는 0 이며, 이로 인해 루프가 실패합니다.

반대 자릿수 감지

프리앰블에 정의 된대로 현재 숫자 n 과 이전 숫자 -p 가 반대 숫자 인지 여부를 테스트하는 데 다음 표현식이 사용됩니다 .

n & p & ((p * n) % 5 < 0) | ~(p -= n) == 9

이는 다음과 같습니다.

n & p & ((p * n) % 5 < 0) | (p -= n) == -10

참고 : JS에서 모듈로의 결과는 피제수와 같은 부호를 갖습니다.

다음과 같이 해석 될 수 있습니다.

(n is odd AND -p is odd AND (neither -p or n is equal to 5)) OR (n + -p = 10)

따라서이 표현식은 n-p 가 반대 자리 이거나 동일한 홀수 자리 인 경우에만 1을 반환합니다 . 숫자를 두 번 선택할 수 없기 때문에이 후자의 경우 올바르게 처리됩니다.

이 표현식이 1을 반환 하면 '자릿수'가 이전에 방문되었는지 여부를 알기 위해 a [p / 2] (여기서 p 는 이제 숫자의 부정 합계와 동일 함)를 테스트 합니다 . 그렇지 않으면, 우리는 a [0] 을 테스트 합니다 .

첫 번째 반복에 대하여

첫 번째 반복은 이전 숫자가 없으며 무조건 성공하기를 원한다는 점에서 특별한 경우입니다.

[1 .. 9]의 n 에 대해 p1 로 초기화하면됩니다 .

  • (1 * n) % 5 부정적 일 수 없다
  • ~(1 - n) 9와 같을 수 없습니다

원래 답변, 90 바이트

너무 자세하게 표시되지 않도록이 게시물에서 삭제되었습니다. 당신은 할 수 여기를 참조하십시오 .


대체함으로써 -1 바이트 !!a[1]&a[1]&&임의 truthy 보낸 값이 반환 될 수있다
허만 L를

@HermanLauenstein 감사합니다. (이제 a[1]*더 짧습니다.)
Arnauld

1
나는 필사적으로 공식을 생각하려고 has a node directly in line했지만, 그것이 그렇게 단순하다는 것을 몰랐다 ...
Neil

@Neil이 포스트의 개정 이력을 보면, 나는 즉시 그 사실을 깨닫지 못했다고 말할 수 있다고 확신합니다 ... :)
Arnauld

당신이 대체 할 수있는 생각 ?a[-n]^=1:0&&a[-n]^=1-1에, (모바일) 테스트 할 수 없습니다
스탠 스트 럼에게

45

x86 32 비트 머신 코드, 62 60 바이트

16 진 덤프 :

33 c0 60 8b f2 33 db 99 80 f9 02 72 2d ad 50 0f
ab c2 72 25 3b c3 77 01 93 2b c3 d1 e8 72 14 68
92 08 0e 02 0f a3 5c 04 ff 5f 73 07 03 d8 0f a3
da 73 06 5b e2 d7 61 40 c3 58 61 c3

목록의 길이 ecx와의 첫 번째 요소에 대한 포인터를 수신하고 edx결과를 al다음 과 같이 반환합니다 .

__declspec(naked) bool __fastcall check(int length, const int* list)

중간에 노드를 포함하는 8 개의 라인이 있습니다.

1-3
4-6
7-9
1-7
2 ~ 8
3-9
1-9
3-7

더 큰 숫자와 작은 숫자의 차이에 따라 그룹화했습니다.

차이 2 : 3 줄 (1, 4 또는 7에서 시작)
    1-3
    4-6
    7-9
차이 4 : 1 라인 (3에서 시작)
    3-7
차이 6 : 3 줄 (1, 2 또는 3에서 시작)
    1-7
    2 ~ 8
    3-9
차이 8 : 1 행 (1에서 시작)
    1-9

그런 다음 반차 및 더 작은 수로 색인을 생성 한 2 차원 조회 테이블로 변환했습니다.

76543210
--------
10010010 - half-difference 1
00001000 - half-difference 2
00001110 - half-difference 3
00000010 - half-difference 4

이것은 32 비트의 "매직"비트 맵을 만듭니다. 코드를 인덱싱하기 위해 코드는이를 스택으로 푸시합니다. 그런 다음 하나의 인덱스를 사용하여 한 바이트를 추출하고 해당 바이트에서 다른 인덱스를 사용하여 한 비트를 추출합니다. 이 모든 것은 하나의 명령을 사용합니다.

bt byte ptr [esp + eax - 1], ebx; // -1 because half-difference is 1-based

비트 맵이 중간에 노드가 있음을 나타내면 계산하기 쉽습니다. 작은 숫자에 절반의 차이를 더하십시오.

조립 소스 :

    xor eax, eax;   // prepare to return false
    pushad;         // save all registers
    mov esi, edx;   // esi = pointer to input list
    xor ebx, ebx;   // ebx = previously encountered number = 0
    cdq;            // edx = bitmap of visited numbers = 0

    cmp cl, 2;      // is input list too short?
    jb bad_no_pop;  // bad!

again:
    lodsd;          // read one number
    push eax;

    bts edx, eax;   // check and update the bitmap
    jc bad;         // same number twice? - bad!

    cmp eax, ebx;   // sort two recent numbers (ebx = minimum)
    ja skip1;
    xchg eax, ebx;
skip1:

    // Check whether the line crosses a node
    sub eax, ebx;   // calculate half the difference
    shr eax, 1;
    jc skip_cross;  // odd difference? - no node in the middle

    push 0x020e0892;// push magic bitmap onto stack
    bt byte ptr [esp + eax - 1], ebx; // is there a node in the middle?
    pop edi;
    jnc skip_cross; // no - skip the check

    add ebx, eax;   // calculate the node in the middle
    bt edx, ebx;    // was it visited?
    jnc bad;        // no - bad!

skip_cross:
    pop ebx;
    loop again;

    // The loop was finished normally - return true
    popad;          // restore registers
    inc eax;        // change 0 to 1
    ret;            // return

    // Return false
bad:
    pop eax;        // discard data on stack
bad_no_pop:
    popad;          // restore registers
    ret;            // return

좋은! 나는 이것을 정말로 좋아한다 bt byte ptr [esp + eax], ebx.
Arnauld

5
당신은 사용할 수 있습니다 : 조립 솔루션 볼 니스 cdq대신 xor edx, edx으로 eax제로입니다. 또한, 당신은 접을 수 dec eaxbt [esp + eax - 1], ebx같은 길이 인 그러나 당신이를 제거 할 수 있습니다 inc ebx이상. 이렇게하면 2 바이트가 절약됩니다.
Jester

아이디어 주셔서 감사합니다! 하나 :이 경우, 골퍼의 낙원에 당신의 장소를 확보 한
anatolyg

5
골퍼 파라다이스가 다른 사람들에게는 지옥이라는 데 모두 동의 할 수 있습니다.
Adonalsium

19

파이썬 (2) , 140 (131) 114 (104) 99 바이트

Jonathan Frech 덕분에 -2 바이트 Chas Brown
덕분에 -5 바이트

v={0};k=input()
for l,n in zip(k,k[1:])or q:(2**n+~2**l)%21%15%9==5<v-{l+n>>1}==v>q;v|={l};n in v>q

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

설명:

# full program, raising a NameError for invalid input
v={0}            # set of visited nodes
k=input()        # load pattern
# iterate through adjacent pairs, if there is no pair, raise a NameError
for l,n in zip(k,k[1:])or q:
  # detect moves skipping over nodes, details below
  (2**n + ~2**l) % 21 % 15 % 9 == 5 < v - {l+n >> 1} == v > q
  v |= {l}       # add the last node to the set of visited nodes
  n in v > q     # if the current node was previously visited, raise a NameError

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

8 쌍의 노드 만이 그들 사이에 노드를 가지고 있습니다. 노드 쌍은 공식으로 단일 정수로 표시 될 수 있습니다 2^a-2^b-1. 이 수는 반복 된 모듈로로 단축 될 수 있습니다.

a  b  2^a-2^b-1  (2^a-2^b-1)%21%15%9
1  3         -7                    5
1  7       -127                    5
1  9       -511                    5
2  8       -253                    5
3  1          5                    5
3  7       -121                    5
3  9       -505                    5
4  6        -49                    5
6  4         47                    5
7  1        125                    5
7  3        119                    5
7  9       -385                    5
8  2        251                    5
9  1        509                    5
9  3        503                    5
9  7        383                    5

(2**n+~2**l)%21%15%9==5먼저 해당 쌍이 존재 v-{l+n>>1}==v하는지 확인한 다음로 지정된 노드 사이에 (a+b)/2아직 방문하지 않았는지 확인 q하고 NameError를 발생시킵니다. 이러한 쌍 사이에 체인 비교를 사용하면 이전 비교가 반환 될 때만 다음 비교가 실행됩니다 True.


17

젤리 ,  24 22 19  18 바이트

-2 더 이상 빈 목록을 처리 할 필요가 없기 때문에
-1 j@을 연결에서 연결로 전환 ;합니다. 누락 된 항목은 사용 된 방법에 대해 중간에 발생 하지 않아도 됩니다. )
-2로 전환 P¬aSH하는 oSH우리 평탄화 이후 (OK하면 절반 두 결과가 없습니다 1이다 0.5) 어쨌든 필터링되는, 복수의 동일한 결과를 갖는 더 중 사용 된 방법에 영향을 미치지
-1 씨 Xcoder 덕분 (0 인덱스 입력 가능)

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼

합법적 인 경우 정수 목록을 가져 와서 [0,8]진실한 값 ( 1)을 반환하고 그렇지 않은 경우 거짓 값 ( )을 반환하는 모나드 링크 0.

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

어떻게?

입력 목록에서 인접한 0 개의 인덱스 노드 쌍을 살펴 봅니다. 2 개 중 3 개의 정수 나누기가 2 씩 다르면 상단과 하단 행에 있고, 2 개 중 3 개에 의한 모듈로가 2 씩 다르면 왼쪽 및 오른쪽 열에 있습니다. 이러한 쌍의 합을 2로 나눈 값은 3 노드 라인의 0 인덱스 중간 노드이거나 정수가 아닌 값이므로 먼저 0 인덱스 쌍 앞에 삽입 된 다음 가짜 노드 ( 0.5또는3.5)가 제거되고 결과 목록 목록이 평평해진 다음 중복 제거되어 (주문 유지, 고유 항목을 생성하기 위해) 입력과 비교됩니다. 법적으로 스 와이프하는 경우이 모든 것이 불법이 아닌 결과가됩니다 누락 된 중간 노드를 추가하거나 중복 노드를 제거합니다 (인접 쌍이 없기 때문에 길이가 1 인 입력 목록에는 특별한 케이싱이 필요하지 않습니다).

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼ - left input is a list of integers   e.g. [3,4,7,1,2,8,3]
          µƝ       - perform the chain to the left for adjacent pairs:
                   - e.g. for [a,b] in:   [3,4]         [4,7]         [7,1]         [1,2]         [2,8]         [8,3]
 d3                -   divmod by 3        [[1,0],[1,1]] [[1,1],[2,1]] [[2,1],[0,1]] [[0,1],[0,2]] [[0,2],[2,2]] [[2,2],[1,0]]
   Z               -   transpose          [[1,1],[0,1]] [[1,2],[1,1]] [[2,0],[1,1]] [[0,0],[1,2]] [[0,2],[2,2]] [[2,1],[2,0]]
    I              -   differences        [0,1]         [1,0]         [-2,0]        [0,1]         [2,0]         [-1,-2]
     Ị             -   abs(v)<=1          [1,1]         [1,1]         [0,1]         [1,1]         [0,1]         [1,0]
       S           -   sum (of [a,b])      7            11            8              3            10            11
      o            -   OR (vectorises)    [1,1]         [1,1]         [8,1]         [1,1]         [10,1]        [1,11]
        H          -   halve (vectorises) [0.5,0.5]     [0.5,0.5]     [4,0.5]       [0.5,0.5]     [5,0.5]       [0.5,5.5]
         ;         -   concatenate        [0.5,0.5,3,4] [0.5,0.5,4,7] [4,0.5,7,1]   [0.5,0.5,1,2] [5,0.5,2,8]   [0.5,5.5,8,3]
            F      - flatten              [0.5,0.5,3,4,  0.5,0.5,4,7,  4,0.5,7,1,    0.5,0.5,1,2,  5,0.5,2,8,    0.5,5.5,8,3]
                ¤  - nilad followed by link(s) as a nilad:
              9    -   literal nine
               Ḷ   -   lowered range = [0,1,2,3,4,5,6,7,8]
             f     - filter keep          [        3,4,          4,7,  4,    7,1,            1,2,  5,    2,8,         ,8,3]
                 Q  - deduplicate          [3,4,7,1,2,5,8]
                  ⁼ - equal to the input?  e.g. 0 (here because 5 was introduced AND because 3 was removed from the right)

이전 방법

젤리 ,  36  35 바이트

9s3;Z$;“Æ7a‘DZ¤;U$;©0m€2iị®oµƝFQ⁼ȧȦ

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

어떻게?

위와 유사하지만 모든 3 노드 라인 가능성을 구성하고 조회를 수행합니다 (중간 노드의 합계를 테스트하고 절반으로 줄이기 위해 divmod를 사용하는지 확인하는 대신).

먼저 3 노드 라인 목록 구성 :

9s3;Z$;“Æ7a‘DZ¤;U$;©0
9s3                   - nine (implicit range) split into threes = [[1,2,3],[4,5,6],[7,8,9]]
     $                - last two links as a monad:
    Z                 -   transpose = [[1,4,7],[2,5,8],[6,7,9]]
   ;                  -   concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9]]
              ¤       - nilad followed by link(s) as a nilad:
       “Æ7a‘          -   code-page index list = [13,55,97]
            D         -   decimal (vectorises) = [[1,3],[5,5],[9,7]]
             Z        -   transpose = [[1,5,9],[3,5,7]]
      ;               - concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]]
                 $    - last two links as a monad:
                U     -   upend = [[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3]]
               ;      -   concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3]]
                    0 - literal zero (to cater for non-matches in the main link since ị, index into, is 1-based and modular the 0th index is the rightmost)
                  ;   - concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
                   ©  - copy the result to the register

이제 의사 결정 :

...m€2iị®oµƝFQ⁼ȧȦ - left input is a list of integers               e.g. [4,5,8,2,3,9,4]
          µƝ      - perform the chain to the left for adjacent pairs:
                  - i.e. for [a,b] in [[4,5],[5,8],[8,2],[2,3],[3,9],[9,4]]
...               -   perform the code described above = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
   m€2            -   modulo-2 slice €ach = [[1,3],[4,6],[3,9],[1,7],[2,8],[6,9],[1,9],[3,7],[3,1],[6,4],[9,7],[7,1],[8,2],[9,3],[9,1],[7,3],[0]]
      i           -   index of [a,b] in that (or 0 if not there)    e.g. [0,0,13,0,6,0]
        ®         -   recall from register = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
       ị          -   index into (1-based & modular)     e.g. [0,0,[8,5,2],0,[3,6,9],0]
         o        -   OR [a,b]           e.g. [[4,5],[5,8],[8,5,2],[2,3],[3,6,9],[9,4]]
            F     - flatten                          e.g. [4,5,5,8,8,5,2,2,3,3,6,9,9,4]
             Q    - deduplicate                                    e.g. [4,5,8,2,3,6,9]
              ⁼   - equal to the input?                            e.g. 0 (here because 6 was introduced AND because 4 was removed from the right)
                Ȧ - any and all? (0 if input is empty [or contains a falsey value when flattened - no such input], 1 otherwise)
               ȧ  - AND (to force an empty input to evaluate as 1 AND 0 = 0)

많은 유니 코드 문자가있을 때 어떻게 19 바이트로 나옵니까?
이즈 카타

@Izkata Jelly는 자체 코드 페이지를 사용하며 헤더에서 "바이트"를 클릭하면 볼 수 있습니다. 원시 바이트 형식에서 소스 코드에서 볼 수있는 각 유니 코드 문자는 단일 바이트입니다.
Jonathan Allan

15

Stax , 28 바이트

æ¡_t¿♂≥7▼├öä▒╨½╧£x╪╨┌i╒ë╖¢g•

그것을 실행

false 인 경우 0을, true 인 경우 양의 정수를 생성합니다. 동일한 프로그램의 해당 ASCII 표현은 이렇습니다.

cu=x%v*x2BF1379E-%_|+YA=!*yhxi(#+*

일반적인 아이디어는 법적 스 와이프 패턴에 필요한 몇 가지 조건을 계산하고 모두 곱하는 것입니다.

cu=                                 First: no duplicates
   x%v*                             Second: length of input minus 1
       x2B                          Get all adjacent pairs  
          F                         For each pair, execute the rest
           1379E-%                  a) Any digits that are not 1, 3, 7, 9?
                  _|+Y              Get sum of pair, and store in Y register
                      A=!           b) Sum is not equal to 10?
                         *          c) multiply; logical and: a, b
                          yh        half of y; this will be equal to the
                                        number directly between the current
                                        pair if there is one
                            xi(#    d) has the middle number been observed yet?
                                +   e) plus; logical or: c, d
                                 *  multiply by the accumulated value so far

Y레지스터를 영리하게 사용합니다 .
Weijun Zhou

github의 또 다른 문제.
Weijun Zhou

1
우연히도 그 버그를 이미 수정했지만 지금까지는 배포하지 않았습니다. (내 프로그램에는 영향을 미치지 않습니다)
재귀 적

1
이상하게 들릴지 모르지만 첫 번째 값을 버리고 잘못된 값으로 v포함 시킬 수 있습니다 1. 2이상은 진실합니다.
Weijun Zhou

10

자바 스크립트, 112 바이트

x=>/^(?!.*(.).*\1|[^5]*(19|28|37|46|91|82|73|64)|[^2]*(13|31)|[^8]*(79|97)|[^4]*(17|71)|[^6]*(39|93))../.test(x)

정규 표현식 기반의 언어가 더 짧을 수도 있습니다. 그러나 나는 모른다.

Neil 덕분에 3 바이트 )(?!|절약 하도록 변경하십시오 .


@WeijunZhou 나는 213에 대해 사실을 알았습니다. 무엇이 잘못 되었나요?
tsh

문제가 없습니다. 죄송합니다.
Weijun Zhou

이제 OP가 명확 해 졌으므로에 실패했습니다 144.
Weijun Zhou

1
@WeijunZhou는 수정해야합니다; 2 바이트 더 ...
tsh

궁금한 점이 있다면 Retina 0.8.2 포트는 98 바이트에서 작동하는 것 같습니다.
Neil


6

껍질 , 25 20 바이트

S=öufΛ¦1ΣẊ§Jzo½+em‰3

0부터 시작하는 색인이있는 정수 목록을 가져옵니다. 0 또는 1을 반환 합니다. 온라인으로 사용해보십시오!

설명

Jonathan Allan의 Jelly 답변 에서 아이디어를 훔쳤습니다 . 아이디어는 동일합니다. 인접한 각 쌍 사이에 새 "평균 노드"를 삽입하고 실제 노드가 아닌 노드를 필터링하고 중복을 제거하고 원래 목록과 비교하십시오. 원본 목록에 중복 항목이 포함되어 있으면 결과가 잘못됩니다. 목록이 방문하지 않은 노드를 건너 뛰면 해당 쌍 사이의 처리 된 목록에 존재하며 결과는 거짓입니다. 입력이 싱글 톤 인 경우 처리 된 목록이 비어 있고 결과가 잘못되었습니다. 그렇지 않으면 진실입니다.

S=öufΛ¦1ΣẊ§Jzo½+em‰3  Implicit input, say [0,4,6,7,1]
                 m‰3  Divmod each by 3: L = [[0,0],[1,1],[2,0],[2,1],[0,1]]
         Ẋ§Jzo½+e     This part inserts the middle node between adjacent nodes.
         Ẋ            Do this for each adjacent pair, e.g. [1,1],[2,0]:
          §           Apply two functions and combine results with third.
            zo½+      First function:
            z         Zip with
               +      addition,
             o½       then halve: N = [3/2,1/2]
                e     Second function: pair: P = [[1,1],[2,0]]
           J          Combining function: join P with N: [[1,1],[3/2,1/2],[2,0]]
                      Result is a list of such triples.
        Σ             Concatenate: [[0,0],[1/2,1/2],[1,1],[1,1],[3/2,1/2],...,[0,1]]
    f                 Keep only those pairs
     Λ                both of whose elements
      ¦1              are divisible by 1, i.e. are integers: [[0,0],[1,1],[1,1],,...,[0,1]]
   u                  Remove duplicates: [[0,0],[1,1],[2,0],[2,1],[0,1]]
S=ö                   Is the result equal to L? Implicitly print 1 or 0.

3

C ++, 267256 바이트

#define R)return 0
#define H(a,q)if(d==q&&n==a&&!m[a]R;
int v(int s[],int l){if(l<2 R;int m[10]{},i=1,p=s[0],d,n;for(;i<l;++i){m[p]=1;if(m[s[i]]R;d=(d=p-s[i])<0?-d:d;if(d%2<1){n=(p+s[i])/2;H(5,4)H(5,8)H(2,2)H(5,2)H(8,2)H(4,6)H(5,6)H(6,6)}p=s[i];}return 1;}

패턴이 방문하지 않은 노드를 건너 뛰지 않는지 확인하기 위해 몇 가지 작업을 수행합니다.

  1. 현재 노드와 마지막 노드 사이의 숫자 차이가 d어디에 있는지 계산 d하십시오.
  2. 경우 d홀수, 다음 검사 할 필요가 없습니다, 그것은 노드를 건너 뛸 수 없습니다.
  3. 경우 d와 동일 4또는 8다음 점프 노드 사이에 1-9또는 3-7, 그래서 노드를 확인5
  4. 경우 d2이고, 중간 노드 ( (last_node + current_node)/2) 중 2,5- 또는 8이고, 그 중간 노드 확인
  5. 경우 d6이고, 같은 이전하지만, 확인 4, 5또는6

매개 변수는 int[]요소 개수입니다. 유형 int으로 해석 될 수있는를 반환합니다.bool


!(d%2)=> d%2<1작동합니다.
Zacharý


나는 새로운 트릭을 배웠다 : int s[]=> int*s. 나는 그것이 효과가 있다고 생각합니다.
Zacharý

2

Perl, 135 바이트 (134+ -n)

@a{split//}=1;(@{[/./g]}==keys%a&&/../)||die();for$c(qw/132 465 798 174 285 396 195 375/){$c=~/(.)(.)(.)/;/^[^$3]*($1$2|$2$1)/&&die()}

약간 ungolfed 버전

@a{split//} = 1;
(@{[/./g]} == keys %a && /../) || die();
for $c (qw/132 465 798 174 285 396 195 375/) {
  $c=~/(.)(.)(.)/;
  /^[^$3]*($1$2|$2$1)/&&die()
}

종료 코드를 통해 출력합니다. 0진실하고 다른 가치는 허위입니다. 당으로 메타 합의 , 실패의 경우에 STDERR 출력은 무시됩니다.

단순히 모든 가능성을 나열하는 것보다 "이동할 수 없음"규칙을 확인하는 더 빠른 방법이있을 것입니다.


2

MATL , 42 41 39 바이트

9:IeXKi"Ky@=&fJ*+XK+y&fJ*+Em~zw0@(]z8<v

이것은 생산

  • 0이 아닌 숫자 만 사실 출력으로 포함하는 비어 있지 않은 열 벡터 ; 또는
  • 적어도 0 을 거짓으로 포함하는 비어 있지 않은 열 벡터

여기서 이러한 출력이 각각 진실하고 허위 인 이유를 읽을 수 있습니다. 온라인으로 사용해보십시오!

또는 진실성 / 거짓성에 대한 표준 테스트 가 포함 된 바닥 글 코드를 사용하여 모든 테스트 사례를 확인하십시오 .


2

Stax , 73 72 66 65 바이트 CP437

ÉWyƒ▬ºJOTƒw-H┌↓&ⁿç↨¼<ü6π║¢S○j⌂zXΣE7≈╩╕╤ö±÷C6▒☼■iP-↑⌐¥]╩q|+zΦ4Φ·¥Ω

압축을 풀면 79 바이트

d4{cAs-5F132396978714EEL3/{xs:IBc0<A*++cEd:-1=sccHs|M=s{U>m|A**mEx%2<xu%x%=!L|+

온라인으로 실행하고 디버그하십시오!

또는 실행 일괄 시험 , meXSTAX는 여러 입력을 처리 할 수 있도록 헤더이다.

해시를 사용하지 않는 구현 허위 사례 및 실제 사례에 대해 엄격하게 양수 (실제로 테스트 실패 횟수) 0출력 합니다.

설명

d입력 스택을 지 웁니다. 입력은 x어쨌든 변수 입니다.

4{cAs-5F 중간 노드 목록의 첫 부분을 생성합니다.

132396978714EE 중간 노드 목록의 두 번째 부분을 하드 코드합니다.

L3/기본 스택의 모든 요소를 ​​수집하고 각각 3 개의 요소를 포함하는 부분으로 나눕니다. 결과는 array a이며 이는 유효하지 않은 모든 3 노드 그룹의 배열입니다.

{xs:IBc0<A*++cEd:-1=sccHs|M=s{U>m|A**mE유효하지 않은 각 노드 목록에 대해 다음 점검을 수행하십시오. 확인 결과는을 and사용하여 수행 **됩니다. 8 개의 유효하지 않은 노드 목록이 있으므로이 코드의 결과는 8 개의 요소로 구성된 배열입니다. 마지막 E은 배열을 기본 스택의 개별 요소로 디스패치합니다.

xs:I 입력 배열에서 노드 목록 요소의 색인을 가져옵니다.

Bc0<A*++"중간 노드"(예 : 5노드 세트 1,5,9) -1의 색인이 (입력 배열에 존재하지 않음) 인 경우 색인을로 변경하십시오 9.

cEd:-1=두 "터미널 노드"(예 : 1,5노드 세트 1,5,9)가 입력 배열에 인접 해 있는지 테스트합니다 .

sccHs|M= "중간 노드"의 변환 된 인덱스가 두 "터미널 노드"의 인덱스보다 큰지 테스트합니다. 여기에는 "중간 노드"가 누락되었거나 "중간 노드"가 두 "터미널 노드"뒤에 오는 경우가 포함됩니다.

s{U>m|A"끝 노드"의 두 인덱스가 모두 음수가 아닌지 테스트합니다. (즉, 둘 다 입력에 나타납니다).

두 가지 추가 테스트가 수행됩니다.

x%2< 입력 배열이 싱글 톤인지 테스트합니다.

xu%x%=! 두 번 방문한 노드인지 테스트합니다.

기본 스택에는 10 개의 테스트 결과가 있습니다 (각 유효하지 않은 노드 목록에 대해 하나씩 두 개의 추가 테스트).

L|+10 개의 요소를 수집하여 추가합니다. |a배열에 진실한 요소가 있는지 간단히 확인하는 데 사용될 수도 있습니다.

암시 적 출력.


2

자바, 375355 바이트

Zacharý 덕분에 -20 바이트

int v(int s[]){int[]m=new int[10];int i=1,p=s[0],d,n,l=s.length;if(l<2)return 0;for(;i<l;++i){m[p]=1;if(m[s[i]]!=0)return 0;d=(d=p-s[i])<0?-d:d;if(d%2==0){n=(p+s[i])/2;if((d==4||d==8)&&n==5&&m[5]==0)return 0;if(d==2&&(n==2&&m[2]==0||n==5&&m[5]==0||n==8&&m[8]==0))return 0;if(d==6&&(n==4&&m[4]==0||n==5&&m[5]==0||n==6&&m[6]==0))return 0;}p=s[i];}return 1;}

이것은 이 답변 의 포트이며 동일한 원리로 작동합니다.


우와 당신은 자바에서 답답합니다.
Zacharý

int v(int s[]){int[]m=new int[10];int i=1,p=s[0],d,n,l=s.length;if(l<2)return 0;for(;i<l;++i){m[p]=1;if(m[s[i]]!=0)return 0;d=(d=p-s[i])<0?-d:d;if(d%2==0){n=(p+s[i])/2;if((d==4||d==8)&&n==5&&m[5]==0)return 0;if((d==2)&&(n==2&&m[2]==0||n==5&&m[5]==0||n==8&&m[8]==0))return 0;if(d==6&&(n==4&&m[4]==0||n==5&&m[5]==0||n==6&&m[6]==0))return 0;}p=s[i];}return 1;}작동 (작업 순서)
Zacharý

당신은 (d==2)그냥로 바꿀 수 있습니다 d==2, 나는 전에 그것을 간과했습니다.
Zacharý

d%2==0=>d%2<1
Zacharý

0

Pyth , 33 바이트

q{@U9.nm+mc|g1aZksd2-MC.DR3d_dC,t

테스트 스위트.

0 기반 인덱싱을 사용합니다.

설명

q {@ U9.nm + mc | g1aZksd2-MC.DR3d_dC, t –> 전체 프로그램. 입력 : STDIN의 목록 L.

                               , t –> 첫 번째 요소없이 L과 L을 쌍으로합니다.
                              C –> 조옮김.
       m –> 쌍 목록 (2 요소 목록)에 맵핑하십시오.
        + mc | g1aZksd2-MC.DR3d –> 매핑 할 함수 (변수 : d) :
                         R d –> d의 각 요소에 대해 ...
                       .D 3 –> ... divmod를 3 씩 가져옵니다.
                      C –> 전치.
                    -M –> 빼기로 각각을 줄입니다.
         m –> 각 차이 (변수 : k) :
            g1aZl –> Is | k | ≤ 1?
           | sd –> 이것이 잘못된 경우 d의 합으로 바꿉니다.
          c 2 –> 2로 나눕니다.
        + _d –> 매핑 결과에 d의 역을 추가합니다.
     .n –> 평평하게하기.
  @ U9 –> (ℤ ∩ [0; 9))와 교차합니다.
 {–> 중복 제거.
q –> 그리고 결과가 L인지 확인하십시오.

34 바이트에 대한 대체 접근법 :

q{sI#I#+Fm+,hdcR2+MCd]edCtBK.DR3QK

0

apt , 35 바이트

eUä@[(Xu3 aYu3)¥1ªX+Y ÷2XY]Ãc f9o)â

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

약간 골퍼되지 않음 및 작동 방식

eUä@[(Xu3 aYu3)¥1ªX+Y ÷2XY]Ãc f9o)â

Implicit beginning U(input) and some arbitrary sequence conversions

UeUä@[(Xu3 aYu3)==1||X+Y ÷2XY]} c f9o)â

  Uä             Convert the input array into length-2 subsections and map...
    @[ ... ]}      function of X,Y which returns an array of...
      Xu3 aYu3==1||X+Y ÷2          (abs(X%3 - Y%3)==1||X+Y)/2,
                         XY        X, Y
  c              Flatten the result of mapping
    f9o          Intersect with range(9)
        â        Take unique elements, preserving order
Ue             Is the result the same as original array?

이 Jelly 솔루션 의 아이디어를 포팅하여 잠재적 점프를 결정하는 데 약간의 차이가 있습니다.

  • Jelly 답변은 divmod를 사용하여 적용시 /3또는 쌍에 2의 차이가 있는지 확인합니다 %3.
  • 이 대답은 단지 사용 %3하고 차이가 0 또는 2인지 확인합니다. 차이가 0이면 두 셀이 세로로 정렬되며 비 점프는 여전히의 속성을 공유합니다 (X+Y)%2 != 0.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.