Чи законний режим мого пальця?


154

Більшість смартфонів Android дозволяють користувачеві скористатися схемою пальця, щоб відкрити свій телефон:

блокування візерунка

Деякі зразки є законними, а інші - неможливими. З огляду на шаблон введення пальцем, поверніть форму та помилкове вказівку, чи вказаний шаблон введення законний чи ні.

Вхідні дані

Сітка позначена рядками від 1 до 9:

1 2 3   
4 5 6   
7 8 9

Вхід - це число, що складається з вузлів, відвіданих від першого до останнього. Наприклад, наведена вище модель пальця - 12357.

Введенням може бути десяткове число, рядок або список чисел. Він не буде містити 0, оскільки немає вузла 0.

Поправка: індексація 0-8 дозволена, оскільки багато мов індексують від 0. Якщо ви використовуєте 0-8, потрібно буде вказати як таке на початку своєї відповіді та відповідно скорегувати тестові випадки.

Правила

  • Кожен вузол починається, як спочатку не відвідуваний, і його можна відвідувати лише один раз. Будь-яка модель, яка відвідує вузол не один раз, є хибною.

  • Простий малюнок повинен містити принаймні одне пальце, тому мінімум 2 вузли.

  • Неможливо пропустити через невідомий вузол прямо у відповідність з іншим. Наприклад, 13 - хибний, тому що 2 є невидимими і безпосередньо в черзі.

  • Можна лише пропустити через відвідуваний вузол. 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 так. Це буде непорожнім.
stanri

Питання, пов'язані з математикою: math.stackexchange.com/questions/205049/…
Pureferret

Відповіді:


69

JavaScript (ES6), 64 байти

Вводить введення як масив чисел. Фальшиві значення - 0 або NaN . Значення Truthy - це суворо додатні цілі числа.

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)

    протилежні цифри

Крім того, цифра, що стоїть між двома протилежними цифрами n і p , дорівнює (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()цикл із наступною ітерацією. В іншому випадку він очистить прапор і змусить цикл негайно вийти з ладу.

  • Якщо p встановлено як невизначений :

    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)

Тому цей вираз повертає 1, якщо і лише тоді, коли n і -p - протилежні цифри або вони однакові непарні цифри. Оскільки цифру неможливо вибрати двічі, то в останньому випадку все одно правильно переконатися.

Якщо цей вираз повертає 1 , ми тестуємо a [p / 2] (де p зараз дорівнює запереченій сумі цифр), щоб дізнатися, чи був раніше відвіданий 'проміжок між цифрою'. В іншому випадку ми перевіряємо [0], який гарантовано є правдою.

Про першу ітерацію

Перша ітерація - це особливий випадок, оскільки немає попередньої цифри, і ми хочемо, щоб вона була безумовно успішною.

Ми досягаємо цього, ініціалізуючи p до 1 , тому що для будь-якого n в [1 .. 9] :

  • (1 * n) % 5 не може бути негативним
  • ~(1 - n) не може бути рівним 9

Оригінальна відповідь, 90 байт

Видалено з цієї публікації, щоб вона не стала надто багатослівною. Ви можете побачити тут .


-1 байт, замінивши !!a[1]&на a[1]&&, оскільки будь-яке значення truthy може бути повернене
Герман L

@HermanLauenstein Дякую, це справді здається нормальним. (Зараз a[1]*ще коротше.)
Арнальд,

1
Я відчайдушно намагався придумати формулу has a node directly in line, я не розумів, що це буде так просто ...
Ніл,

@Neil Переглянувши історію редагування цього допису, я впевнений, що ви можете сказати, що я і цього не зрозумів одразу ... :)
Арнольд,

Думаю , ви можете замінити ?a[-n]^=1:0з &&a[-n]^=1на -1, не може перевірити (на мобільний)
Stan бриньчати

45

32-бітний машинний код x86, 62 60 байт

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

Він отримує довжину списку в 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-D таблицю пошуку, індексовану половиною різниці та меншим числом:

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.
Арнольд

5
Приємно бачити рішення для складання :) Ви можете використовувати cdqзамість xor edx, edxяк eaxнуль. Крім того , ви можете скласти dec eaxв bt [esp + eax - 1], ebxякий такий же довжини , але потім дозволяє видалити inc ebxпізніше. Це має заощадити два байти.
Єстер

Дякую за ідеї! Ви забезпечили своє місце в раю гольфіста, якщо такий є :)
anatolyg

5
Я думаю, що ми можемо погодитися, що рай для гольфістів - це пекло для всіх інших.
Адоналізій

19

Пітон 2 , 140 131 114 104 99 байт

-2 байти завдяки Джонатану Фреху
-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викликає ім'я Error. Використовуючи ланцюгові порівняння між цими парами, наступне порівняння виконується лише тоді, коли повернеться попереднє 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, вони знаходяться у верхньому та нижньому рядах, якщо модуль на три з двох відрізняється на 2, вони знаходяться у лівій та правій колонках. Сума таких пар, розділених на дві, є або 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⁼ȧȦ

Спробуйте в Інтернеті! або побачити тестовий набір .

Як?

Подібно до вищезазначеного, але будує всі можливості у трьох вузлах-рядках та виконує пошук (замість перевірки, як це використовується за допомогою divmod для тестування та вдвічі меншої суми для середнього вузла).

По-перше, побудова списку тривузлових ліній:

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 байт, коли є купа символів Unicode?
Ізката

@Izkata Jelly використовує власну кодову сторінку, яку ви можете побачити, натиснувши "байти" у заголовку. У своїй необробленій байтовій формі кожен із символів Unicode, який ви можете бачити у вихідному коді, - це лише один байт.
Джонатан Аллан

15

Стакс , 28 байт

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

Виконати його

Він створює 0 для помилкових, а додатні цілі числа для істинних. Відповідне представлення такої ж програми 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реєстру.
Вейджун Чжоу

Ще одне питання про github.
Вейджун Чжоу

1
Я випадково вже виправив цю помилку, але не розгорнув її до цих пір. (це не впливає на мою програму)
рекурсивна

1
Це може здатися дивним, але ви можете кинути перше vі включити 1як помилкове значення. 2і вище - truthy.
Вейджун Чжоу

10

JavaScript, 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)

Можливо, мова на основі регулярних виразів повинна бути коротшою. Але я не знаю.

Завдяки Нілу, змініть, )(?!щоб |зберегти 3 байти.


@WeijunZhou Я справдився для 213, що не так?
tsh

Нічого не так, вибачте за це.
Вейджун Чжоу

Тепер, відколи уточнив, ОП не працює 144.
Вейджун Чжоу

1
@WeijunZhou слід виправити; Ще 2 байти ...
tsh

Якщо вам цікаво, порт Retina 0.8.2, здається, працює у 98 байт.
Ніл


6

Лушпиння , 25 20 байт

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

Бере список цілих чисел з індексуванням на основі 0. Повертає 0 або 1. Спробуйте онлайн!

Пояснення

Я вкрав кілька ідей з відповіді Джонатана Аллана на желе . Ідея та ж: вставити новий «середній вузол» між кожною сусідньою парою, відфільтрувати ті, що не є фактичними вузлами, видалити дублікати та порівняти з вихідним списком. Якщо оригінальний список містить дублікати, результат стає хибним. Якщо список пропускає невидимий вузол, він присутній в обробленому списку між відповідною парою, і результат є хибним. Якщо вхід є однотонним, оброблений список порожній, а результат - хибним. В іншому випадку вона є правдою.

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 байт

#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. Якщо dце 2, а середній вузол ( (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()}

Трохи незворушена версія

@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

Це виробляє

  • вектор не порожнього стовпця, що містить лише ненульові числа в якості правдивого виводу; або
  • вектор не порожнього стовпця, що містить принаймні нуль, як помилковий.

Тут ви можете прочитати, чому ці результати є відповідно істинними, і хибними. Спробуйте в Інтернеті!

Або перевірити всі тестові випадки за допомогою коду нижнього колонтитула, що включає стандарт тест на правдивість / хибність.


2

Стакс , 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|+

Запуск та налагодження в Інтернеті!

або запустити пакетний тест , де meXє заголовок, щоб Stax міг обробляти багаторядкові введення.

Реалізація без використання хешів. Виводить суворо позитивне число (фактично кількість невдалих тестів) для фальшивих випадків і 0для правдивих .

Пояснення

dочищає стек вводу. Вхід є зміннимx будь-якому випадку .

4{cAs-5F генерує першу частину списку середнього вузла.

132396978714EE жорсткі коди другої частини списку середніх вузлів.

L3/ Збирає всі елементи в основний стек і ділить на частини, кожна з яких містить 3 елементи, результат - масив 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могла бути також використана, яка просто перевіряє, чи є в масиві якісь truthy елементи.

Неявний вихід.


2

Java, 375 355 байт

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

Це відповідь цієї відповіді, і вона працює на тих же принципах


Вуа. Ви прихиляєтесь до 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;}повинен працювати (порядок операцій)
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 -> Повна програма. Введення: список L від STDIN.

                               , t -> Пара L з L без першого елемента.
                              C -> Транспонування.
       m -> Позначте перелік пар (двоелементні списки):
        + 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

Japt , 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, щоб перевірити, чи пара має різницю 2 при застосуванні /3або %3.
  • Ця відповідь використовує лише %3і перевіряє, чи різниця дорівнює 0 або 2. Якщо різниця дорівнює 0, дві комірки розташовані вертикально, а не-стрибки все ще поділяють властивість (X+Y)%2 != 0.

0

Python 2 , 97 байт

На основі відповіді ovs, але 2 байти коротше і менш виразно. Просто перетворює індекси на 2d координати і перевіряє паритет. Припускає 0-8 індексів.

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

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.