Android Kilit Desenini Çözme


26

Arkadaşınızın Android telefona şifresini girdiğini görelim. Deseni nasıl yaptıklarını hatırlamıyorsun ama desenin nasıl göründüğünü hatırlıyorsun. Endişeli arkadaş olduğunuzda, şifrelerinin ne kadar güvenli olduğunu bilmek istersiniz. İşiniz, belirli bir modelin yapılabilecek tüm yollarını hesaplamaktır.

Android kalıpları nasıl çalışır?

Desenler 3x3 düğüm ızgarasına çizilir. Bir düzende, parmaklarını ekrandan kaldırmadan bir dizi düğüm ziyaret edilir. Ziyaret ettikleri her düğüm önceki düğüme bir kenar ile bağlanır. Akılda tutulması gereken iki kural vardır.

  • Herhangi bir düğümü bir kereden fazla ziyaret edemezsiniz

  • Bir kenar görünmeyen bir düğümden geçemez

Gerçek android kilit kombinasyonlarında genellikle çok zor ve dolayısıyla çok yaygın olmamakla birlikte, şövalye gibi hareket etmenin mümkün olduğunu unutmayın . Yani, bir taraftan bitişik olmayan bir köşeye veya başka bir yöne hareket etmek mümkündür. İşte böyle bir hareket kullanan iki kalıp örneği:

İşte gerçekleştirilen animasyonlu bir GIF .

Bir model çözme

Tipik bir model şöyle bir şeye benzeyebilir:

Bunun gibi basit bir desenle, iki deseni çizmenin iki yolu vardır. İki gevşek ucun herhangi birinden başlayabilir ve vurgulanan düğümlerden diğerine geçebilirsiniz. Bu, çoğu insan için geçerli olsa da, özellikle insanların tipik olarak kullandığılar, bu tüm modeller için doğru değildir.

Aşağıdaki modeli göz önünde bulundurun:

Hemen fark edilebilir iki çözüm var. Sol üstte başlayan bir kişi:

Ve bir tanesi alt ortada başlıyor:

Bununla birlikte, bir çizginin zaten seçildikten sonra bir noktadan geçmesine izin verildiğinden, üst ortada başlayan ek bir desen vardır:

Bu belirli modelin 3 çözümü vardır, ancak modeller 1 ile 4 arasında bir çözüme sahip olabilir [kaynak belirtilmeli] .

İşte her birinin bazı örnekleri:

1.

2.

3.

4.

I / O

Bir düğüm sıfır ila dokuz dahil tam sayılar, dize eşdeğerleri veya a ila i (veya A ila I) karakterleri olarak temsil edilebilir. Her düğüm, bu kümelerden birinin benzersiz bir temsiline sahip olmalıdır.

Bir çözüm, düğüm temsillerini içeren sıralı bir kap ile temsil edilecektir. Düğümlerin, geçirildikleri sırayla sipariş edilmesi gerekir.

Bir düzen sırasız düğüm çiftleri kabı ile temsil edilecektir. Her bir çift, çiftin iki noktasını birbirine bağlayan bir kenarı temsil eder. Desen gösterimleri benzersiz değil.

Standart girdi yöntemleri ile girdi olarak bir model gösterimi alacak ve aynı modeli oluşturan tüm olası çözümleri standart çıktı yöntemleri ile çıkartacaksınız.

Her girişin en az bir çözüme sahip olacağını ve en az 4 düğüm bağlayacağını varsayabilirsiniz.

Dil seçimine zorlanmak veya istemek zorunda kalırsanız, sıralanmamış bir kabın yerine sipariş edilen bir kap kullanmayı tercih edebilirsiniz.

Test Kılıfları

Aşağıdaki düzende düzenlenmiş düğümlerle:

0 1 2
3 4 5
6 7 8

{...}Sırasız bir konteyner, [...]düzenli bir konteyner olalım ve (...)bir çift olsun.

Aşağıdaki girişler ve çıkışlar eşleşmelidir

{(1,4),(3,5),(5,8)} -> {[1,4,3,5,8]}
{(1,4),(3,4),(5,4),(8,5)} -> {[1,4,3,5,8]}
{(0,4),(4,5),(5,8),(7,8)} -> {[0,4,5,8,7],[7,8,5,4,0]}
{(0,2),(2,4),(4,7)} -> {[0,1,2,4,7],[1,0,2,4,7],[7,4,2,1,0]}
{(0,2),(2,6),(6,8)} -> {[0,1,2,4,6,7,8],[1,0,2,4,6,7,8],[8,7,6,4,2,1,0],[7,8,6,4,2,1,0]}
{(2,3),(3,7),(7,8)} -> {[2,3,7,8],[8,7,3,2]}
{(0,7),(1,2),(1,4),(2,7)} -> {[0,7,2,1,4],[4,1,2,7,0]}
{(0,4),(0,7),(1,3),(2,6),(2,8),(3,4),(5,7)} -> {[1,3,4,0,7,5,8,2,6]}
{(1,3),(5,8)} -> {}

Tüm test vakalarının imgur albümü resim olarak burada bulunabilir . Desenler kırmızı mavi renkte çözümler.

puanlama

Bu kod golfü. En az bayt kazanır.


1
Güzel soru, ben de aynısını özel olarak merak ediyordum. :)
ThreeFx

Bu soruyu brainflak'ta cevaplayacak mısın? Şimdi bu etkileyici olurdu. : P
DJMcMayhem

Sadece bir şekilde çözülebilen bir kalıp hangisidir? Bence okları önemsiz bir şekilde tersine çevirerek en az 2'niz olduğunu düşünüyorum.
ÜçFx

@DJMcMayhem Denerim ama hiçbir söz veremem
Buğday Sihirbazı,

Deneyin @ThreeFx bu kendin için. Zaten ziyaret edilmiş bir düğümde duramazsınız, ancak tek bir paternden geçebilirsiniz, yönsüz yapılabilir.
Buğday Sihirbazı,

Yanıtlar:


3

Python 2.7, 493 430 bayt

exec("L=['012','345','678','036','147','258','048','246'];L+=[i[::-1]IL];S=sorted;F=lambda t:''.join(str(i)It)\ndef N(x):\n s=' '.join(F(S(i))Ix)\nIL:s=s.replace(i[::2],i[:2]+' '+i[1:])\n return S(set(s.split()))\ndef P(s):\n e=0\nIL:e|=-1<s.find(i[::2])<s.find(i[1])\n return[zip(s[:-1],s[1:]),L][e]\nx=N(input());print[F(i)I__import__('itertools').permutations({iI`x`if i.isdigit()})if x==N(P(F(i)))]".replace('I',' for i in '))

Tek satır sürümü, programı exec("...".replace('I',' for i in '))tüm döngüler ve üreticiler için tek bir kısa devre yapabilecek Ive bu okunabilir sürümün üzerine 15 bayt kazandıracak şekilde sarar :

L=['012','345','678','036','147','258','048','246'];L+=[i[::-1]for i in L]
S=sorted;F=lambda t:''.join(str(i)for i in t)
def N(x):
 s=' '.join(F(S(i))for i in x)
 for i in L:s=s.replace(i[::2],i[:2]+' '+i[1:])
 return S(set(s.split()))
def P(s):
 e=0
 for i in L:e|=-1<s.find(i[::2])<s.find(i[1])
 return[zip(s[:-1],s[1:]),L][e]
x=N(input())
print[F(i)for i in __import__('itertools').permutations({i for i in`x`if i.isdigit()})if x==N(P(F(i)))]

Program girişi (örn. {(1,4),(3,4),(5,4),(8,5)}) Veya bir dize listesi (örneğin ['14','34','54','85']) (veya diğer piton dostu biçimlerde) alır ve çıktıyı dizge listesi olarak döndürür. Bu yüzden teknik olarak sipariş edilen bir konteyner sipariş edilmiş konteyner var.

İşlev, Nbir deseni normalleştirir, böylece iki desen kolayca karşılaştırılabilir. Normalleştirme, kenarları belirten çiftleri sıralar (bunun '02'yerine '20'), çift kenarları genişletmek için dize değiştirme kullanır (örneğin '02'olur '01 12'), kopyaları çıkarmak için kenarları bir kümeye böler ve sonucu sıralar.

Bu fonksiyon F, ints / string dizelerini telleri düzleştirir, böylece farklı şekillerde üretilen yolları normalleştirebiliriz.

Liste L, ekrandaki tüm satırları içerir.

Ardından normalize düzendeki tüm basamakların her permütasyonunu alırız ve geçerli bir yol hesaplarsak ya Lda geçersizse (gerçek yollar gibi çiftler listesine asla normalleşmez) ya da geçerli olduğunda sipariş düğümlerini gösteren bir çiftler listesi hesaplarız. Bu aynı düzende normalleşirse, geçerli bir çözümümüz olur ve nihai listeye ekleriz.

Ana kontrol dize kadar bir permütasyon doğrulamak için gerekli solan -1<s.find(i[::2])<s.find(i[1])bir çizgi ile bir hata tespit eden i. Örneğin, çizgi '210'ile kod oluşuyorsa bir hata tespit eder '20'(yani indeksi -1'den büyüktür) ve '1'ondan sonra gerçekleşir. Girişte olmadığından endişelenmemize gerek yok çünkü 1 normalize edilmiş şekilde girişte görünmeyecek.


NOT: Ben değiştirilmesi biliyorum str(i)for i in t ile map(str,t) ve {i for i in`x`if i.isdigit()} ile set('012345678')&set(`x`) orijinal kod daha kısa olur, ama bu yine de biraz daha uzun olduğu ikame olurdu I .


2
Falseolabilir 1<0ve üzerinde gereksiz bir boşluk var F(i) for. +1.
Yytsi

@TuukkaX Teşekkürler, bıraktığımı gördüğümde avuç içi yüzüm False.
Linus

['012','345','678','036','147','258','048','246']olabilir '012 345 678 036 147 258 048 246'.split()'için -1 bayt.
Bay Xcoder
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.