Android Kilit Ekranı


25

giriş

Uzun bir masanın sonunda bir tahta odada oturuyorsunuz. Etrafınıza bakın ve Apple Yönetim Kurulu Tim Cook, Steve Jobs hayaleti ve Jack Donaghy'yi görün. Apple bu toplantıyı aradı çünkü Android kilit ekranının ne kadar serin olduğunu fark ettiler ve 1-UP yapmak istiyorlar. Odadaki herkes sana bakar ve Ghost Steve ağlar, "Yardım et, CodeGolf Man! Sen benim tek umudumsun!"

Sorun

Android kilit ekranı, parmağınızı bir noktadan diğerine kaydırarak bağlanabilen 3 x 3 nokta ızgarasıdır. Bir parola, herhangi bir sayıda nokta içeren ve herhangi bir sayıda noktayı içermeyen olası bir yol olarak kabul edilir. (Gerçek bir telefonda, yol en az 4 nokta uzunluğunda olmalıdır. Bu zorluk için bu kısıtlamayı göz ardı edin.) Apple, 3 x 3 ızgarasını (M * N) / 9 olan bir M x N ızgarasıyla değiştirmeyi planlıyor. Kez daha iyi!

Kurallar:

  • Sıfır nokta yolu şifre değil, 1 nokta yolu
  • Bir yol kendini geçebilir
  • Bir yol, o noktayı eklemeden doğrudan bir noktadan geçemez.
  • Bir nokta yalnızca bir kez kullanılabilir
  • Döndürmeyle aynı olan yollar aynı parola değil
  • Aynı ama ters sırada olan yollar aynı parola değil
  • Örneğin, 1 - 9 arasında numaralandırılmış noktalı 3x3 ızgarada:

    1 2 3
    4 5 6
    7 8 9
    

    Bazı geçerli yollar:

    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
    

    Ve bazı geçersiz yollar:

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

    Girişiniz üç rakam olacaktır:

    (M,N,d)
    

    Kılavuzun M x N olduğu ve d yolun uzunluğu

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

    Programınıza veya işlevinize girişe virgülle ayrılmış bir dize olarak verilecek ve bu uzunluktaki olası şifrelerin sayısını döndürmelidir. Örneğin:

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

    Standart kod golf kuralları geçerlidir, en kısa kod kazanır!

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

    2
    Giriş virgülle ayrılmış bir dize mi, yoksa üç ayrı parametre mi?
    user80551 31.03.2014

    1
    @ user80551 Bağlamdan yola çıkarak, eğer bir programa girilirse dizge olacağını ya da işlevi çağırmak için kullanılıyorsa parametreleri ayıracağını düşünüyorum.
    user12205,

    1
    @Platatat, user80551'in sorusunu cevaplayabilir misiniz, çünkü bu, kodu tasarlamak gerçekten önemlidir
    RononDex,

    3
    Belirli bir çözümün hem derleme hem de yürütme süresi için bir zaman sınırı olup olmayacağına karar vermelisiniz. Böyle bir sınırlama olmadan, teorik 256!olarak, 16 x 16 ızgaradaki noktaların tüm permütasyonlarından hangisinin geçerli bir kilit açma düzenini temsil ettiğini doğrulayan bir program yazmak kolaydır . Uygulamada, böyle bir program asla sonlandırılmaz.
    Dennis,

    3
    Ama sorunun android kilit sistemine dayandığını söyledim ... Peki neden android kilit sistemiyle aynı kuralları kullanmamalıyım?
    Platatat

    Yanıtlar:


    14

    Python - 170 bayt

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

    İçindeki parantezlerin sum([...])kesinlikle gerekli olmadığının farkındayım , ancak onları dahil etmemenin büyük bir cezası var.

    Tüm 3x3'ler için çıktı:

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

    üretir:

    1624
    7152
    26016
    72912
    140704
    140704
    

    Test / onay amaçlı, 4x5 anakart için ilk 6 değer:

    20
    262
    3280
    39644
    459764
    5101232
    

    4x5, 2x2, 3x3 ve 2x4 peg atlamalarına sahip olduğundan emin olmak için ilginç bir durumdur.


    Kısa açıklama

    Genel olarak, bu birikimli budama ile kapsamlı bir aramadır. Örneğin p(3, 3, 4), 1624 olduğundan , p(3, 3, 5)tüm 15120’yi kontrol etmek yerine yalnızca 8120 olasılıkları kontrol eder. Mantığın çoğu şu durumda bulunur:

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

    Düz İngilizce olarak, bu olarak anlaşılabilir:

    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
    Dünyada neler olup bittiğini burada açıklayabilir misiniz?
    Aprıʇǝɥʇuʎs

    1
    sListe yerine set yaparak birkaç bayttan tasarruf edebilirsiniz . Parantez düşürme büyük performans cezası göremiyorum; neden böyle bir ceza olsun ki?
    user2357112

    1
    @ user2357112 biri bir Jeneratör, diğeri bir Listede toplanıyor. CPython ile haklısınız, çok fazla fark yok (sadece yaklaşık% 20 daha yavaş). PyPy ile, 5 kat daha yavaş.
    primo

    1
    @ user2357112 Sonunda sset olarak tanımlayarak ne demek istediğinizi anladım . Bugünkü piton dersim: olarak {i}değerlendirir set([i]). Bir sözdizimi hatası umuyordum. Bir kümeye bir öğe eklemek daha sonra olur s|{i}ve aynı zamanda i in starafından değiştirilmesine izin verir s&{i}.
    primo
    Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
    Licensed under cc by-sa 3.0 with attribution required.