คิดออกรูปแบบการล็อค Android


26

ให้บอกว่าคุณเห็นเพื่อนของคุณป้อนรหัสผ่านของเขาหรือเธอลงในโทรศัพท์ Android ของพวกเขา คุณจำไม่ได้ว่าพวกเขาสร้างรูปแบบอย่างไร แต่คุณจำได้ว่ารูปแบบนั้นเป็นอย่างไร เป็นเพื่อนที่เกี่ยวข้องที่คุณต้องการทราบว่ารหัสผ่านของพวกเขาปลอดภัยเพียงใด งานของคุณคือการคำนวณทุกวิธีที่สามารถทำรูปแบบเฉพาะ

รูปแบบ Android ทำงานอย่างไร

รูปแบบจะถูกวาดบนตารางของโหนด 3x3 ในรูปแบบหนึ่งเข้าชมชุดของโหนดโดยไม่ต้องยกนิ้วของพวกเขาจากหน้าจอ แต่ละโหนดที่พวกเขาเยี่ยมชมเชื่อมต่อกับโหนดก่อนหน้าโดยขอบ มีกฎสองข้อที่ต้องคำนึงถึง

  • คุณไม่สามารถเยี่ยมชมหนึ่งโหนดมากกว่าหนึ่งครั้ง

  • ขอบอาจไม่ผ่านโหนดที่ไม่ได้เข้าชม

โปรดทราบว่าในขณะที่มักจะยากมากที่จะดำเนินการและจึงไม่บ่อยมากในแบบ real รวมกันล็อคหุ่นยนต์ก็เป็นไปได้ที่จะย้ายเหมือนอัศวิน นั่นคือเป็นไปได้ที่จะย้ายจากด้านหนึ่งไปยังมุมที่ไม่ติดกันหรืออีกด้านหนึ่ง นี่คือสองตัวอย่างของรูปแบบที่ใช้การเคลื่อนไหวดังกล่าว:

นี่คือGif แบบเคลื่อนไหวของมันที่กำลังแสดงอยู่

การแก้ลวดลาย

รูปแบบทั่วไปอาจมีลักษณะดังนี้:

ด้วยรูปแบบที่เรียบง่ายเช่นนี้มันมีสองวิธีที่สองวาดรูปแบบ คุณสามารถเริ่มต้นที่ปลายทั้งสองด้านใดด้านหนึ่งหลวมและเดินทางผ่านโหนดที่ถูกเน้นสีไปยังอีกด้านหนึ่ง แม้ว่าสิ่งนี้จะเป็นจริงสำหรับหลาย ๆ รูปแบบโดยเฉพาะอย่างยิ่งสิ่งที่มนุษย์ใช้โดยทั่วไปสิ่งนี้ไม่เป็นความจริงสำหรับทุกรูปแบบ

พิจารณารูปแบบต่อไปนี้:

มีสองวิธีแก้ไขปัญหาที่รู้จักได้ทันที หนึ่งเริ่มต้นที่ด้านซ้ายบน:

และเริ่มต้นที่กึ่งกลางด้านล่าง:

อย่างไรก็ตามเนื่องจากบรรทัดได้รับอนุญาตให้ผ่านจุดเมื่อมีการเลือกแล้วมีรูปแบบเพิ่มเติมที่เริ่มต้นที่ตรงกลางด้านบน:

รูปแบบนี้โดยเฉพาะมี 3 รูปแบบการแก้ปัญหา แต่จะมีที่ใดก็ได้ระหว่าง 1 และ 4 โซลูชั่น[อ้างจำเป็น]

นี่คือตัวอย่างของแต่ละรายการ:

1

2

3

4

I / O

โหนดสามารถแสดงเป็นจำนวนเต็มตั้งแต่ศูนย์ถึงเก้ารวมถึงสตริงเทียบเท่าหรืออักขระจาก 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)} -> {}

Imgur อัลบั้มของทุกกรณีทดสอบเป็นภาพที่สามารถพบได้ที่นี่ รูปแบบที่อยู่ในการแก้ปัญหาสีฟ้าเป็นสีแดง

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟ ไบต์ที่น้อยที่สุดจะเป็นผู้ชนะ


1
คำถามที่ดีฉันมักจะสงสัยเหมือนกันในที่ส่วนตัว :)
ThreeFx

คุณจะตอบคำถามนี้ด้วยการใช้สมองไหม? ตอนนี้ที่จะเป็นที่น่าประทับใจ : P
DJMcMayhem

รูปแบบใดที่สามารถแก้ไขได้ทางเดียวเท่านั้น ฉันคิดว่าคุณมีอย่างน้อย 2 เพียงแค่สลับลูกศรไปเล็กน้อย
ThreeFx

@DJMcMayhem ฉันจะลอง แต่ฉันไม่สามารถทำสัญญาใด ๆ ได้
Wheat Wizard

@ThreeFx ลองนี้หนึ่งสำหรับตัวเอง เนื่องจากคุณไม่สามารถหยุดที่โหนดที่เคยไปแล้ว แต่คุณสามารถผ่านหนึ่งรูปแบบสามารถกำหนดทิศทางได้
ตัวช่วยสร้างข้าวสาลี

คำตอบ:


3

Python 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 และตัวกำเนิดทั้งหมดสามารถ shorted ด้วย single 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จะทำให้ tuples ของ ints / strings เป็นสตริงดังนั้นเราจึงสามารถทำให้เส้นทางปกติที่ผลิตในรูปแบบที่แตกต่างกัน

รายการLมีทุกบรรทัดบนหน้าจอ

จากนั้นเราใช้การเปลี่ยนแปลงของตัวเลขทั้งหมดในรูปแบบที่ทำให้เป็นมาตรฐานและคำนวณเส้นทางที่ถูกต้องหรือLถ้าไม่ถูกต้อง (ซึ่งไม่เคยทำให้รายการคู่เหมือนปกติเหมือนเส้นทางจริง) หรือรายการของคู่ที่บ่งชี้ว่าโหนดลำดับนั้นถูกเยี่ยมชมถ้าถูกต้อง หากนี่เป็นการทำให้รูปแบบเดียวกันเป็นปกติเรามีวิธีการแก้ไขที่ถูกต้องและรวมไว้ในรายการสุดท้าย

การตรวจสอบหลักที่จำเป็นในการตรวจสอบการเปลี่ยนแปลงเป็นสตริงsเป็นซึ่งตรวจพบข้อผิดพลาดด้วยเส้น-1<s.find(i[::2])<s.find(i[1]) iเช่นกับบรรทัด'210'รหัสตรวจพบข้อผิดพลาดหาก'20'เกิดขึ้น (เช่นดัชนีของมันมากกว่า -1) และ'1'เกิดขึ้นหลังจากนั้น เราไม่ต้องกังวลกับ 1 ที่ไม่เกิดขึ้นเพราะ 1 จะปรากฏในรูปแบบปกติเมื่อไม่ได้อยู่ในอินพุต


หมายเหตุ:ฉันรู้ว่าการแทนที่ str(i)for i in t ด้วย map(str,t) และ {i for i in`x`if i.isdigit()} ด้วย set('012345678')&set(`x`) จะทำให้รหัสต้นฉบับสั้นลง แต่สิ่งนี้จะยังคงนานกว่าการทดแทน Iเล็กน้อย


2
Falseอาจจะเป็นและมีช่องว่างที่ไร้ประโยชน์1<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.