我的滑动方式合法吗?


154

大多数Android智能手机都允许用户使用滑动模式打开手机:

图案锁

某些模式是合法的,而其他则是不可能的。给定输入滑动模式,请返回真或假,以指示给定的输入模式是否合法。

输入项

网格标记为逐行1到9:

1 2 3   
4 5 6   
7 8 9

输入是一个从头到尾访问的节点组成的数字。例如,上方的滑动模式为12357。

输入可以是十进制数字,字符串或数字列表。它不会包含0,因为没有节点0。

修订:由于许多语言都从0开始索引,因此允许索引0-8。如果您使用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

@Zgarb是的。这将是非空的。
斯坦里

Answers:


69

JavaScript(ES6),64字节

将输入作为数字数组。伪造的值为0NaN。真实值严格是正整数。

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

    如果先前未选择当前数字na[-n] ^= -n将设置该标志并让every()循环在下一次迭代中继续进行。否则,它将清除该标志并强制循环立即失败。

  • 如果p设置为undefined

    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],该值保证为真。

关于第一次迭代

第一次迭代是一个特例,因为没有前一位,我们希望它无条件地成功。

我们实现,通过初始化p1,因为对于任何Ñ[1 .. 9]

  • (1 * n) % 5 不能为负
  • ~(1 - n) 不能等于9

原始答案,90个字节

已从此帖子中删除,以免太冗长。你可以在这里看到它


-1字节替换!!a[1]&a[1]&&,因为可以返回任何真实值
Herman 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字节

十六进制转储:

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

然后,我将其转换为以半差和较小数字索引的二维查找表:

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
很高兴看到装配解决方案:)您可以使用as cdq而不是零。同样,您可以折叠成相同长度的,但随后可以将其删除。这将为您节省两个字节。xor edx, edxeaxdec eaxbt [esp + eax - 1], ebxinc ebx
小丑

感谢您的想法!您已经在高尔夫球手的天堂中占据一席之地,如果有一个:)
anatolyg 18-2-14

5
我认为我们都可以同意高尔夫球手天堂对其他所有人来说都是地狱。
Adonalsium '18

19

Python 2中140个 131 114 104 99字节

-2字节归功于Jonathan Frech
-5字节归功于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

在线尝试!

说明:

# 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因为不再需要处理
从连接join j@到连接的空列表-1 ;(对于所使用的方法,不需要在中间遇到错过的项,因为在三重奏的开头就可以了)
-2从切换P¬aSHoSH(自从我们展平以来,可以得到两个结果,无论如何1都将0.5其中的一半过滤掉,并且具有多个相等的结果也不会影响所采用的方法)
-1感谢Xcoder先生(0索引)允许输入)

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼

单链链接,其中包含一个整数列表,如果合法则[0,8]返回真值(1),否则返回假值()0

在线尝试!或见一个测试套件

怎么样?

查看输入列表中每对相邻的0索引节点。如果整数除以两个中的三个相差2,则它们在顶部和底部行中;如果两个整数中的三个相除的模数相差2,则它们在左侧和右侧列中。此类对的总和除以2可以是三节点行的0索引中间节点或非整数值-因此,这些值首先插入0索引对的前面,然后再插入假节点(例如0.53.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)

当有一堆unicode字符时,它如何变成19个字节?
Izkata

@Izkata Jelly使用其自己的代码页,您可以通过单击标题中的“字节”来查看。在原始代码中,您可以在源代码中看到的每个Unicode字符都只是一个字节。
乔纳森·艾伦

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寄存器。

github上的另一个问题。

1
巧合的是,我已经修复了该错误,但是直到现在才部署它。(这不会影响我的程序)
递归

1
听起来可能很奇怪,但是您可以删除第一个,v并将其包含1为虚假值。2以上都是真实的。
周卫军

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)

也许一些基于正则表达式的语言应该更短一些。但是我不知道。

感谢Neil,更改)(?!|节省3个字节。


@WeijunZhou我对213正确,怎么了?
tsh

没错,对不起。
周卫军

现在,自从OP澄清以来,失败了144
周卫军

1
@WeijunZhou应该固定;还有2个字节...
tsh

如果您想知道,Retina 0.8.2端口似乎可以使用98字节。
尼尔,

6

视网膜0.8.2,98字节

受tsh的回答影响。我尝试将其“改写”为相反,匹配无效的滑动,然后进行“反抓取”。

A`(.).*\1|^([^5]*(19|28|37|46|91|82|73|64)|[^2]*(13|31)|[^8]*(79|97)|[^4]*(17|71)|[^6]*(39|93)|.$)

在线尝试


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 ++,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等于48,则跳转在节点1-9或之间进行3-7,因此检查节点5
  4. 如果d为2,中间节点((last_node + current_node)/2)为2,5或8,则检查中间节点
  5. 如果d是6,和以前一样,但与检查456

参数是int[]及其元素计数。它返回一个int可以解释为bool类型的


!(d%2)=> d%2<1应该可以。
扎卡里


我学会了一个新技巧:int s[]=> int*s。我认为那行得通。
扎卡里

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

MATL42 41 39字节

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

这产生

  • 非空列向量,仅包含非零数字作为真实输出;要么
  • 一个非空列向量,至少包含一个零

在这里您可以了解为什么这些输出分别是真实的和虚假的。在线尝试!

或使用页脚代码验证所有测试用例,其中包括用于真实性/虚假性的标准测试


2

Stax73 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可以处理多行输入。

实现不使用hash.Outputs严格正数(实际上是失败的测试数)falsy案件和0truthy的。

说明

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

Java中,375个 355字节

-20字节归功于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;}

这是此答案的一部分,并且基于相同的原理


哇。您正在使用Java。
扎卡里

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;}应该工作(操作顺序)
扎卡里

您可以更改(d==2)为just d==2,我之前忽略了这一点。
扎卡里

d%2==0=>d%2<1
扎卡里

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 –>是| 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解决方案移植了这个想法,在确定潜在跳跃方面有所不同:

  • 果冻答案使用divmod来查看应用/3或时一对是否相差2 %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

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.