Mẫu Swipe của tôi có hợp pháp không?


154

Hầu hết các điện thoại thông minh Android cho phép người dùng sử dụng kiểu vuốt để mở điện thoại của họ:

khóa mẫu

Một số mô hình là hợp pháp, và những người khác là không thể. Đưa ra một mẫu vuốt đầu vào, trả về một giá trị trung thực hoặc sai lệch cho biết mẫu đầu vào đã cho có hợp pháp hay không.

Đầu vào

Lưới được dán nhãn theo hàng từ 1 đến 9:

1 2 3   
4 5 6   
7 8 9

Đầu vào là một số bao gồm các nút được truy cập từ đầu đến cuối. Ví dụ, mẫu vuốt ở trên là 12357.

Đầu vào có thể là một số thập phân, chuỗi hoặc danh sách các số. Nó sẽ không chứa 0 vì không có nút 0.

Sửa đổi: lập chỉ mục 0-8 được cho phép vì rất nhiều chỉ số ngôn ngữ từ 0. Nếu bạn sử dụng 0-8, sẽ cần phải chỉ ra như vậy khi bắt đầu câu trả lời của bạn và điều chỉnh các trường hợp kiểm tra cho phù hợp.

Quy tắc

  • Mỗi nút bắt đầu như không mong muốn ban đầu và chỉ có thể được truy cập một lần. Bất kỳ mẫu nào truy cập một nút nhiều lần là sai.

  • Một mẫu trung thực phải chứa ít nhất một lần vuốt, do đó tối thiểu là 2 nút.

  • Không thể bỏ qua một nút không mong muốn trực tiếp với một nút khác. Ví dụ: 13 là sai vì 2 là không mong muốn và trực tiếp trong dòng.

  • Chỉ có thể bỏ qua một nút truy cập. 42631 là một ví dụ về điều này.

  • Dòng có thể vượt qua khác. Ví dụ, 1524 là sự thật.

  • Giả sử độ rộng nút là không đáng kể và bỏ qua các vấn đề thực tế (độ dày ngón tay, v.v.). Vì vậy, 16 là sự thật mặc dù có thể khó đạt được một chút trong thực tế.

Các trường hợp thử nghiệm

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

Đây là , vì vậy số byte ít nhất sẽ thắng.




Là danh sách đầu vào được đảm bảo là không trống?
Zgarb

@Zgarb vâng. Nó sẽ không trống rỗng.
stanri

Câu hỏi toán học liên quan: math.stackexchange.com/questions/205049/
Pureferret

Câu trả lời:


69

JavaScript (ES6), 64 byte

Đưa đầu vào như một mảng số. Giá trị giả là 0 hoặc NaN . Giá trị thật là số nguyên dương.

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

Các trường hợp thử nghiệm

Làm sao?

Lời nói đầu

Hai chữ số được đặt theo chiều dọc, chiều ngang hoặc đường chéo nếu:

  • cả hai đều lẻ, khác nhau và khác với 5 (hình 1)
  • HOẶC cả hai đều chẵn và tổng của chúng là 10 (hình 2)

    chữ số trái ngược

Ngoài ra, chữ số đứng giữa hai chữ số đối lập np bằng (n + p) / 2 .

Mã nguồn được định dạng

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
  )

Theo dõi các chữ số trước

Cờ cho các chữ số được truy cập được lưu trữ tại các chỉ số âm trong mảng đầu vào a , để chúng không va chạm với các phần tử ban đầu của nó.

  • Nếu p được đặt thành -n :

    Nếu chữ số hiện tại n không được chọn trước đó, a[-n] ^= -nsẽ đặt cờ và để every()vòng lặp tiếp tục với lần lặp tiếp theo. Nếu không, nó sẽ xóa cờ và buộc vòng lặp thất bại ngay lập tức.

  • Nếu p được đặt thành không xác định :

    a[undefined] ^= undefinedkết quả là 0 , điều này cũng buộc vòng lặp thất bại.

Phát hiện các chữ số trái ngược

Biểu thức sau đây được sử dụng để kiểm tra xem chữ số hiện tại n và chữ số -p trước đó có phải là chữ số trái ngược nhau, như được định nghĩa trong phần mở đầu hay không:

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

tương đương với:

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

Lưu ý: Trong JS, kết quả của modulo có cùng dấu với cổ tức.

Nó có thể được hiểu là:

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

Do đó, biểu thức này trả về 1 khi và chỉ khi n-p là các chữ số đối lập hoặc chúng là cùng một chữ số lẻ. Bởi vì một chữ số không thể được chọn hai lần, trường hợp sau này được xử lý chính xác.

Nếu biểu thức này trả về 1 , chúng tôi sẽ kiểm tra [p / 2] (trong đó p bây giờ bằng tổng âm của các chữ số) để biết liệu 'chữ số ở giữa' đã được truy cập trước đó chưa. Mặt khác, chúng tôi kiểm tra [0] được đảm bảo là trung thực.

Về lần lặp đầu tiên

Lặp lại đầu tiên là một trường hợp đặc biệt, trong đó không có chữ số trước đó và chúng tôi muốn nó thành công vô điều kiện.

Chúng tôi đạt được điều đó bằng cách khởi tạo p thành 1 , vì với bất kỳ n nào trong [1 .. 9] :

  • (1 * n) % 5 không thể phủ định
  • ~(1 - n) không thể bằng 9

Câu trả lời gốc, 90 byte

Đã xóa khỏi bài đăng này để nó không quá dài dòng. Bạn có thể thấy nó ở đây .


-1 byte bằng cách thay thế !!a[1]&bằng a[1]&&, vì bất kỳ giá trị trung thực nào cũng có thể được trả về
Herman L

@HermanLauenstein Cảm ơn, điều đó có vẻ thực sự OK. (Bây giờ, a[1]*thậm chí còn ngắn hơn.)
Arnauld

1
Tôi đã cố gắng hết sức để nghĩ ra một công thức cho has a node directly in line, tôi đã không nhận ra nó sẽ đơn giản như vậy ...
Neil

@Neil Bằng cách xem lịch sử sửa đổi của bài đăng này, tôi chắc chắn bạn có thể nói rằng tôi đã không nhận ra điều đó ngay lập tức ... :)
Arnauld

Hãy nghĩ rằng bạn có thể thay thế ?a[-n]^=1:0bằng &&a[-n]^=1-1, không thể kiểm tra (trên thiết bị di động)
Stan Strum

45

mã máy x86 32 bit, 62 60 byte

Hexdump:

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

Nó nhận được độ dài của danh sách trong ecxvà một con trỏ tới phần tử đầu tiên edxvà trả về kết quả alsau:

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

Có 8 dòng chứa một nút ở giữa:

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

Tôi nhóm chúng theo sự khác biệt giữa số lớn hơn và số nhỏ hơn.

Sự khác biệt 2: 3 dòng (bắt đầu từ 1, 4 hoặc 7)
    1 - 3
    4 - 6
    7 - 9
Chênh lệch 4: 1 dòng (bắt đầu từ 3)
    3 - 7
Chênh lệch 6: 3 dòng (bắt đầu từ 1, 2 hoặc 3)
    1 - 7
    2 - 8
    3 - 9
Chênh lệch 8: 1 dòng (bắt đầu từ 1)
    1 - 9

Sau đó, tôi đã chuyển đổi nó thành bảng tra cứu 2 chiều được lập chỉ mục bằng một nửa khác biệt và số nhỏ hơn:

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

Điều này tạo ra một bitmap "ma thuật" gồm 32 bit. Để lập chỉ mục cho nó, mã đẩy nó vào ngăn xếp. Sau đó, nó trích xuất một byte bằng một chỉ mục và từ byte đó, nó trích xuất một bit bằng chỉ mục khác. Tất cả điều này bằng một hướng dẫn:

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

Nếu bitmap chỉ ra rằng có một nút ở giữa, thật dễ dàng để tính toán - thêm một nửa số chênh lệch vào số nhỏ hơn.

Nguồn hội:

    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

Đẹp! Tôi thực sự thích điều này bt byte ptr [esp + eax], ebx.
Arnauld

5
Rất vui được gặp giải pháp lắp ráp :) Bạn có thể sử dụng cdqthay vì xor edx, edxnhư eaxlà zero. Ngoài ra, bạn có thể gấp lại dec eaxthành bt [esp + eax - 1], ebxcùng chiều dài nhưng sau đó cho phép bạn loại bỏ cái inc ebxsau. Điều này sẽ giúp bạn tiết kiệm hai byte.
Jester

Cảm ơn các ý tưởng! Bạn đã đảm bảo vị trí của mình trong thiên đường của golfer, nếu có một :)
anatolyg

5
Tôi nghĩ tất cả chúng ta có thể đồng ý rằng thiên đường Golfers là địa ngục đối với những người khác.
Adonalsium

19

Python 2 , 140 131 114 104 99 byte

-2 byte nhờ Jonathan Frech
-5 byte nhờ Chas Brown

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

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

Giải trình:

# 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

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

Chỉ có 8 cặp nút có một nút ở giữa chúng. Một cặp nút có thể được biểu diễn dưới dạng một số nguyên theo công thức 2^a-2^b-1. Con số này có thể được rút ngắn bằng modulo lặp đi lặp lại:

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đầu tiên kiểm tra xem một cặp như vậy có mặt hay không, sau đó v-{l+n>>1}==vkiểm tra xem nút ở giữa, được đưa ra bởi (a+b)/2, chưa được truy cập và qđưa ra NameError. Bằng cách sử dụng so sánh chuỗi giữa các cặp này, so sánh tiếp theo chỉ được thực hiện khi trả về trước đó True.


17

Thạch ,  24 22 19  18 byte

-2 vì chúng tôi không còn cần phải xử lý danh sách trống
-1 chuyển từ tham gia, j@sang ghép nối, ;(mục bị bỏ lỡ không cần phải gặp ở giữa đối với phương thức được sử dụng, khi bắt đầu bộ ba là ổn )
-2 chuyển từ P¬aSHđến oSH(OK để có hai kết quả vì chúng ta san bằng, một nửa 10.5được lọc ra dù sao, và có nhiều kết quả tương đương đã không ảnh hưởng đến các phương pháp sử dụng một trong hai)
-1 Nhờ ông Xcoder (0-lập chỉ mục đầu vào được cho phép)

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼

Một liên kết đơn âm lấy danh sách các số nguyên trong [0,8]và trả về giá trị trung thực ( 1) nếu hợp pháp và giá trị falsey ( 0) nếu không.

Hãy thử trực tuyến! hoặc xem một bộ thử nghiệm .

Làm sao?

Nhìn vào từng cặp nút 0 chỉ mục liền kề trong danh sách đầu vào. Nếu phép chia số nguyên cho ba trong số hai khác nhau cho 2 thì chúng nằm ở hàng trên cùng và dưới cùng, nếu modulo bằng ba trong số hai khác nhau thì chúng nằm ở cột bên trái và bên phải. Tổng của các cặp như vậy chia cho hai là nút giữa được lập chỉ mục 0 của một dòng ba nút hoặc giá trị không nguyên - vì vậy các giá trị này trước tiên được chèn vào trước cặp 0 được lập chỉ mục và sau đó bất kỳ các nút không có thật (như 0.5hoặc3.5) được xóa, danh sách kết quả của danh sách được làm phẳng và sau đó được sao chép lại (để mang lại các mục duy nhất, được bảo toàn theo thứ tự) và cuối cùng được so sánh với đầu vào - đối với một lần vuốt hợp pháp, tất cả những điều này sẽ trở thành không có trong khi bất hợp pháp những cái sẽ thêm các nút giữa bị thiếu và / hoặc loại bỏ các nút trùng lặp (lưu ý rằng không có vỏ đặc biệt nào được yêu cầu cho danh sách đầu vào có độ dài 1 vì nó không có cặp liền kề):

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)

Phương pháp trước

Thạch ,  36  35 byte

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

Hãy thử trực tuyến! hoặc xem một bộ thử nghiệm .

Làm sao?

Tương tự như trên nhưng xây dựng tất cả các khả năng ba nút và thực hiện tra cứu (thay vì kiểm tra khi nó sử dụng divmod để kiểm tra và giảm một nửa tổng cho nút giữa).

Đầu tiên là việc xây dựng danh sách ba nút-dòng:

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

Bây giờ việc ra quyết định:

...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)

Làm thế nào để nó đi ra 19 byte khi có một loạt các ký tự unicode?
Izkata

@Izkata Jelly sử dụng trang mã riêng của mình, bạn có thể thấy bằng cách nhấp vào "byte" trong tiêu đề. Ở dạng byte thô, mỗi ký tự Unicode bạn có thể thấy trong mã nguồn chỉ là một byte đơn.
Jonathan Allan

15

Stax , 28 byte

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

Chạy nó

Nó tạo ra 0 cho sai và số nguyên dương cho đúng. Đại diện ascii tương ứng của cùng một chương trình là đây.

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

Ý tưởng chung là tính toán một số điều kiện cần thiết cho các mẫu vuốt hợp pháp và nhân tất cả chúng lại với nhau.

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

Khéo léo sử dụng Ysổ đăng ký.
Weijun Zhou

Một vấn đề khác trên github.
Weijun Zhou

1
Tôi tình cờ đã sửa lỗi đó, nhưng đã không triển khai nó cho đến bây giờ. (nó không ảnh hưởng đến chương trình của tôi)
đệ quy

1
Nghe có vẻ lạ, nhưng bạn có thể bỏ cái đầu tiên vvà bao gồm 1giá trị giả. 2và ở trên là sự thật.
Weijun Zhou

10

JavaScript, 112 byte

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)

Có lẽ một số ngôn ngữ dựa trên regex nên ngắn hơn. Nhưng tôi không biết.

Nhờ Neil, thay đổi )(?!để |tiết kiệm 3 byte.


@ WeijunZhou Tôi đã đúng với 213, có gì sai?
tsh

Không có gì là sai, xin lỗi cho nó.
Weijun Zhou

Bây giờ kể từ khi OP làm rõ, thất bại cho 144.
Weijun Zhou

1
@WeijunZhou nên được sửa; Thêm 2 byte ...
tsh

Trong trường hợp bạn đang tự hỏi, một cổng Retina 0.8.2 dường như hoạt động ở mức 98 byte.
Neil


6

Husk , 25 20 byte

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

Đưa ra một danh sách các số nguyên với lập chỉ mục dựa trên 0. Trả về 0 hoặc 1. Hãy thử trực tuyến!

Giải trình

Tôi đã đánh cắp một số ý tưởng từ câu trả lời Jelly của Jonathan Allan . Ý tưởng là như nhau: chèn một "nút trung bình" mới giữa mỗi cặp liền kề, lọc ra những nút không phải là nút thực tế, loại bỏ trùng lặp và so sánh với danh sách ban đầu. Nếu danh sách ban đầu chứa các bản sao, kết quả là sai lệch. Nếu danh sách bỏ qua một nút không mong muốn, thì nó sẽ xuất hiện trong danh sách được xử lý giữa các cặp tương ứng và kết quả là sai. Nếu đầu vào là một singleton, danh sách được xử lý trống và kết quả là sai. Nếu không, nó là sự thật.

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 ++, 267 256 byte

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

Để kiểm tra xem mẫu có bỏ qua nút không mong muốn hay không, nó thực hiện một số điều:

  1. Tính toán dđâu dlà sự khác biệt giữa số nút hiện hành và nút cuối cùng.
  2. Nếu dlà số lẻ, thì không cần kiểm tra, nó không thể bỏ qua một nút.
  3. Nếu dbằng 4hoặc 8, thì bước nhảy nằm giữa các nút 1-9hoặc 3-7, vì vậy hãy kiểm tra nút5
  4. Nếu dlà 2 và nút giữa ( (last_node + current_node)/2) là 2,5 hoặc 8, thì hãy kiểm tra nút giữa
  5. Nếu dlà 6, kiểm tra tương tự như trước nhưng với 4, 5hoặc6

Các tham số là một int[]và nó là phần tử đếm. Nó trả về một intcái có thể được hiểu là một boolloại


!(d%2)=> d%2<1nên làm việc.
Zacharý


Tôi đã học được một mẹo mới: int s[]=> int*s. Tôi nghĩ rằng nó sẽ làm việc.
Zacharý

2

Perl, 135 byte (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()}

Phiên bản hơi vô căn cứ

@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()
}

Đầu ra thông qua mã thoát. 0là sự thật, bất kỳ giá trị nào khác là giả. Theo sự đồng thuận meta , đầu ra STDERR trong trường hợp thất bại được bỏ qua.

Có lẽ có một cách nhanh hơn để kiểm tra quy tắc "không thể nhảy qua" hơn là chỉ liệt kê tất cả các khả năng.


2

MATL , 42 41 39 byte

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

Điều này tạo ra

  • một vectơ cột không trống chỉ chứa các số khác không là đầu ra trung thực; hoặc là
  • một vectơ cột không trống chứa ít nhất một số 0 là giả.

Ở đây bạn có thể đọc tại sao các kết quả đầu ra tương ứng là trung thực và giả. Hãy thử trực tuyến!

Hoặc xác minh tất cả các trường hợp kiểm tra , với mã chân trang bao gồm kiểm tra tiêu chuẩn về tính trung thực / giả mạo.


2

Stax , 73 72 66 65 byte CP437

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

79 byte khi giải nén,

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

Chạy và gỡ lỗi trực tuyến!

hoặc chạy thử nghiệm lô , trong đó meXlà một tiêu đề để Stax có thể xử lý đầu vào đa dòng.

Thực hiện mà không sử dụng hash.Outputs số nghiêm dương tính (trên thực tế số lượng các bài kiểm tra thất bại) cho falsy trường hợp và 0cho truthy người.

Giải trình

dxóa ngăn xếp đầu vào. Đầu vào là biến x.

4{cAs-5F tạo phần đầu tiên của danh sách nút giữa.

132396978714EE mã hóa phần thứ hai của danh sách nút giữa.

L3/Tập hợp tất cả các phần tử trong ngăn xếp chính và chia thành các phần, mỗi phần chứa 3 phần tử, kết quả là mảng a, chỉ là mảng của tất cả các nhóm 3 nút không hợp lệ.

{xs:IBc0<A*++cEd:-1=sccHs|M=s{U>m|A**mEĐối với mỗi danh sách nút không hợp lệ, thực hiện các kiểm tra sau. Kết quả của kết quả kiểm tra là anded bằng cách sử dụng **. Vì có 8 danh sách nút không hợp lệ, kết quả của mã này sẽ là một mảng gồm 8 phần tử. Cuối cùng Egửi mảng đến các phần tử riêng lẻ của nó trên ngăn xếp chính.

xs:I lấy chỉ mục của các thành phần danh sách nút trong mảng đầu vào.

Bc0<A*++Nếu chỉ mục của "nút giữa" (ví dụ 5trong tập nút 1,5,9) là -1(có nghĩa là nó không tồn tại trong mảng đầu vào), hãy thay đổi chỉ mục thành 9.

cEd:-1=kiểm tra xem hai "nút đầu cuối" (ví dụ 1,5trong tập nút 1,5,9) có liền kề trong mảng đầu vào không.

sccHs|M= kiểm tra xem chỉ số được chuyển đổi của "nút giữa" có lớn hơn chỉ số của hai "nút cuối" hay không, bao gồm hai trường hợp: "nút giữa" bị thiếu hoặc "nút giữa" xuất hiện sau hai "nút cuối"

s{U>m|Akiểm tra xem cả hai chỉ số của "nút cuối" có phải là không âm hay không. (tức là cả hai đều xuất hiện trong đầu vào).

Hai bài kiểm tra bổ sung được thực hiện,

x%2< kiểm tra xem mảng đầu vào có phải là một singleton không.

xu%x%=! kiểm tra xem các nút đã được truy cập hai lần.

Có 10 kết quả thử nghiệm trên ngăn xếp chính (một cho mỗi danh sách nút không hợp lệ, cộng với hai thử nghiệm bổ sung).

L|+thu thập 10 yếu tố và thêm chúng. |acũng có thể được sử dụng để kiểm tra xem có bất kỳ phần tử trung thực nào trên mảng không.

Ngụ ý đầu ra.


2

Java, 375 355 byte

-20 byte nhờ 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;}

Đây là một cổng của câu trả lời này và nó hoạt động trên cùng một nguyên tắc


Ái chà. Bạn đang loay hoay trong Java.
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;}nên làm việc (thứ tự các hoạt động)
Zacharý

Bạn có thể thay đổi (d==2)thành chỉ d==2, tôi đã bỏ qua điều đó trước đây.
Zacharý

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

0

Bình thường , 33 byte

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

Bộ thử nghiệm.

Sử dụng lập chỉ mục dựa trên 0.

Giải trình

q {@ U9.nm + mc | g1aZksd2-MC.DR3d_dC, t -> Chương trình đầy đủ. Đầu vào: một danh sách L từ STDIN.

                               , t -> Ghép L với L không có phần tử đầu tiên.
                              C -> Chuyển vị.
       m -> Ánh xạ qua danh sách các cặp (danh sách 2 yếu tố):
        + mc | g1aZksd2-MC.DR3d -> Hàm được ánh xạ (biến: d):
                         R d -> Với mỗi phần tử của d ...
                       .D 3 -> ... Lấy divmod của nó bằng 3.
                      C -> Chuyển hướng.
                    -M -> Giảm từng bằng phép trừ.
         m -> Với mỗi khác biệt (biến: k):
            g1aZl -> Là | k | ≤ 1?
           | sd -> Nếu đó là giả, thay thế nó bằng tổng d.
          c 2 -> Chia cho 2.
        + _d -> Nối ngược lại d vào kết quả ánh xạ.
     .n -> Làm phẳng.
  @ U9 -> Đi giao điểm với (∩ [0; 9)).
 {-> Khử trùng lặp.
q -> Và kiểm tra xem kết quả có bằng L.

Cách tiếp cận khác cho 34 byte :

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

0

Japt , 35 byte

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

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

Hơi vô dụng & Cách thức hoạt động

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?

Đưa ra ý tưởng từ giải pháp Jelly này , với một số khác biệt trong việc xác định các bước nhảy tiềm năng:

  • Câu trả lời Jelly sử dụng divmod để xem một cặp có chênh lệch 2 khi áp dụng /3hay không %3.
  • Câu trả lời này chỉ sử dụng %3và kiểm tra xem chênh lệch là 0 hay 2. Nếu chênh lệch là 0, hai ô được căn chỉnh theo chiều dọc và không nhảy vẫn chia sẻ thuộc tính của (X+Y)%2 != 0.

0

Python 2 , 97 byte

Dựa trên câu trả lời của ovs nhưng ngắn hơn 2 byte và ít khó hiểu hơn. Chỉ cần chuyển đổi các chỉ mục thành tọa độ 2d và kiểm tra tính chẵn lẻ. Giả sử 0-8 chỉ số.

v={9}
s=input()
for n,l in zip(s[1:]or q,s):n/3+l/3&1|n%3+l%3&1or n+l>>1in v or q;v|={l};n in v>q

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

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.