Reorganización de bloque

14

Entonces, su tarea es tomar un bloque de 3x3 donde -estén los espacios en blanco medios y *los espacios llenos medios, por ejemplo:

-**
-*-
*-*

y reorganizar el bloque para que *forme una X, así:

*-*
-*-
*-*

Entrada: 3x3 cuadrados como los anteriores, pueden ser 3 líneas, una matriz, o como quieras.

Salida: la cantidad más corta de movimientos para reorganizar en una X. Cada movimiento es voltear 2 personajes que se tocan, y son horizontales entre sí, verticales entre sí o diagonales entre sí. Si no es posible, devuelva cualquier salida imposible, por ejemplo 999o -4242. 5es el número más pequeño

Casos de prueba:

1) Salida: 1

-**
-*-
*-*

2) Salida: -1

-*-
-*-
*-*

3) Salida: 3

---
-**
***

4) Salida: 0

*-*
-*-
*-*

Puede sustituir los caracteres en blanco y no en blanco, pero asegúrese de incluir cuál es cuál en su publicación

Code Golf

Recuerde que este es el código de golf, ¡el código más corto gana!

Noah Cristino
fuente
1
Al voltear 2 caracteres, ¿querías decir voltear desde el espacio *y viceversa, o intercambiarlos?
user202729
¿Qué pasa si hay más de cinco *? ¿Puedes agregar algunos casos de prueba más?
Stewie Griffin
@ user202729, por ejemplo, abc sería acb si voltea los últimos 2 caracteres.
Noah Cristino
@StewieGriffin "si no es posible devolver un -1" más de 5 *o menos de 5 lo hace imposible.
Noah Cristino
66
¿Podemos usar algo diferente a -1? Por ejemplo 5(imposible de otro modo), o arrojando un error?
Jonathan Allan

Respuestas:

12

Python 3 , 104 78 bytes

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

Pruébalo en línea!

Editar: aplicó las sugerencias de @Jonathan Allan y @ xnor para reducir drásticamente el recuento de bytes.

La entrada es una lista de cadenas de longitud 9 con ceros y unos, siendo uno el *s.

Aquí hay algunas observaciones:

  • Ya no necesitamos mover las estrellas en las celdas correctas. Cualquier estrella extraviada tiene 5 celdas circundantes que no se pueden bloquear a la vez (de lo contrario, la respuesta ya es -1).
  • El costo de cada estrella extraviada es 1 o 2, y es 2 solo si está rodeado por tres estrellas colocadas correctamente.
  • El costo de cada estrella extraviada es independiente el uno del otro.

Por lo tanto, primero probamos si la cadena tiene cinco unidades y luego contamos estas cosas:

  • El número de estrellas mal ubicadas (= unas en índices impares)
  • El número de estrellas fuera de lugar de costo 2 (= células a 0124, 0346, 2458, 4678siendo todos unos)
    • Factorice n[4]ser uno y luego pruebe cada extracción de rango '111'.
    • Como tal estrella es como máximo una, podemos usarla de forma segura en maxlugar de sum.
Bubbler
fuente
Ahorre 17 bytes aceptando una lista en lugar de una cadena (reemplazando counts por sumsy '111'con [1]*3) TIO (He estado tratando de ser inteligente con un n[i::j]>=[1]*3bucle pero no lo he encontrado más corto).
Jonathan Allan
Como solo puede haber una estrella de costo 2, parece que puedes hacerlo max(n,n[6:],n[::3],n[2::3])>='1'*3.
xnor
Hay otros arreglos que tienen un costo de 2 estrellas. Creo que [0,1,1,1,1,0,1,0,0] debería devolver 3 en lugar de 2.
RootTwo
Además, [1,1,1,1,0,0,1,0,0] debería ser 3 en lugar de 2.
RootTwo
Además, [1,1,1,1,0,0,1,0,0] debería ser 3 en lugar de 2.
RootTwo
4

Jalea , 26 bytes

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

Pruébalo en línea!


Tome una lista plana como entrada.

Lástima que Jelly no tenga "índices de verdad multidimensionales" ... T€ṭ€"JẎtambién funciona pero toma 1 byte más.


Algoritmo: hay 5 posiciones de bloque actuales y 5 objetivos (destinos), ¡el algoritmo prueba cada uno de los 5! coincidencia, y la salida de la suma mínima de [origen, destino] distancia de Chebyshev.

usuario202729
fuente
Puede tomar una lista plana ("como quiera") ... ¿tal vez incluso pueda tomar índices basados ​​en 0 y tener 24?
Jonathan Allan
4

Haskell , 176 132 126 104 bytes

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

Pruébalo en línea!


Toma una lista de enteros con 1 como carácter no en blanco. Suma el número de cuadrados indexados pares distintos de cero, luego agrega 1 si se encuentra alguno de los patrones de doble movimiento (el cuadrado central y la columna / fila del borde están completamente llenos). La última parte es un poco derrochadora, creo, probablemente podría mejorarse mucho con este método de fuerza bruta. Devuelve 5 (una salida imposible) en una entrada imposible.

aoemica
fuente
2
Algunos consejos: la lengthprueba se puede acortar sum[1|1<-a]. Función spara: (1-e,n+sum[1|b>e])que puede alinear para guardar otro byte. Se puede utilizar el otherwiseprotector de ma guardar par de (). Finalmente, &&en el nivel superior en un guardia puede ser reemplazado por ,. ...
nimi
2
Puede guardar otro byte utilizando una sumcomprensión en una lista para emitir un booleano a int. Pruébalo en línea!
Post Rock Garf Hunter
2
En realidad, puede guardar bastantes bytes porque una vez que los protectores de patrones se han ido, puede mover todo hacia arriba m. Pruébalo en línea!
Post Rock Garf Hunter
2
Además, dado que cada elemento no 1 de adebe ser, 0¿no puedes usarlo en sum alugar de sum[1|1<-a]? Pruébalo en línea!
Post Rock Garf Hunter
1
Me acabo de dar cuenta ya que no puede haber más de 1 lado con todos los 1s a menos que el centro lo sea 0, puedes hacerlo en 3<-lugar de elem 3$. También puedes usar en sum.map(a!!)lugar de sum<$>map(a!!).
Post Rock Garf Hunter
3

Python 2 , 194192 bytes

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)

Pruébalo en línea!

ovs
fuente
1
No funciona con [0,1,0,1,0,1,1,1,0](esperado: 4, real: 13).
Bubbler
@Bubbler lo arregló
ovs
3

JavaScript (ES6), 123 bytes

Toma la entrada como un entero de 9 bits. Resuelve el acertijo aplicando ingenuamente las reglas, que se ha demostrado que no es el enfoque más corto.

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

Pruébalo en línea!

Comentado

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 : Este código realiza algunos movimientos ilegales más allá de la parte superior del tablero cuando m se multiplica por 64. Pero simplemente se ignoran, ya que no pueden conducir a una solución más corta que la mejor solución legal.

A continuación se muestran las máscaras de bits de intercambio de 9 bases y el patrón de destino. La esquina superior izquierda es el bit más 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
Arnauld
fuente
¿Puedes vincular un hexdump para probar? Además, no sabía que los números enteros de 9 bits fueran posibles en JS
Stan Strum el
@StanStrum Actualizado a una versión más corta con una codificación más sencilla. (Y sí: JS admite operaciones bit a bit de hasta 32 bits.)
Arnauld
2

Jalea , 26 bytes

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

Pruébalo en línea!

Un enlace monádico.

¿Cómo?

Inspirado por la respuesta Python de Bubbler ; golf para adaptarse a 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
Jonathan Allan
fuente
2

JavaScript, 85 bytes

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

Este es un puerto regex de la respuesta de Bubbler .

Ingrese como una cadena de 0/1.

tsh
fuente
2

Stax , 23 22 bytes

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

Ejecutar y depurarlo

Este programa toma una matriz de [0, 1]como entrada, y devuelve un número entero de movimientos, o una cadena vacía si no hay solución posible.

Considere estos índices para la cuadrícula

0 1 2
3 4 5
6 7 8
  • Si no son exactamente 5 1s en la entrada, entonces no hay solución, por lo que producimos no hay salida.
  • Los centros de cada lado son las posiciones incorrectas. Estos son los índices 1, 3, 5 y 7. Sumar la distancia para cada uno 1en estas posiciones producirá el resultado final.
  • Para cada uno 1en una posición incorrecta, su distancia es 1 o 2. Será 2 si está rodeado por otros 1s. Por ejemplo, si hay 1s en los índices [0, 1, 2, 4], entonces la distancia para el incorrecto 1es 2.
  • Con esto en mente, considere este pseudocódigo para obtener la distancia contribuida al resultado por el índice 1.

    1. Leer 4 bits de los índices [1, 0, 2, 4]. Esto coloca la posición incorrecta en la posición más significativa.
    2. Convierta estos bits a un número bdel 0 al 15.
    3. Cuando 0 <= b <= 7la distancia es 0. Cuando 8 <= b <= 14la distancia es 1. Cuando b == 15la distancia es 2. Esto se puede calcular utilizando la división entera por b * 2 / 15.

Por lo tanto, la distancia total se puede calcular repitiendo este proceso 4 veces y girando la cuadrícula en el medio.

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

Ejecute este

recursivo
fuente
Comprueba la edición, se acepta cualquier valor imposible, no solo -1 si eso te ayuda
Noah Cristino
Si. Eso ahorró 2 bytes.
recursivo
1

Excel, 86 81 bytes

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

Viejo: cuando la salida 'imposible' 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)

Usos 1para llenado y 0vacío, entrada en rango A1:C3. Posible jugar más al golf si podemos devolver valores distintos de -1"imposible". Devuelve un#DIV/0! error en cuadrículas imposibles

Funciona con la misma lógica que la respuesta Python de Bubbler .

Cronocidales
fuente
Verifique la edición, se acepta cualquier valor imposible, no solo -1
Noah Cristino