안드로이드 잠금 패턴 파악


26

친구가 자신의 Android 휴대 전화에 비밀번호를 입력하는 것을 보았습니다. 패턴을 어떻게 만들 었는지 기억하지 못하지만 패턴이 어떻게 생겼는지 기억합니다. 관심있는 친구이기 때문에 자신의 암호가 얼마나 안전한지 알고 싶습니다. 당신의 임무는 특정 패턴을 만들 수있는 모든 방법을 계산하는 것입니다.

안드로이드 패턴 작동 방식

패턴은 3x3 그리드 노드에 그려집니다. 패턴에서 하나는 화면에서 손가락을 떼지 않고 일련의 노드를 방문합니다. 그들이 방문하는 각 노드는 에지에 의해 이전 노드에 연결됩니다. 명심해야 할 두 가지 규칙이 있습니다.

  • 한 노드를 두 번 이상 방문 할 수 없습니다

  • 에지가 방문하지 않은 노드를 통과하지 못할 수 있습니다

실제 안드로이드 잠금 조합에서는 일반적으로 수행하기가 어렵고 그리 일반적이지 않지만 Knight 처럼 이동할 수 있습니다. 즉, 한쪽에서 인접하지 않은 모서리로 또는 다른 방향으로 이동할 수 있습니다. 이러한 이동을 사용하는 패턴의 두 가지 예는 다음과 같습니다.

다음은 애니메이션 GIF 입니다.

패턴 해결

일반적인 패턴은 다음과 같습니다.

이와 같은 간단한 패턴으로 두 가지 방법으로 패턴을 그릴 수 있습니다. 두 느슨한 끝 중 하나에서 시작하여 강조 표시된 노드를 통해 다른 끝으로 이동할 수 있습니다. 많은 패턴, 특히 인간이 일반적으로 사용하는 패턴에 대해서는 이것이 사실이지만 모든 패턴에 대해 이것이 사실은 아닙니다.

다음 패턴을 고려하십시오.

즉시 인식 가능한 두 가지 솔루션이 있습니다. 왼쪽 상단에서 시작하는 것 :

그리고 하나는 하단 중앙에서 시작합니다.

그러나 선이 이미 선택된 지점을 통과 할 수 있기 때문에 상단 가운데에서 시작하는 추가 패턴이 있습니다.

이 특정 패턴은 3 해법이 있지만 패턴 사이 어딘가에 1 개 4의 솔루션을 가질 수있다 [표창장] .

각각의 예는 다음과 같습니다.

1.

2.

삼.

4.

I / O

노드는 0에서 9까지의 정수, 해당 문자열 또는 a에서 i까지 (또는 A에서 I까지)의 정수로 표시 될 수 있습니다. 각 노드는이 세트 중 하나에서 고유 한 표현을 가져야합니다.

솔루션은 노드 표현이 포함 된 정렬 된 컨테이너로 표시됩니다. 노드는 전달 된 순서와 동일한 순서로 주문해야합니다.

패턴은 노드 쌍의 정렬되지 않은 컨테이너로 표시됩니다. 각 쌍은 쌍의 두 점을 연결하는 모서리를 나타냅니다. 패턴 표현은 고유하지 않습니다.

표준 입력 방법을 통해 패턴 표현을 입력으로 사용하고 표준 출력 방법을 통해 동일한 패턴을 만드는 가능한 모든 솔루션을 출력합니다.

각 입력에 하나 이상의 솔루션이 있고 4 개 이상의 노드를 연결한다고 가정 할 수 있습니다.

언어 선택에 의해 원하거나 강요된 경우 순서가없는 컨테이너 대신 순서가 지정된 컨테이너를 사용하도록 선택할 수 있습니다.

테스트 사례

노드는 다음 패턴으로 배열됩니다.

0 1 2
3 4 5
6 7 8

하자 {...}정렬되지 않은 컨테이너 수, [...]주문 용기, 그리고 (...)한 쌍의 수.

다음 입력 및 출력이 일치해야합니다

{(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)} -> {}

그림으로 모든 테스트 사례의 이미지 앨범은 여기 에서 찾을 수 있습니다 . 패턴은 파란색으로 파란색으로 표시됩니다.

채점

이것은 코드 골프입니다. 가장 적은 바이트가 이깁니다.


1
좋은 질문, 나는 종종 개인적으로 같은 것을 궁금해했다. :)
ThreeFx

당신은 brainflak에서 이것에 대답 할 것입니까? 이제 감동이 될 것입니다. : P
DJMcMayhem

한 가지 방법으로 만 해결할 수있는 패턴은 무엇입니까? 나는 당신이 화살을 사소하게 뒤집어서 적어도 2를 가지고 있다고 생각합니다.
ThreeFx

@DJMcMayhem 나는 시도하지만 약속을 할 수 없습니다
Wheat Wizard

시도 @ThreeFx 자신을 위해 하나. 이미 방문한 노드에서 멈출 수는 없지만 하나의 패턴을 통과 할 수 있으므로 방향성을 지정할 수 있습니다.
밀 마법사

답변:


3

파이썬 2.7, 493 430 바이트

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

단일 라인 버전은 프로그램을 래핑하여 exec("...".replace('I',' for i in '))모든 for-loops 및 생성기가 단일로 단락 될 수 있고이 I읽기 쉬운 버전보다 15 바이트를 절약합니다.

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

프로그램은 표시된 방식 (예 :) {(1,4),(3,4),(5,4),(8,5)}또는 문자열 목록 (예 ['14','34','54','85']:) (또는 다른 파이썬 친화적 형식)으로 입력을 받아 출력을 문자열 목록으로 반환합니다. 따라서 기술적으로 주문 된 컨테이너로 구성된 주문 된 컨테이너가 있습니다.

이 기능 N은 패턴을 정규화하여 두 패턴을 쉽게 비교할 수 있습니다. 정규화는을 '02'대신하여 모서리를 나타내는 쌍을 정렬하고 '20', 문자열 교체를 사용하여 이중 모서리를 확장하고 (예 : '02'가 됨 '01 12') 모서리를 세트로 분할하여 중복을 제거하고 결과를 정렬합니다.

이 함수 F는 int / string의 튜플을 문자열로 평탄화하여 다른 방식으로 생성 된 경로를 정규화 할 수 있습니다.

목록 L에는 화면의 모든 줄이 포함됩니다.

그런 다음 정규화 된 패턴으로 모든 숫자의 각 순열을 취하여 유효한 경로를 계산하거나 유효 L하지 않은 경우 (실제 경로와 같이 쌍 목록으로 정규화되지 않음) 또는 유효한 경우 주문 노드가 방문했음을 나타내는 쌍 목록을 계산합니다. 이것이 동일한 패턴으로 정규화되면 유효한 솔루션이 있으며 최종 목록에 포함시킵니다.

주 검사 문자열로 순열 검증에 필요한 s-1<s.find(i[::2])<s.find(i[1])선에 에러를 검출하는 i. 예를 들어, 줄 '210'이 있으면 코드는 오류가 '20'발생 하면 (즉, 인덱스가 -1보다 큰 경우) 오류를 감지하고 그 '1'후에 발생합니다. 1이 입력에 없을 때 정규화 된 패턴으로 표시되므로 1이 발생하지 않을 것에 대해 걱정할 필요가 없습니다.


참고 : with with를 바꾸면 원래 코드가 더 짧아 지지만 대체하는 것보다 약간 더 길 것입니다 .str(i)for i in t map(str,t) {i for i in`x`if i.isdigit()} set('012345678')&set(`x`) I


2
False1<0쓸모없는 공백이있을 수 있습니다 F(i) for. +1.
Yytsi

@TuukkaX 고마워, 내가 떠났을 때 나는 손바닥에 부딪쳤다 False.
Linus

['012','345','678','036','147','258','048','246']'012 345 678 036 147 258 048 246'.split()'-1 바이트 일 수 있습니다 .
Mr. Xcoder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.