Androidロック画面


25

イントロ

長いテーブルの端にある会議室に座っています。周りを見てみると、ティムクック、アップルの取締役会、スティーブジョブズの幽霊、ジャックドナギーが見えます。Appleがこの会議を呼び出したのは、Androidのロック画面がどれほどクールであるかを認識しており、それらを1アップにしたいからです。ゴーストスティーブが叫ぶように、部屋の誰もがあなたを見つめます。「助けてくれ、CodeGolf Man!あなたは私の唯一の希望です!」

問題

Androidのロック画面は3 x 3のドットグリッドで、1つのドットから次のドットに指をスワイプしてパスを作成することで接続できます。パスワードは、任意の数のドットを含む可能性のあるパスと見なされ、任意の数のドットを除外します。(実際の電話では、パスは少なくとも4ドットである必要があります。このチャレンジでは、その制限を無視してください。)Appleは、3 x 3グリッドを(M * N)/ 9であるM x Nグリッドに置き換える予定です倍良い!

ルール:

  • ゼロドットパスはパスワードではありませんが、1ドットパスはパスワードです
  • パスはそれ自身を横断できます
  • パスは、ドットを含めずにドットを直接越えることはできません
  • ドットは1回しか使用できません
  • ローテーションによって同一のパスは同じパスワードではありません
  • 同一であるが逆の順序のパスは同じパスワードではありません
  • たとえば、1〜9の番号が付けられた3x3グリッドの場合:

    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
    

    入力は3つの数字になります。

    (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
    入力はコンマ区切りの文字列ですか、3つの個別のパラメーターですか?
    user80551

    1
    @ user80551コンテキストに基づいて、プログラムへの入力の場合は文字列になり、関数の呼び出しに使用される場合は個別のパラメーターになると思います。
    user12205 14年

    1
    これは、コードを設計することが非常に重要であるとして@Platatatあなたは、回答user80551の質問を喜ばせることができます
    RononDex

    3
    特定のソリューションのコンパイル時間と実行時間の両方に時間制限があるかどうかを判断する必要があります。そのような制限がなければ、理論的には256!、16 x 16グリッド上のドットのすべての順列のどれが有効なロック解除パターンを表すかを検証するプログラムを作成するのは簡単です。実際には、そのようなプログラムは決して終了しません。
    デニス14年

    3
    しかし、私は問題がアンドロイドロックシステムに基づいていると言いました...それで、なぜ私はアンドロイドロックシステムと同じ規則を使うべきではありませんか?
    プラタタ14

    回答:


    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)15120すべてを単純にチェックするのではなく、8120の可能性のみをチェックします。ほとんどのロジックは条件に含まれています。

    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を14

    1
    @ user2357112 1つはジェネレーターで合計し、もう1つはリストで合計しています。CPythonでは、あなたは正しいです。それほど違いはありません(わずかに約20%遅くなります)。PyPyでは、5倍以上遅くなります。
    プリモ14

    1
    @ user2357112最後にs、セットとして定義することの意味を確認します。今日の私のPythonレッスン:と{i}評価しset([i])ます。構文エラーが予想されます。アイテムをセットにs|{i}追加i in sすると、になり、で置き換えることもできますs&{i}
    プリモ14
    弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
    Licensed under cc by-sa 3.0 with attribution required.