Schermata di blocco Android


25

Intro

Sei seduto in una sala riunioni alla fine di un lungo tavolo. Ti guardi intorno e vedi Tim Cook, il Consiglio di amministrazione di Apple, il fantasma di Steve Jobs e Jack Donaghy. Apple ha convocato questo incontro perché si sono resi conto di quanto sia più interessante la schermata di blocco di Android e vogliono 1-UP. Tutti nella stanza ti fissano mentre Ghost Steve piange, "Aiutami, CodeGolf Man! Sei la mia unica speranza!"

Il problema

La schermata di blocco di Android è una griglia 3 x 3 di punti che può essere collegata facendo scorrere un dito da un punto all'altro, creando un percorso. Una password è considerata ogni possibile percorso che include un numero qualsiasi di punti ed esclude qualsiasi numero di punti. (Su un telefono reale, il percorso deve essere lungo almeno 4 punti. Per questa sfida, ignora quella restrizione.) Apple prevede di sostituire la griglia 3 x 3 con una griglia M x N, che è (M * N) / 9 volte meglio!

Regole:

  • Un percorso punto zero non è una password, ma un percorso punto 1 lo è
  • Un percorso può attraversare se stesso
  • Un percorso non può attraversare direttamente un punto senza includerlo
  • Un punto può essere utilizzato solo una volta
  • I percorsi identici per rotazione non sono la stessa password
  • I percorsi identici ma ordinati al contrario non sono la stessa password
  • Ad esempio, su una griglia 3x3 con punti numerati da 1 a 9:

    1 2 3
    4 5 6
    7 8 9
    

    Alcuni percorsi validi sono:

    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
    

    E alcuni percorsi non validi sono:

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

    Il tuo input sarà di tre numeri:

    (M,N,d)
    

    Dove la griglia è M x N e d è la lunghezza del percorso

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

    Al programma o alla funzione verrà fornito l'input come stringa separata da virgola e deve restituire il numero di possibili password di quella lunghezza. Per esempio:

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

    Si applicano le regole standard del codice golf, vince il codice più corto!

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

    2
    L'input è una stringa separata da virgola o tre parametri separati?
    user80551

    1
    @ user80551 In base al contesto, penso che sarà una stringa se viene immesso in un programma o parametri separati se viene utilizzato per chiamare la funzione.
    user12205

    1
    @Platatat, per favore, puoi rispondere alla domanda di user80551, poiché questo è davvero importante per progettare il codice
    RononDex

    3
    Dovresti decidere se ci sarà un limite di tempo sia per la compilazione che per il tempo di esecuzione di una determinata soluzione. Senza tale limite, è facile scrivere un programma che, in teoria, verifica quale di tutte le 256!permutazioni dei punti sulla griglia 16 x 16 rappresentano un modello di sblocco valido. In pratica, un tale programma non si sarebbe mai concluso.
    Dennis,

    3
    Ma ho detto che il problema era basato sul sistema di blocco Android ... Quindi perché non dovrei usare le stesse regole del sistema di blocco Android?
    Platatat,

    Risposte:


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

    Mi rendo conto che le parentesi all'interno sum([...])non sono strettamente necessarie, ma c'è una grande penalità prestazionale per non includerle.

    Uscita per tutti i 3x3:

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

    produce:

    1624
    7152
    26016
    72912
    140704
    140704
    

    A scopo di test / conferma, i primi 6 valori per una scheda 4x5:

    20
    262
    3280
    39644
    459764
    5101232
    

    Il 4x5 è un caso interessante da verificare, perché ha salti di picchetti 2x2, 3x3 e 2x4.


    Breve spiegazione

    In generale, questa è una ricerca esaustiva, con potatura cumulativa. Ad esempio, poiché p(3, 3, 4)è 1624, p(3, 3, 5)controllerà solo 8120 possibilità, anziché controllare ingenuamente tutti i 15120. La maggior parte della logica è contenuta nella condizione:

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

    In parole povere, questo può essere inteso come:

    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
    Potresti spiegare cosa sta succedendo nel mondo qui?
    Aprıʇǝɥʇuʎs

    1
    È possibile salvare alcuni byte essendo sun set anziché un elenco. Non vedo la grande penalità prestazionale di far cadere le parentesi; perché dovrebbe esserci una sanzione del genere?
    user2357112 supporta Monica

    1
    @ user2357112 uno sta sommando un generatore, l'altro sopra un elenco. Con CPython, hai ragione, non c'è molta differenza (solo circa il 20% più lento). Con PyPy, è oltre 5 volte più lento.
    primo

    1
    @ user2357112 Finalmente capisco cosa intendevi definendo sun set. La mia lezione di pitone per oggi: {i}valuta come set([i]). Mi sarei aspettato un errore di sintassi. L'aggiunta di un elemento a un set diventa quindi s|{i}e consente anche i in sdi essere sostituito da s&{i}.
    primo
    Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
    Licensed under cc by-sa 3.0 with attribution required.