My Swipe Pattern è legale?


154

La maggior parte degli smartphone Android consente all'utente di utilizzare una sequenza di scorrimento per aprire il proprio telefono:

serratura a combinazione

Alcuni modelli sono legittimi e altri sono impossibili. Dato un modello di scorrimento dell'input, restituire un valore di verità o errato che indica se il modello di input specificato è legale o meno.

Ingresso

La griglia è etichettata per riga da 1 a 9:

1 2 3   
4 5 6   
7 8 9

L'input è un numero composto dai nodi visitati dal primo all'ultimo. Ad esempio, il modello di scorrimento sopra è 12357.

L'input può essere un numero decimale, una stringa o un elenco di numeri. Non conterrà 0 perché non esiste un nodo 0.

Modifica: l'indicizzazione 0-8 è consentita poiché molte lingue indicizzano da 0. Se si utilizza 0-8, sarà necessario indicare come tale all'inizio della risposta e modificare i casi di test di conseguenza.

Regole

  • Ogni nodo inizia inizialmente come non visitato e può essere visitato solo una volta. Qualsiasi modello che visita un nodo più di una volta è falso.

  • Un modello veritiero deve contenere almeno un colpo, quindi almeno 2 nodi.

  • Non è possibile saltare un nodo non visitato direttamente in linea con un altro. Ad esempio, 13 è falso perché 2 non è consigliato e direttamente in linea.

  • È possibile saltare solo su un nodo visitato. 42631 ne è un esempio.

  • Le linee potrebbero incrociarsi altrimenti. Ad esempio, il 1524 è vero.

  • Supponiamo che le larghezze dei nodi siano insignificanti e ignorino i problemi pratici (spessore delle dita, ecc.). Quindi il 16 è vero anche se in realtà potrebbe essere leggermente più difficile da raggiungere.

Casi test

1 -> false     
12 -> true   
13 -> false   
16 -> true  
31 -> false   
33 -> false  
137 -> false   
582 -> true  
519 -> true  
1541 -> false  
12357 -> true    
15782 -> true   
19735 -> false  
42631 -> true   
157842 -> true  
167294385 -> true   
297381645 -> false   
294381675 -> true

Questo è , quindi vince il minor numero di byte.




L'elenco di input è garantito non vuoto?
Zgarb,

@Zgarb sì. Sarà vuoto.
Stanari,

Domanda di matematica correlata: math.stackexchange.com/questions/205049/…
Pureferret

Risposte:


69

JavaScript (ES6), 64 byte

Accetta input come una matrice di numeri. I valori falsi sono 0 o NaN . I valori di verità sono numeri interi assolutamente positivi.

a=>a[p=1]*a.every(n=>a[p=a[n&p&p*n%5<0|~(p-=n)==9&&p/2]&&-n]^=p)

Casi test

Come?

Preambolo

Due cifre si contrappongono verticalmente, orizzontalmente o diagonalmente se:

  • sono entrambi dispari, diversi l'uno dall'altro e diversi da 5 (figura 1)
  • O sono entrambi pari e la loro somma è 10 (figura 2)

    cifre contrapposte

Inoltre, la cifra tra due cifre opposte n e p è uguale a (n + p) / 2 .

Codice sorgente formattato

a =>
  // force a falsy result if a[1] is undefined
  a[p = 1] *
  // walk through all values n in a[]
  a.every(n =>
    // access either a[-n] or a[undefined]
    a[
      // set p to either -n or undefined
      p =
        // read either a[0] or a[in_between_digit]
        a[
          n & p & p * n % 5 < 0 | ~(p -= n) == 9
          && p / 2
        ]
        && -n
    ]
    // toggle the flag
    ^= p
  )

Tenere traccia delle cifre precedenti

I flag per le cifre visitate sono memorizzati in indici negativi nella matrice di input a , in modo che non si scontrino con i suoi elementi originali.

  • Se p è impostato su -n :

    Se la cifra corrente n non è stata precedentemente selezionata, a[-n] ^= -nimposterà il flag e lascerà che il every()ciclo continui con la successiva iterazione. Altrimenti, cancellerà la bandiera e forzerà immediatamente il loop a fallire.

  • Se p è impostato su indefinito :

    a[undefined] ^= undefinedgenera 0 , che forza anche il fallimento del loop.

Rilevamento di cifre contrapposte

La seguente espressione viene utilizzata per verificare se la cifra corrente n e la cifra precedente -p sono cifre contrapposte, come definito nel preambolo:

n & p & ((p * n) % 5 < 0) | ~(p -= n) == 9

che equivale a:

n & p & ((p * n) % 5 < 0) | (p -= n) == -10

Nota: in JS, il risultato del modulo ha lo stesso segno del dividendo.

Può essere interpretato come:

(n is odd AND -p is odd AND (neither -p or n is equal to 5)) OR (n + -p = 10)

Pertanto, questa espressione restituisce 1 se e solo se n e -p sono cifre contrapposte o hanno la stessa cifra dispari. Poiché una cifra non può essere selezionata due volte, quest'ultimo caso viene comunque risolto correttamente.

Se questa espressione restituisce 1 , testiamo un [p / 2] (dove p è ora uguale alla somma negata delle cifre) per sapere se la "cifra intermedia" è stata precedentemente visitata. Altrimenti, testiamo uno [0] che è garantito per essere vero.

Informazioni sulla prima iterazione

La prima iterazione è un caso speciale, in quanto non esiste una cifra precedente e vogliamo che abbia successo incondizionatamente.

Lo raggiungiamo inizializzando p su 1 , perché per qualsiasi n in [1 .. 9] :

  • (1 * n) % 5 non può essere negativo
  • ~(1 - n) non può essere uguale a 9

Risposta originale, 90 byte

Rimosso da questo post in modo che non sia troppo dettagliato. Puoi vederlo qui .


-1 byte sostituendo !!a[1]&con a[1]&&, poiché può essere restituito qualsiasi valore di verità
Herman L

@HermanLauenstein Grazie, sembra davvero OK. (Ora a[1]*è ancora più breve.)
Arnauld,

1
Stavo disperatamente cercando di pensare a una formula per has a node directly in line, non mi rendevo conto che sarebbe stato così semplice ...
Neil,

@Neil Guardando la cronologia delle revisioni di questo post, sono sicuro che puoi dire che non me ne sono reso conto neanche immediatamente ... :)
Arnauld,

Pensi di poter sostituire ?a[-n]^=1:0con &&a[-n]^=1per -1, non puoi testare (su cellulare)
Stan Strum,

45

x86 codice macchina a 32 bit, 62 60 byte

hexdump:

33 c0 60 8b f2 33 db 99 80 f9 02 72 2d ad 50 0f
ab c2 72 25 3b c3 77 01 93 2b c3 d1 e8 72 14 68
92 08 0e 02 0f a3 5c 04 ff 5f 73 07 03 d8 0f a3
da 73 06 5b e2 d7 61 40 c3 58 61 c3

Riceve la lunghezza dell'elenco in ecxe un puntatore al primo elemento in edxe restituisce il risultato in al:

__declspec(naked) bool __fastcall check(int length, const int* list)

Esistono 8 righe che contengono un nodo nel mezzo:

1 - 3
4 - 6
7 - 9
1 - 7
2 - 8
3 - 9
1 - 9
3 - 7

Li ho raggruppati in base alla differenza tra il numero più grande e quello più piccolo.

Differenza 2: 3 righe (a partire da 1, 4 o 7)
    1 - 3
    4 - 6
    7 - 9
Differenza 4: 1 linea (a partire da 3)
    3 - 7
Differenza 6: 3 righe (a partire da 1, 2 o 3)
    1 - 7
    2 - 8
    3 - 9
Differenza 8: 1 linea (a partire da 1)
    1 - 9

Quindi, l'ho convertito in una tabella di ricerca 2D indicizzata per mezzo di differenza e numero più piccolo:

76543210
--------
10010010 - half-difference 1
00001000 - half-difference 2
00001110 - half-difference 3
00000010 - half-difference 4

Questo crea una bitmap "magica" di 32 bit. Per indicizzarlo, il codice lo inserisce nello stack. Quindi estrae un byte usando un indice e da quel byte estrae un bit usando l'altro indice. Tutto questo usando un'istruzione:

bt byte ptr [esp + eax - 1], ebx; // -1 because half-difference is 1-based

Se la bitmap indica che c'è un nodo nel mezzo, è facile da calcolare: aggiungi metà della differenza al numero più piccolo.

Fonte di assemblaggio:

    xor eax, eax;   // prepare to return false
    pushad;         // save all registers
    mov esi, edx;   // esi = pointer to input list
    xor ebx, ebx;   // ebx = previously encountered number = 0
    cdq;            // edx = bitmap of visited numbers = 0

    cmp cl, 2;      // is input list too short?
    jb bad_no_pop;  // bad!

again:
    lodsd;          // read one number
    push eax;

    bts edx, eax;   // check and update the bitmap
    jc bad;         // same number twice? - bad!

    cmp eax, ebx;   // sort two recent numbers (ebx = minimum)
    ja skip1;
    xchg eax, ebx;
skip1:

    // Check whether the line crosses a node
    sub eax, ebx;   // calculate half the difference
    shr eax, 1;
    jc skip_cross;  // odd difference? - no node in the middle

    push 0x020e0892;// push magic bitmap onto stack
    bt byte ptr [esp + eax - 1], ebx; // is there a node in the middle?
    pop edi;
    jnc skip_cross; // no - skip the check

    add ebx, eax;   // calculate the node in the middle
    bt edx, ebx;    // was it visited?
    jnc bad;        // no - bad!

skip_cross:
    pop ebx;
    loop again;

    // The loop was finished normally - return true
    popad;          // restore registers
    inc eax;        // change 0 to 1
    ret;            // return

    // Return false
bad:
    pop eax;        // discard data on stack
bad_no_pop:
    popad;          // restore registers
    ret;            // return

Bello! Mi piace molto questo bt byte ptr [esp + eax], ebx.
Arnauld,

5
Bello vedere la soluzione di assemblaggio :) Puoi usare al cdqposto di xor edx, edxas eaxis zero. Inoltre, si può piegare la dec eaxin bt [esp + eax - 1], ebxcui è stessa lunghezza, ma poi consente di rimuovere il inc ebxpiù tardi. Questo dovrebbe farti risparmiare due byte.
Giullare

Grazie per le idee! Hai assicurato il tuo posto nel paradiso del golfista, se ce n'è uno :)
Anatolyg

5
Penso che possiamo essere tutti d'accordo sul fatto che il paradiso dei golfisti è un inferno per tutti gli altri.
Adonalsium,

19

Python 2 , 140 131 114 104 99 byte

-2 byte grazie a Jonathan Frech
-5 byte grazie a Chas Brown

v={0};k=input()
for l,n in zip(k,k[1:])or q:(2**n+~2**l)%21%15%9==5<v-{l+n>>1}==v>q;v|={l};n in v>q

Provalo online!

Spiegazione:

# full program, raising a NameError for invalid input
v={0}            # set of visited nodes
k=input()        # load pattern
# iterate through adjacent pairs, if there is no pair, raise a NameError
for l,n in zip(k,k[1:])or q:
  # detect moves skipping over nodes, details below
  (2**n + ~2**l) % 21 % 15 % 9 == 5 < v - {l+n >> 1} == v > q
  v |= {l}       # add the last node to the set of visited nodes
  n in v > q     # if the current node was previously visited, raise a NameError

Provalo online!

Solo 8 coppie di nodi hanno un nodo tra di loro. Una coppia di nodi può essere rappresentata come un singolo numero intero dalla formula 2^a-2^b-1. Questo numero può essere abbreviato da modulo ripetuto:

a  b  2^a-2^b-1  (2^a-2^b-1)%21%15%9
1  3         -7                    5
1  7       -127                    5
1  9       -511                    5
2  8       -253                    5
3  1          5                    5
3  7       -121                    5
3  9       -505                    5
4  6        -49                    5
6  4         47                    5
7  1        125                    5
7  3        119                    5
7  9       -385                    5
8  2        251                    5
9  1        509                    5
9  3        503                    5
9  7        383                    5

(2**n+~2**l)%21%15%9==5controlla innanzitutto se tale coppia è presente, quindi v-{l+n>>1}==vverifica se il nodo in mezzo, che è dato da (a+b)/2, non è stato ancora visitato e qgenera un NameError. Utilizzando il confronto incatenato tra queste coppie, il confronto successivo viene eseguito solo quando viene restituito il precedente True.


17

Gelatina ,  24 22 19  18 byte

-2 poiché non è più necessario gestire un elenco vuoto
-1 passando da join, j@per concatenare ;(l'elemento mancante non deve essere incontrato nel mezzo per il metodo impiegato, essendo all'inizio del trio va bene )
-2 passando da P¬aSHa oSH(OK per avere due risultati da quando abbiamo appiattito, la metà di 1è 0.5comunque filtrata e avere risultati uguali multipli non ha alcun effetto sul metodo utilizzato)
-1 Grazie a Mr. Xcoder (indicizzato 0 input consentito)

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼

Un collegamento monadico che prende un elenco di numeri interi [0,8]e restituisce un valore di verità ( 1) se legale e un valore di falsa ( 0) in caso contrario.

Provalo online! o vedere una suite di test .

Come?

Guarda ciascuna coppia adiacente di nodi indicizzati 0 nell'elenco di input. Se la divisione intera per tre dei due differisce per 2 sono nelle righe superiore e inferiore, se il modulo per tre dei due differisce per 2 si trovano nelle colonne sinistra e destra. La somma di tali coppie divise per due è il nodo medio indicizzato 0 di una linea a tre nodi o un valore non intero - quindi questi valori vengono prima inseriti davanti alla coppia indicizzata 0 e quindi qualsiasi nodi fasulli (come 0.5o3.5) vengono rimossi, l'elenco risultante di elenchi viene appiattito e quindi duplicato (per produrre voci univoche conservate nell'ordine) e infine confrontato con l'input: per un colpo legale tutto questo finirà per essere una non-operazione mentre illegale quelli aggiungeranno nodi intermedi mancanti e / o rimuoveranno nodi duplicati (si noti che non è necessario un involucro speciale per un elenco di input di lunghezza 1 poiché non ha coppie adiacenti):

d3ZIỊoSH;µƝFf9Ḷ¤Q⁼ - left input is a list of integers   e.g. [3,4,7,1,2,8,3]
          µƝ       - perform the chain to the left for adjacent pairs:
                   - e.g. for [a,b] in:   [3,4]         [4,7]         [7,1]         [1,2]         [2,8]         [8,3]
 d3                -   divmod by 3        [[1,0],[1,1]] [[1,1],[2,1]] [[2,1],[0,1]] [[0,1],[0,2]] [[0,2],[2,2]] [[2,2],[1,0]]
   Z               -   transpose          [[1,1],[0,1]] [[1,2],[1,1]] [[2,0],[1,1]] [[0,0],[1,2]] [[0,2],[2,2]] [[2,1],[2,0]]
    I              -   differences        [0,1]         [1,0]         [-2,0]        [0,1]         [2,0]         [-1,-2]
     Ị             -   abs(v)<=1          [1,1]         [1,1]         [0,1]         [1,1]         [0,1]         [1,0]
       S           -   sum (of [a,b])      7            11            8              3            10            11
      o            -   OR (vectorises)    [1,1]         [1,1]         [8,1]         [1,1]         [10,1]        [1,11]
        H          -   halve (vectorises) [0.5,0.5]     [0.5,0.5]     [4,0.5]       [0.5,0.5]     [5,0.5]       [0.5,5.5]
         ;         -   concatenate        [0.5,0.5,3,4] [0.5,0.5,4,7] [4,0.5,7,1]   [0.5,0.5,1,2] [5,0.5,2,8]   [0.5,5.5,8,3]
            F      - flatten              [0.5,0.5,3,4,  0.5,0.5,4,7,  4,0.5,7,1,    0.5,0.5,1,2,  5,0.5,2,8,    0.5,5.5,8,3]
                ¤  - nilad followed by link(s) as a nilad:
              9    -   literal nine
               Ḷ   -   lowered range = [0,1,2,3,4,5,6,7,8]
             f     - filter keep          [        3,4,          4,7,  4,    7,1,            1,2,  5,    2,8,         ,8,3]
                 Q  - deduplicate          [3,4,7,1,2,5,8]
                  ⁼ - equal to the input?  e.g. 0 (here because 5 was introduced AND because 3 was removed from the right)

Metodo precedente

Gelatina ,  36  35 byte

9s3;Z$;“Æ7a‘DZ¤;U$;©0m€2iị®oµƝFQ⁼ȧȦ

Provalo online! o vedere una suite di test .

Come?

Simile a quanto sopra ma costruisce tutte le possibilità della linea a tre nodi ed esegue la ricerca (piuttosto che controllare mentre procede usando divmod per testare e dimezzare la somma per il nodo centrale).

Innanzitutto la costruzione dell'elenco delle linee a tre nodi:

9s3;Z$;“Æ7a‘DZ¤;U$;©0
9s3                   - nine (implicit range) split into threes = [[1,2,3],[4,5,6],[7,8,9]]
     $                - last two links as a monad:
    Z                 -   transpose = [[1,4,7],[2,5,8],[6,7,9]]
   ;                  -   concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9]]
              ¤       - nilad followed by link(s) as a nilad:
       “Æ7a‘          -   code-page index list = [13,55,97]
            D         -   decimal (vectorises) = [[1,3],[5,5],[9,7]]
             Z        -   transpose = [[1,5,9],[3,5,7]]
      ;               - concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7]]
                 $    - last two links as a monad:
                U     -   upend = [[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3]]
               ;      -   concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3]]
                    0 - literal zero (to cater for non-matches in the main link since ị, index into, is 1-based and modular the 0th index is the rightmost)
                  ;   - concatenate = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
                   ©  - copy the result to the register

Ora il processo decisionale:

...m€2iị®oµƝFQ⁼ȧȦ - left input is a list of integers               e.g. [4,5,8,2,3,9,4]
          µƝ      - perform the chain to the left for adjacent pairs:
                  - i.e. for [a,b] in [[4,5],[5,8],[8,2],[2,3],[3,9],[9,4]]
...               -   perform the code described above = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
   m€2            -   modulo-2 slice €ach = [[1,3],[4,6],[3,9],[1,7],[2,8],[6,9],[1,9],[3,7],[3,1],[6,4],[9,7],[7,1],[8,2],[9,3],[9,1],[7,3],[0]]
      i           -   index of [a,b] in that (or 0 if not there)    e.g. [0,0,13,0,6,0]
        ®         -   recall from register = [[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[1,5,9],[3,5,7],[3,2,1],[6,5,4],[9,8,7],[7,4,1],[8,5,2],[9,6,3],[9,5,1],[7,5,3],0]
       ị          -   index into (1-based & modular)     e.g. [0,0,[8,5,2],0,[3,6,9],0]
         o        -   OR [a,b]           e.g. [[4,5],[5,8],[8,5,2],[2,3],[3,6,9],[9,4]]
            F     - flatten                          e.g. [4,5,5,8,8,5,2,2,3,3,6,9,9,4]
             Q    - deduplicate                                    e.g. [4,5,8,2,3,6,9]
              ⁼   - equal to the input?                            e.g. 0 (here because 6 was introduced AND because 4 was removed from the right)
                Ȧ - any and all? (0 if input is empty [or contains a falsey value when flattened - no such input], 1 otherwise)
               ȧ  - AND (to force an empty input to evaluate as 1 AND 0 = 0)

Come viene fuori a 19 byte quando ci sono un sacco di personaggi unicode?
Izkata,

@Izkata Jelly utilizza la propria tabella codici, che puoi vedere facendo clic su "byte" nell'intestazione. Nella sua forma di byte non elaborata, ciascuno dei caratteri Unicode che puoi vedere nel codice sorgente è solo un singolo byte.
Jonathan Allan,

15

Stax , 28 byte

æ¡_t¿♂≥7▼├öä▒╨½╧£x╪╨┌i╒ë╖¢g•

Eseguirlo

Produce 0 per false e numeri interi positivi per true. La corrispondente rappresentazione ASCII dello stesso programma è questa.

cu=x%v*x2BF1379E-%_|+YA=!*yhxi(#+*

L'idea generale è calcolare diverse condizioni necessarie per gli schemi di scorrimento legali e moltiplicarli tutti insieme.

cu=                                 First: no duplicates
   x%v*                             Second: length of input minus 1
       x2B                          Get all adjacent pairs  
          F                         For each pair, execute the rest
           1379E-%                  a) Any digits that are not 1, 3, 7, 9?
                  _|+Y              Get sum of pair, and store in Y register
                      A=!           b) Sum is not equal to 10?
                         *          c) multiply; logical and: a, b
                          yh        half of y; this will be equal to the
                                        number directly between the current
                                        pair if there is one
                            xi(#    d) has the middle number been observed yet?
                                +   e) plus; logical or: c, d
                                 *  multiply by the accumulated value so far

Uso intelligente del Yregistro.
Weijun Zhou,

Un altro problema su Github.
Weijun Zhou,

1
Per coincidenza, avevo già risolto quel bug, ma non lo avevo distribuito fino ad ora. (non influisce sul mio programma)
ricorsivo il

1
Può sembrare strano, ma puoi eliminare il primo ve includerlo 1come valore errato. 2e soprattutto sono veritieri.
Weijun Zhou,

10

JavaScript, 112 byte

x=>/^(?!.*(.).*\1|[^5]*(19|28|37|46|91|82|73|64)|[^2]*(13|31)|[^8]*(79|97)|[^4]*(17|71)|[^6]*(39|93))../.test(x)

Forse un linguaggio basato su regex dovrebbe essere più breve. Ma non lo so.

Grazie a Neil, modifica )(?!per |salvare 3 byte.


@WeijunZhou Sono diventato vero per il 213, cosa c'è che non va?
TSH

Niente è sbagliato, scusami.
Weijun Zhou,

Ora, dal momento che OP ha chiarito, fallisce per 144.
Weijun Zhou,

1
@WeijunZhou dovrebbe essere risolto; Altre 2 byte ...
TSH

Nel caso ve lo stiate chiedendo, una porta Retina 0.8.2 sembra funzionare a 98 byte.
Neil,

6

Retina 0.8.2 , 98 byte

Influenzato dalla risposta di tsh . Ho provato a "riformulare" il contrario, facendo corrispondere i colpi non validi, quindi Anti-grepping.

A`(.).*\1|^([^5]*(19|28|37|46|91|82|73|64)|[^2]*(13|31)|[^8]*(79|97)|[^4]*(17|71)|[^6]*(39|93)|.$)

Provalo online


6

Buccia , 25 20 byte

S=öufΛ¦1ΣẊ§Jzo½+em‰3

Prende un elenco di numeri interi con indicizzazione basata su 0. Restituisce 0 o 1. Provalo online!

Spiegazione

Ho rubato alcune idee dalla risposta Jelly di Jonathan Allan . L'idea è la stessa: inserire un nuovo "nodo medio" tra ciascuna coppia adiacente, filtrare quelli che non sono nodi effettivi, rimuovere i duplicati e confrontarli con l'elenco originale. Se l'elenco originale contiene duplicati, il risultato è errato. Se l'elenco salta un nodo non visitato, è presente nell'elenco elaborato tra la coppia corrispondente e il risultato è errato. Se l'input è un singleton, l'elenco elaborato è vuoto e il risultato è errato. Altrimenti, è vero.

S=öufΛ¦1ΣẊ§Jzo½+em‰3  Implicit input, say [0,4,6,7,1]
                 m‰3  Divmod each by 3: L = [[0,0],[1,1],[2,0],[2,1],[0,1]]
         Ẋ§Jzo½+e     This part inserts the middle node between adjacent nodes.
         Ẋ            Do this for each adjacent pair, e.g. [1,1],[2,0]:
          §           Apply two functions and combine results with third.
            zo½+      First function:
            z         Zip with
               +      addition,
             o½       then halve: N = [3/2,1/2]
                e     Second function: pair: P = [[1,1],[2,0]]
           J          Combining function: join P with N: [[1,1],[3/2,1/2],[2,0]]
                      Result is a list of such triples.
        Σ             Concatenate: [[0,0],[1/2,1/2],[1,1],[1,1],[3/2,1/2],...,[0,1]]
    f                 Keep only those pairs
     Λ                both of whose elements
      ¦1              are divisible by 1, i.e. are integers: [[0,0],[1,1],[1,1],,...,[0,1]]
   u                  Remove duplicates: [[0,0],[1,1],[2,0],[2,1],[0,1]]
S=ö                   Is the result equal to L? Implicitly print 1 or 0.

3

C ++, 267 256 byte

#define R)return 0
#define H(a,q)if(d==q&&n==a&&!m[a]R;
int v(int s[],int l){if(l<2 R;int m[10]{},i=1,p=s[0],d,n;for(;i<l;++i){m[p]=1;if(m[s[i]]R;d=(d=p-s[i])<0?-d:d;if(d%2<1){n=(p+s[i])/2;H(5,4)H(5,8)H(2,2)H(5,2)H(8,2)H(4,6)H(5,6)H(6,6)}p=s[i];}return 1;}

Per verificare se il modello non salta su un nodo non visitato, fa diverse cose:

  1. Calcola ddoved trova la differenza numerica tra il nodo corrente e l'ultimo nodo.
  2. Se d è dispari, non è necessario verificare, non può saltare un nodo.
  3. Se dè uguale a 4o 8, quindi il salto è tra i nodi 1-9o 3-7, quindi controlla il nodo5
  4. Se dè 2 e il nodo centrale ((last_node + current_node)/2 ) è 2,5 o 8, quindi controllare il nodo centrale
  5. Se dè 6, lo stesso controllo di prima ma con 4, 5o6

I parametri sono un int[]ed è il conteggio degli elementi. Restituisce un intche può essere interpretato come un booltipo


!(d%2)=> d%2<1dovrebbe funzionare.
Zacharý


Ho imparato un nuovo trucco: int s[]=> int*s. Penso che funzionerà.
Zacharý,

2

Perl, 135 byte (134 + -n)

@a{split//}=1;(@{[/./g]}==keys%a&&/../)||die();for$c(qw/132 465 798 174 285 396 195 375/){$c=~/(.)(.)(.)/;/^[^$3]*($1$2|$2$1)/&&die()}

Versione leggermente non golfata

@a{split//} = 1;
(@{[/./g]} == keys %a && /../) || die();
for $c (qw/132 465 798 174 285 396 195 375/) {
  $c=~/(.)(.)(.)/;
  /^[^$3]*($1$2|$2$1)/&&die()
}

Uscite tramite codice di uscita. 0è vero, ogni altro valore è falso. Come da meta consenso , l'output STDERR nel caso di errore viene ignorato.

C'è probabilmente un modo più rapido per controllare la regola "impossibile saltare" piuttosto che elencare semplicemente tutte le possibilità.


2

MATL , 42 41 39 byte

9:IeXKi"Ky@=&fJ*+XK+y&fJ*+Em~zw0@(]z8<v

Questo produce

  • un vettore di colonna non vuoto contenente solo numeri diversi da zero come output di verità; o
  • un vettore di colonna non vuoto contenente almeno uno zero come falsy.

Qui puoi leggere perché questi risultati sono rispettivamente verità e falsità. Provalo online!

Oppure verifica tutti i casi di test , con un codice a piè di pagina che include il test standard per verità / falsità.


2

Stax , 73 72 66 65 byte CP437

ÉWyƒ▬ºJOTƒw-H┌↓&ⁿç↨¼<ü6π║¢S○j⌂zXΣE7≈╩╕╤ö±÷C6▒☼■iP-↑⌐¥]╩q|+zΦ4Φ·¥Ω

79 byte se decompresso,

d4{cAs-5F132396978714EEL3/{xs:IBc0<A*++cEd:-1=sccHs|M=s{U>m|A**mEx%2<xu%x%=!L|+

Esegui ed esegui il debug online!

o eseguire il test batch , dovemeX è presente un'intestazione in modo che Stax possa elaborare input multilinea.

Implementazione senza uso di hash. Emette un numero strettamente positivo (in realtà il numero di test falliti) per casi falsi e 0per quelli veritieri .

Spiegazione

dcancella lo stack di input. L'ingresso è xcomunque variabile .

4{cAs-5F genera la prima parte dell'elenco del nodo centrale.

132396978714EE codifica la seconda parte dell'elenco del nodo centrale.

L3/Raccoglie tutti gli elementi nello stack principale e li divide in parti contenenti ciascuna 3 elementi, il risultato è array a, che è solo l'array di tutti i gruppi di 3 nodi non validi.

{xs:IBc0<A*++cEd:-1=sccHs|M=s{U>m|A**mEPer ogni elenco di nodi non validi, eseguire i seguenti controlli. Il risultato dei risultati del controllo viene modificato andutilizzando il **. Poiché esistono 8 elenchi di nodi non validi, il risultato di questo codice sarà un array di 8 elementi. Il finale Einvia l'array ai suoi singoli elementi nello stack principale.

xs:I ottiene l'indice degli elementi dell'elenco nodi nell'array di input.

Bc0<A*++Se l'indice di "nodo centrale" (ad es. 5Nel set di nodi 1,5,9) è -1(il che significa che non esiste nell'array di input), cambiare l'indice in 9.

cEd:-1=verifica se i due "nodi terminali" (ad es. 1,5nel set di nodi 1,5,9) sono adiacenti nell'array di input.

sccHs|M= verifica se l'indice trasformato del "nodo centrale" è più grande di quelli dei due "nodi terminali", che include due casi: manca il "nodo centrale" o il "nodo centrale" segue i due "nodi terminali"

s{U>m|Averifica se entrambi gli indici dei "nodi finali" non sono negativi. (cioè entrambi appaiono nell'input).

Vengono eseguiti due test aggiuntivi,

x%2< verifica se l'array di input è un singleton.

xu%x%=! verifica se sono nodi visitati due volte.

Esistono 10 risultati del test nello stack principale (uno per ciascun elenco di nodi non validi, oltre a due test aggiuntivi).

L|+ raccoglie i 10 elementi e li aggiunge. |aavrebbe potuto essere usato anche per controllare semplicemente se ci sono elementi di verità sull'array.

Uscita implicita.


2

Java, 375 355 byte

-20 byte grazie a Zacharý

int v(int s[]){int[]m=new int[10];int i=1,p=s[0],d,n,l=s.length;if(l<2)return 0;for(;i<l;++i){m[p]=1;if(m[s[i]]!=0)return 0;d=(d=p-s[i])<0?-d:d;if(d%2==0){n=(p+s[i])/2;if((d==4||d==8)&&n==5&&m[5]==0)return 0;if(d==2&&(n==2&&m[2]==0||n==5&&m[5]==0||n==8&&m[8]==0))return 0;if(d==6&&(n==4&&m[4]==0||n==5&&m[5]==0||n==6&&m[6]==0))return 0;}p=s[i];}return 1;}

Questa è una porta di questa risposta e funziona con gli stessi principi


Woah. Stai rispondendo a Java.
Zacharý,

int v(int s[]){int[]m=new int[10];int i=1,p=s[0],d,n,l=s.length;if(l<2)return 0;for(;i<l;++i){m[p]=1;if(m[s[i]]!=0)return 0;d=(d=p-s[i])<0?-d:d;if(d%2==0){n=(p+s[i])/2;if((d==4||d==8)&&n==5&&m[5]==0)return 0;if((d==2)&&(n==2&&m[2]==0||n==5&&m[5]==0||n==8&&m[8]==0))return 0;if(d==6&&(n==4&&m[4]==0||n==5&&m[5]==0||n==6&&m[6]==0))return 0;}p=s[i];}return 1;}dovrebbe funzionare (ordine delle operazioni)
Zacharý,

Puoi passare (d==2)a solo d==2, l'ho trascurato prima.
Zacharý,

d%2==0=>d%2<1
Zacharý

0

Pyth , 33 byte

q{@U9.nm+mc|g1aZksd2-MC.DR3d_dC,t

Suite di test.

Utilizza l'indicizzazione basata su 0.

Spiegazione

q {@ U9.nm + mc | g1aZksd2-MC.DR3d_dC, t -> Programma completo. Input: un elenco L da STDIN.

                               , t -> Associa L a L senza il primo elemento.
                              C -> Transpose.
       m -> Mappa sopra l'elenco delle coppie (elenchi a 2 elementi):
        + mc | g1aZksd2-MC.DR3d -> La funzione da mappare (variabile: d):
                         R d -> Per ogni elemento di d ...
                       .D 3 -> ... Prendi il suo divmod per 3.
                      C -> Trasposizione.
                    -M -> Riduci ciascuno per sottrazione.
         m -> Per ogni differenza (variabile: k):
            g1aZl -> Is | k | ≤ 1?
           | sd -> Se questo è falso, sostituiscilo con la somma di d.
          c 2 -> Dividi per 2.
        + _d -> Aggiungi il retro di d al risultato della mappatura.
     .n -> Appiattisci.
  @ U9 -> Prendi l'incrocio con (ℤ ∩ [0; 9)).
 {-> Deduplicato.
q -> E controlla se il risultato è uguale a L.

Approccio alternativo per 34 byte :

q{sI#I#+Fm+,hdcR2+MCd]edCtBK.DR3QK

0

Japt , 35 byte

eUä@[(Xu3 aYu3)¥1ªX+Y ÷2XY]Ãc f9o)â

Provalo online!

Leggermente ungolfed e come funziona

eUä@[(Xu3 aYu3)¥1ªX+Y ÷2XY]Ãc f9o)â

Implicit beginning U(input) and some arbitrary sequence conversions

UeUä@[(Xu3 aYu3)==1||X+Y ÷2XY]} c f9o)â

  Uä             Convert the input array into length-2 subsections and map...
    @[ ... ]}      function of X,Y which returns an array of...
      Xu3 aYu3==1||X+Y ÷2          (abs(X%3 - Y%3)==1||X+Y)/2,
                         XY        X, Y
  c              Flatten the result of mapping
    f9o          Intersect with range(9)
        â        Take unique elements, preserving order
Ue             Is the result the same as original array?

Portato l'idea da questa soluzione Jelly , con qualche differenza nel determinare potenziali salti:

  • La risposta Jelly usa divmod per vedere se una coppia ha una differenza di 2 quando viene applicata /3o %3.
  • Questa risposta utilizza solo %3e verifica se la differenza è 0 o 2. Se la differenza è 0, le due celle sono allineate verticalmente e i non salti condividono comunque la proprietà di (X+Y)%2 != 0.

0

Python 2 , 97 byte

Basato sulla risposta di ovs ma 2 byte più brevi e meno criptici. Converte solo gli indici in coordinate 2D e verifica la parità. Presuppone 0-8 indici.

v={9}
s=input()
for n,l in zip(s[1:]or q,s):n/3+l/3&1|n%3+l%3&1or n+l>>1in v or q;v|={l};n in v>q

Provalo online!

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.