Android锁屏


25

介绍

您正坐在长桌尽头的会议室。您环顾四周,可以看到苹果董事会的蒂姆·库克,史蒂夫·乔布斯的鬼魂和杰克·多纳西。苹果之所以召开这次会议,是因为他们意识到Android锁定屏幕要酷得多,并且他们希望1-UP。当Ghost Steve哭着时,房间里的每个人都在注视着你,“帮我,CodeGolf的人!你是我唯一的希望!”

问题

Android锁定屏幕是一个3 x 3的点网格,可以通过将手指从一个点滑到另一个点来建立路径来进行连接。密码被认为是任何可能的路径,包括任何数量的点,但不包括任何数量的点。(在实际的电话上,路径必须至少有4个点长。对此挑战,请忽略该限制。)苹果计划用M x N网格(即(M * N)/ 9)替换3 x 3网格。倍好!

规则:

  • 零点路径不是密码,但一个点路径是
  • 一条路可以穿越自己
  • 路径不能直接跨越点而不包含该点
  • 一个点只能使用一次
  • 旋转相同的路径不是相同的密码
  • 相同但反向排序的路径不是相同的密码
  • 例如,在3x3网格上,点编号从1到9:

    1 2 3
    4 5 6
    7 8 9
    

    一些有效的路径是:

    1
    3
    7,2,3
    1,5,9,2
    1,8,6,5,4
    4,2,3,5,6,7,8,9
    5,9,6,4
    

    一些无效的路径是:

    1,3
    1,9,5
    7,5,4,7
    4,6
    

    您的输入将是三个数字:

    (M,N,d)
    

    其中格是M x N,而d是路径的长度

    1 <= M <= 16
    1 <= N <= 16
    1 <= d <= M * N
    

    您的程序或函数将以逗号分隔的字符串形式输入,并且它必须返回该长度的可能密码。例如:

    Input:  2,2,1 
    Output: 4
    Input:  2,2,2
    Output: 12
    Input:  7,4,1
    Output: 28
    

    适用标准代码高尔夫规则,最短代码获胜!

    //If I've made a mistake or the rules are unclear, please correct me!
    

    2
    输入是逗号分隔的字符串还是三个单独的参数?
    2014年

    1
    @ user80551基于上下文,我认为如果将其输入到程序中,它将是一个字符串;如果用于调用函数,则它将是单独的参数。
    user12205 2014年

    1
    @Platatat能否请您回答user80551的问题,因为这对设计代码确实很重要
    RononDex 2014年

    3
    您应该确定给定解决方案的编译时间和执行时间是否都有时间限制。没有这样的限制,很容易编写一个程序,该程序在理论上可以验证256!16 x 16网格上所有点的排列中的哪一个表示有效的解锁图案。实际上,这样的程序永远不会终止。
    丹尼斯

    3
    但是我说这个问题是基于android锁定系统的。。。为什么我不应该使用与android锁定系统相同的规则?
    Platatat 2014年

    Answers:


    14

    Python-170个字节

    from fractions import*
    p=lambda m,n,d,l=0,s=set():d<1or sum([p(m,n,d-1,i,s|{i})for i in range(m*n)if not(s and(s&{i}or set(range(l,i,abs(i-l)/gcd(i%n-l%n,i/n-l/n)))-s))])
    

    我意识到里面的括号sum([...])不是严格必要的,但是如果不包含括号,将会有很大的性能损失。

    所有3x3的输出:

    for i in range(4, 10):
      print p(3, 3, i)
    

    产生:

    1624
    7152
    26016
    72912
    140704
    140704
    

    为了进行测试/确认,使用4x5电路板的前6个值:

    20
    262
    3280
    39644
    459764
    5101232
    

    4x5是一个有趣的验证案例,因为它具有2x2、3x3和2x4钉跳。


    简要说明

    通常,这是一个详尽的搜索,带有累积修剪。例如,因为p(3, 3, 4)是1624,所以p(3, 3, 5)只会检查8120可能性,而不会天真的检查所有15120。大多数逻辑包含在条件中:

    if not(s and(s&{i}or set(range(l,i,abs(i-l)/gcd(i%n-l%n,i/n-l/n)))-s))
    

    用简单的英语来说,可以理解为:

    If no pegs have been used yet
         OR
       the target peg has not yet been used
         AND
       each of the pegs directly between the target peg and the
       current peg (a.k.a. "jumped over") have already been used
    

    2
    您能解释一下这是怎么回事吗?
    ɐɔıʇǝɥʇuʎs

    1
    通过s设置而不是列表,可以节省一些字节。我没有看到放括号会造成很大的性能损失;为什么会有这样的惩罚?
    user2357112支持Monica 2014年

    1
    @ user2357112一种是通过生成器求和,另一种是通过列表求和。没错,使用CPython并没有太大区别(仅慢20%)。使用PyPy,速度是原来的5倍以上。
    primo 2014年

    1
    @ user2357112我终于明白了定义s为集合的含义。我今天的python课:{i}评估为set([i])。我本来期望语法错误。然后将项目追加到集合成为s|{i},也可以i in s将其替换为s&{i}
    primo 2014年
    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.