Riorganizzazione del blocco


14

Quindi il tuo compito è quello di prendere un blocco 3x3 in cui -gli spazi vuoti medi e *gli spazi riempiti medi, ad esempio:

-**
-*-
*-*

e riorganizzare il blocco in modo che la *forma di una X, in questo modo:

*-*
-*-
*-*

Input: 3x3 quadrati come sopra, possono essere 3 linee, un array o come vuoi.

Output: il minor numero di mosse da riordinare in una X. Ogni mossa lancia 2 caratteri che si toccano e sono orizzontali l'uno dall'altro, verticali l'uno dall'altro o diagonali l'uno dall'altro. Se non è possibile, restituire qualsiasi output impossibile, ad esempio 999o -4242. 5è il numero più piccolo del genere.

Casi test:

1) Uscita: 1

-**
-*-
*-*

2) Uscita: -1

-*-
-*-
*-*

3) Uscita: 3

---
-**
***

4) Uscita: 0

*-*
-*-
*-*

Puoi sostituire i caratteri vuoti e non vuoti, ma assicurati di includere qual è quale nel tuo post

Codice Golf

Ricorda che questo è il codice golf vince il codice più corto!


1
Lanciando 2 personaggi, intendevi capovolgere dallo spazio a *e viceversa o scambiarli?
user202729

E se ce ne fossero più di cinque *? Puoi aggiungere altri casi di test?
Stewie Griffin

@ user202729 ad esempio abc sarebbe acb se si invertono gli ultimi 2 caratteri.
Noah Cristino,

@StewieGriffin "se non è possibile restituire un -1" più di 5 *o meno di 5 lo rende impossibile.
Noah Cristino,

6
Possiamo usare qualcosa di diverso da -1? Ad esempio 5(impossibile altrimenti) o lanciando un errore?
Jonathan Allan,

Risposte:


12

Python 3 , 104 78 byte

lambda n:-(sum(n)!=5)or sum(n[1::2])+n[4]*(max(n,n[6:],n[::3],n[2::3])>=[1]*3)

Provalo online!

Modifica: applicati entrambi i suggerimenti di @Jonathan Allan e @ xnor per ridurre drasticamente il conteggio dei byte.

L'input è un elenco di stringhe di lunghezza 9 con zero e uno, uno dei quali è la *s.

Ecco alcune osservazioni:

  • Non abbiamo mai bisogno di spostare le stelle già sulle celle corrette. Ogni stella fuori posto ha 5 celle circostanti che non possono essere bloccate contemporaneamente (altrimenti la risposta è già -1).
  • Il costo per ogni stella fuori posto è 1 o 2, ed è 2 solo se è circondato da tre stelle posizionate correttamente.
  • Il costo per ogni stella fuori posto è indipendente l'uno dall'altro.

Pertanto, per prima cosa testiamo se la stringa ne ha cinque, quindi contiamo queste cose:

  • Il numero di stelle fuori posto (= quelle con indici dispari)
  • Il numero di stelle malriposti di costo 2 (= cellule a 0124, 0346, 2458, 4678essendo tutti quelli)
    • Fattore di n[4]essere uno e quindi testare ogni estrazione di intervallo '111'.
    • Poiché tale stella è al massimo una, possiamo tranquillamente usare al maxposto di sum.

Salva 17 byte di accettare una lista al posto di una stringa (sostituendo counts con sums e '111'con [1]*3) TIO (ho cercato di essere intelligente con un n[i::j]>=[1]*3ciclo, ma non ho trovato più breve).
Jonathan Allan,

Dal momento che può esserci solo una stella cost-2, sembra che tu possa fare max(n,n[6:],n[::3],n[2::3])>='1'*3.
xnor

Ci sono altri accordi che hanno un costo di 2 stelle. Penso che [0,1,1,1,1,0,1,0,0] dovrebbe restituire 3 invece di 2.
RootDue

Inoltre, [1,1,1,1,0,0,1,0,0] dovrebbe essere 3 invece di 2.
RootDue

Inoltre, [1,1,1,1,0,0,1,0,0] dovrebbe essere 3 invece di 2.
RootDue

4

Gelatina , 26 byte

5ḶḤd3ạŒ!Ṁ€€ḅ1Ṃ
T’d3Ç-L=5Ɗ?

Provalo online!


Prendi una lista piatta come input.

Peccato che Jelly non abbia "indici di verità multidimensionali" ... T€ṭ€"JẎfunziona anche ma richiede 1 byte in più.


Algoritmo: ci sono 5 posizioni di blocco correnti e 5 target (destinazioni), l'algoritmo prova ciascuno dei 5! corrispondenza e output della somma minima di [sorgente, destinazione] distanza di Chebyshev.


Puoi prendere una lista piatta ("come vuoi") ... forse puoi anche prendere indici basati su 0 e avere 24?
Jonathan Allan,

4

Haskell , 176 132 126 104 byte

w=0:1:w
m a|sum a/=5=5|1>0=sum$[a!!4|3<-sum.map(a!!)<$>[[0,1,2],[0,3,6],[2,5,8],[6,7,8]]]++zipWith(*)a w

Provalo online!


Prende un elenco di numeri interi con 1 come carattere non vuoto. Somma il numero di quadrati pari a zero pari a zero, quindi aggiunge 1 se viene trovato uno dei modelli di doppio spostamento (quadrato centrale e colonna / riga del bordo completamente riempiti). L'ultima parte è un po 'dispendiosa, penso, probabilmente potrebbe essere molto migliorata rispetto a questo metodo a forza bruta. Restituisce 5 (un'uscita impossibile) su un input impossibile.


2
Alcuni consigli: il lengthtest può essere abbreviato sum[1|1<-a]. Funzione sin: (1-e,n+sum[1|b>e])che è possibile incorporare per salvare un altro byte. È possibile utilizzare la otherwiseguardia in mper salvare paio di (). Infine, &&al livello più alto in una guardia può essere sostituito da ,. ...
nimi,

2
Puoi salvare un altro byte usando a sumsu una lista di comprensione per trasmettere un booleano a int. Provalo online!
Post Rock Garf Hunter,

2
In realtà puoi salvare un bel po 'di byte perché una volta che le protezioni del modello sono sparite, puoi semplicemente spostare tutto in alto m. Provalo online!
Post Rock Garf Hunter,

2
Anche dal momento che ogni elemento non-1 di adeve essere 0non puoi usare al sum aposto di sum[1|1<-a]? Provalo online!
Post Rock Garf Hunter,

1
Mi sono appena reso conto che non ci può essere più di 1 lato con tutte le 1s a meno che non sia il centro 0, puoi fare 3<-invece di elem 3$. Inoltre puoi usare sum.map(a!!)invece di sum<$>map(a!!).
Post Rock Garf Hunter,

3

Python 2 , 194 192 byte

from itertools import*
f=lambda l,k=0:-(sum(l)!=5)or[1,0]*4!=l[:-1]and k<4and-~min(f(l[:a]+[l[b]]+l[a+1:b]+[l[a]]+l[b+1:],k+1)for a,b in combinations(range(9),2)if max(b/3-a/3,abs(a%3-b%3))<2)

Provalo online!


1
Non funziona con [0,1,0,1,0,1,1,1,0](previsto: 4, effettivo: 13).
Gorgogliatore

@Bubbler ha risolto il problema
ovs

3

JavaScript (ES6), 123 byte

Accetta l'input come numero intero a 9 bit. Risolve il puzzle applicando ingenuamente le regole, che hanno dimostrato di non essere l'approccio più breve.

f=(n,k=b=-1)=>n^341?k>2?b:[3,6,9,10,17,18,20,34,36].map(m=>[1,8,8].map(M=>(x=n&(m*=M))&-x^x||f(n^m,k+1)))|b:!~b|k<b?b=k+1:b

Provalo online!

Commentate

f = (                           // f = recursive function taking:
  n,                            //   n = input
  k =                           //   k = number of moves, initialized to -1
  b = -1                        //   b = best result so far, initialized to -1
) =>                            //
  n ^ 341 ?                     // if n does not match the target pattern:
    k > 2 ?                     //   if we've already done more than 3 moves:
      b                         //     we're not going to find a solution -> abort
    :                           //   else:
      [3,6,9,10,17,18,20,34,36] //     for each swap bitmask m
      .map(m =>                 //     and
      [1,8,8]                   //     for each multiplier M:
      .map(M =>                 //       apply the multiplier to m and
        (x = n & (m *= M))      //       apply the final bitmask to n -> this gives x
        & -x                    //       isolate the least significant bit of x
        ^ x ||                  //       if it's the only bit set,
        f(n ^ m, k + 1)         //       then swap the bits and make a recursive call
      )) | b                    //     end of both map() loops; return b
  :                             // else:
    !~b | k < b ? b = k + 1 : b //   this is a solution in k+1 moves: update b

NB : Questo codice esegue alcune mosse illegali oltre la parte superiore del tabellone quando m viene moltiplicato per 64. Ma vengono semplicemente ignorati, in quanto non possono portare a una soluzione più breve della migliore soluzione legale.

Di seguito sono riportate le 9 maschere di scambio di base e il modello di destinazione. L'angolo in alto a sinistra è il bit più significativo.

000  000  001  001  010  010  010  100  100     101
011  110  001  010  001  010  100  010  100     010 (341)
(3)  (6)  (9)  (10) (17) (18) (20) (34) (36)    101

Puoi collegare un hexdump per il test? Inoltre, non sapevo che numeri interi a 9 bit fossero possibili in JS
Stan Strum il

@StanStrum Aggiornato a una versione più breve con una codifica più semplice. (E sì: JS supporta operazioni bit per bit fino a 32 bit.)
Arnauld

2

Gelatina , 26 byte

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ

Provalo online!

Un collegamento monadico.

Come?

Ispirato dalla risposta Python di Bubbler ; giocato a golf per soddisfare Jelly ...

“ċȤ‘ḤB;U$=a¥;Ḋm2ƊẠ€SɓSn5Nȯ - Link: length 9 list of ones & zeros, X
“ċȤ‘                       - list of code-page indices     = [232,154]
    Ḥ                      - double                        = [464,308]
     B                     - to binary     = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0]]
        $                  - last two links as a monad:
       U                   -   upend       = [[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
      ;                    -   concatenate = [[1,1,1,0,1,0,0,0,0],[1,0,0,1,1,0,1,0,0],[0,0,0,0,1,0,1,1,1],[0,0,1,0,1,1,0,0,1]]
           ¥               - last two links as a dyad:
          a                -   logical AND (vectorises)
         =                 -   equal? (vectorises)
                Ɗ          - last three links as a monad:
             Ḋ             -   dequeue X (remove leftmost element)
               2           -   literal two
              m            -   modulo slice (keeps the "edge-elements") 
            ;              - concatenate
                 Ạ€        - all? for €ach (edge-elements: no-op
                           -                else: 1 for any cost-2 element 0 otherwise)
                   S       - sum
                    ɓ      - new dyadic chain ^that on the right; X on the left
                     S     - sum X
                       5   - literal five
                      n    - not equal?
                        N  - negate (-1 if not exactly 5 1s, 0 otherwise)
                         ȯ - logical OR with right

2

JavaScript, 85 byte

s=>/^0*(10*){5}$/.test(s)*s.match(/(?=1.(..)*$|^1(..)?11.1|1.11(..)?1$)|$/g).length-1

Questa è una porta regex della risposta di Bubbler .

Immettere come stringa di 0/1.


2

Stax , 23 22 byte

Ç╙╤Ü┤└åVτ┐├Y-²▼░█∩¡3ëâ

Esegui ed esegui il debug

Questo programma accetta una matrice di [0, 1]come input e restituisce un numero intero di mosse o una stringa vuota se non è possibile alcuna soluzione.

Considera questo indice per la griglia

0 1 2
3 4 5
6 7 8
  • Se non ci sono esattamente 5 1secondi nell'input, allora non c'è soluzione, quindi non produciamo output.
  • I centri di ciascun lato sono le posizioni errate. Questi sono gli indici 1, 3, 5 e 7. Sommare la distanza per ciascuno 1in queste posizioni produrrà il risultato finale.
  • Per ognuno 1in una posizione errata la sua distanza è 1 o 2. Sarà 2 se è circondato da altri 1s. Ad esempio, se ci sono 1s negli indici [0, 1, 2, 4], la distanza per l'incorretto 1è 2.
  • Con questo in mente, considera questo pseudo-codice per ottenere la distanza che ha contribuito al risultato dall'indice 1.

    1. Leggi 4 bit dagli indici [1, 0, 2, 4]. Questo mette la posizione errata nella posizione più significativa.
    2. Convertire questi bit in un numero compreso btra 0 e 15.
    3. Quando 0 <= b <= 7la distanza è 0. Quando 8 <= b <= 14la distanza è 1. Quando b == 15la distanza è 2. Questo può essere calcolato usando la divisione intera per b * 2 / 15.

Quindi la distanza totale può essere calcolata ripetendo questo processo 4 volte e ruotando la griglia in mezzo.

1#5=4*  if the number of 1s is 5, then 4, else 0
D       repeat the rest of the program that many times
  x     push the value in the x register, which is initially the input
  3/    split into 3 rows
  rM    rotate 90 degrees
  $X    flatten back into single array, and save the "rotated" array in the X register
  A|2E  get the digits of 2^10 i.e. [1,0,2,4]
  @     read the bits from the current rotation at indices [1,0,2,4]
  :b    convert bits to integer
  H15/  double, then divide by 2
  +     add to running total

Esegui questo


Controlla la modifica, viene accettato qualsiasi valore impossibile, non solo -1 se questo ti aiuta
Noah Cristino

Sì. Ciò ha salvato 2 byte.
ricorsivo il

1

Excel, 86 81 byte

=SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3))/(SUM(A1:C3)=5)

Vecchio: quando l'output "impossibile" era-1

=IF(SUM(A1:C3)=5,SUM(B1,A2,B3,C2)+B2*(AND(A1:A3)+AND(A1:C1)+AND(C1:C3)+AND(A3:C3)),-1)

Utilizza 1per riempito e 0per vuoto, input nel range A1:C3. È possibile giocare a golf ulteriormente se possiamo restituire valori diversi da -1"impossibile". Restituisce un #DIV/0!errore su griglie impossibili

Funziona sulla stessa logica della risposta Python di Bubbler .


Controlla la modifica, viene accettato qualsiasi valore impossibile, non solo -1
Noah Cristino
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.