Màn hình khóa Android


25

Giới thiệu

Bạn đang ngồi trong một phòng hội đồng ở cuối một cái bàn dài. Bạn nhìn xung quanh và thấy Tim Cook, Hội đồng quản trị Apple, hồn ma của Steve Jobs và Jack Donaghy. Apple đã gọi cuộc họp này vì họ đã nhận ra màn hình khóa Android mát hơn bao nhiêu và họ muốn 1-UP chúng. Mọi người trong phòng nhìn chằm chằm vào bạn khi Ghost Steve khóc, "Giúp tôi với, CodeGolf Man! Bạn là hy vọng duy nhất của tôi!"

Vấn đề

Màn hình khóa Android là một lưới 3 x 3 chấm có thể được kết nối bằng cách vuốt một ngón tay từ một chấm sang điểm tiếp theo, tạo ra một đường dẫn. Mật khẩu được coi là bất kỳ đường dẫn có thể bao gồm bất kỳ số lượng dấu chấm nào và không bao gồm bất kỳ số lượng dấu chấm nào. (Trên điện thoại thực tế, đường dẫn phải dài ít nhất 4 chấm. Đối với thử thách này, hãy bỏ qua hạn chế đó.) Apple có kế hoạch thay thế lưới 3 x 3 bằng lưới M x N, đó là (M * N) / 9 lần tốt hơn!

Quy tắc:

  • Đường dẫn dấu chấm không phải là mật khẩu, nhưng đường dẫn 1 chấm là
  • Một con đường có thể tự đi qua
  • Một đường dẫn không thể giao nhau trực tiếp trên một dấu chấm mà không bao gồm dấu chấm đó
  • Một dấu chấm chỉ có thể được sử dụng một lần
  • Các đường dẫn giống hệt nhau bằng cách xoay không cùng một mật khẩu
  • Các đường dẫn giống hệt nhau nhưng được sắp xếp ngược lại không cùng mật khẩu
  • Ví dụ: trên lưới 3x3 có các chấm được đánh số từ 1 đến 9:

    1 2 3
    4 5 6
    7 8 9
    

    Một số đường dẫn hợp lệ là:

    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
    

    Và một số đường dẫn không hợp lệ là:

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

    Đầu vào của bạn sẽ là ba số:

    (M,N,d)
    

    Trong đó lưới là M x N và d là chiều dài của đường dẫn

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

    Chương trình hoặc hàm của bạn sẽ được cung cấp đầu vào dưới dạng một chuỗi được phân tách bằng dấu phẩy và nó phải trả về số lượng mật khẩu có thể có của độ dài đó. Ví dụ:

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

    Quy tắc golf tiêu chuẩn áp dụng, chiến thắng mã ngắn nhất!

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

    2
    Đầu vào là một chuỗi được phân tách bằng dấu phẩy hoặc ba tham số riêng biệt?
    dùng80551

    1
    @ user80551 Dựa trên ngữ cảnh, tôi nghĩ nó sẽ là một chuỗi nếu nó được nhập vào một chương trình hoặc tách các tham số nếu nó được sử dụng để gọi hàm.
    dùng12205

    1
    @Platatat bạn có thể vui lòng trả lời câu hỏi của user80551 không, vì điều này thực sự quan trọng để thiết kế mã
    RononDex

    3
    Bạn nên quyết định xem sẽ có giới hạn thời gian cho cả thời gian biên dịch và thời gian thực hiện của một giải pháp nhất định hay không. Không có giới hạn như vậy, thật dễ dàng để viết một chương trình, theo lý thuyết, xác minh xem tất cả các 256!hoán vị của các chấm trên lưới 16 x 16 đại diện cho mẫu mở khóa hợp lệ. Trong thực tế, một chương trình như vậy sẽ không bao giờ chấm dứt.
    Dennis

    3
    Nhưng tôi đã nói vấn đề này dựa trên hệ thống khóa android ... Vậy tại sao tôi không nên sử dụng các quy tắc giống như hệ thống khóa Android?
    Platatat

    Câu trả lời:


    14

    Python - 170 byte

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

    Tôi nhận ra rằng các dấu ngoặc bên trong sum([...])không thực sự cần thiết, nhưng có một hình phạt hiệu suất lớn vì không bao gồm chúng.

    Đầu ra cho tất cả 3x3:

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

    Sản xuất:

    1624
    7152
    26016
    72912
    140704
    140704
    

    Đối với mục đích thử nghiệm / xác nhận, 6 giá trị đầu tiên cho bảng 4x5:

    20
    262
    3280
    39644
    459764
    5101232
    

    4x5 là một trường hợp thú vị để xác minh, bởi vì nó có các lần nhảy chốt 2x2, 3x3 và 2x4.


    Giải thích ngắn gọn

    Nói chung, đây là một tìm kiếm toàn diện, với việc cắt tỉa tích lũy. Ví dụ: vì p(3, 3, 4)là 1624, p(3, 3, 5)sẽ chỉ kiểm tra 8120 tính tích cực, thay vì kiểm tra một cách ngây thơ tất cả 15120. Hầu hết logic được chứa trong điều kiệ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))
    

    Trong tiếng Anh đơn giản, điều này có thể được hiểu là:

    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
    Bạn có thể giải thích những gì trên thế giới đang xảy ra ở đây?
    ɐɔıʇǝɥʇuʎs

    1
    Bạn có thể lưu một vài byte bằng cách sđặt một tập hợp thay vì một danh sách. Tôi không thấy hình phạt hiệu suất lớn của việc bỏ dấu ngoặc; Tại sao sẽ có một hình phạt như vậy?
    user2357112 hỗ trợ Monica

    1
    @ user2357112 một cái đang tóm tắt trên một Trình tạo, cái còn lại trên Danh sách. Với CPython, bạn nói đúng, không có nhiều khác biệt (chỉ chậm hơn khoảng 20%). Với PyPy, nó chậm hơn 5 lần.
    primo

    1
    @ user2357112 Cuối cùng tôi cũng hiểu ý của bạn bằng cách định nghĩa slà một tập hợp. Bài học python của tôi cho ngày hôm nay: {i}đánh giá như set([i]). Tôi đã mong đợi một lỗi cú pháp. Việc thêm một mục vào một tập hợp sau đó trở thành s|{i}và nó cũng cho phép i in sđược thay thế bằng s&{i}.
    primo
    Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.