Juguemos Solitario Peg

8

Peg Solitaire es un juego popular que generalmente se juega solo. El juego consiste en un cierto número de clavijas y un tablero que se divide en una cuadrícula; por lo general, el tablero no es rectangular, pero para este desafío asumiremos que sí.

Cada movimiento válido le permite a uno eliminar una sola clavija y el objetivo es jugar de una manera, de modo que quede una sola clavija. Ahora, un movimiento válido tiene que estar en una sola dirección (norte, este, sur u este) y saltar sobre una clavija que se puede quitar.

Ejemplos

Deje .espacios vacíos en el tablero y los números son clavijas, el siguiente movimiento se moverá 1uno hacia la derecha y se eliminará 2del tablero:

.....     .....
.12..  -> ...1.
.....     .....

Un movimiento siempre tendrá que saltar sobre una sola clavija, por lo que lo siguiente no es válido:

......    ......
.123.. -> ....1.
......    ......

Aquí hay algunas configuraciones válidas después de un movimiento cada una:

...1...        ...1...        ..71...        ..71...
.2.34.5  --->  .24...5  --->  .2....5  --->  ......5
.678...  (4W)  .678...  (7N)  .6.8...  (2S)  ...8...
.......        .......        .......        .2.....

Desafío

Dada una configuración inicial de la placa y alguna otra configuración, indique si se puede alcanzar la otra configuración moviendo sucesivamente las clavijas como se describió anteriormente.

Reglas

  • De entrada será una norte×metro matriz / lista de listas / ... de valores que indican un espacio vacío (por ejemplo. Cero o falsa) o clavijas (por ejemplo. No cero o verdadero)
    • se puede suponer norte3 y metro3
    • puede usar verdadero / distinto de cero para indicar espacios vacíos y viceversa si ayuda
  • La salida será dos valores distintos (uno de los valores puede diferir) que indican si se puede alcanzar la configuración final (por ejemplo, falsedad / verdad , []/ [list of moves]..)

Casos de prueba

initial  goal -> output
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,0],[0,1,0],[1,1,0]] -> True
[[1,0,0],[1,1,0],[0,1,0]]  [[0,0,1],[0,1,1],[0,0,0]] -> False
[[0,0,0],[1,0,0],[0,0,0]]  [[0,0,0],[0,0,1],[0,0,0]] -> False
[[0,0,0],[1,1,0],[0,0,0]]  [[0,0,0],[0,1,1],[0,0,0]] -> False
[[0,0,0,0],[1,1,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,1],[0,0,0,0]] -> False
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[0,0,1],[0,1,0],[1,0,0],[0,0,1]] -> True
[[1,0,0],[1,1,0],[1,1,1],[1,1,1]]  [[1,0,0],[0,0,0],[0,0,0],[0,0,0]] -> False
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,1,0],[1,0,0,0],[1,0,1,0],[1,0,0,1]] -> True
[[1,0,1,1],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -> False
[[1,0,0,0],[1,1,0,0],[1,1,1,0],[1,0,1,0]]  [[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]] -> True
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]] -> False
[[0,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,0]]  [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] -> False
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]] -> True
[[0,0,0,1,0,0,0],[0,1,0,1,1,0,1],[0,1,1,1,0,0,0],[0,0,0,0,0,0,0]]  [[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -> True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,1,0,0,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]] -> True
[[0,0,1,1,1,0,0],[0,0,1,1,1,0,0],[1,1,1,1,1,1,1],[1,1,1,0,1,1,1],[1,1,1,1,1,1,1],[0,0,1,1,1,0,0],[0,0,1,1,1,0,0]]  [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] -> True
ბიმო
fuente
1
¿Qué pasó con la vinculación 7en tu ejemplo? ¿Por qué desaparece después de 2moverse hacia el sur?
Novurous
@Ourous: Eso fue solo un error tipográfico, lo arregló.
ბიმო

Respuestas:

2

JavaScript (ES6),  184 178  173 bytes

(initial_board)(target_board)0 01

a=>g=b=>a+''==b|a.some((r,y)=>r.some((v,x,A,X,R)=>[-1,0,1,2].some(h=>(A=a[y+(R=~-h%2)]||0)[X=x+(h%=2)]&v>(R=a[y+R*2]||0)[h+=x+h]&&g(b,A[X]=r[x]=R[h]++)&(A[X]=r[x]=R[h]--))))

Pruébalo en línea!

(eliminó los dos últimos casos de prueba que toman demasiado tiempo para TIO)

Comentado

a =>                             // main function taking the initial board a[]
  g = b =>                       // g = recursive function taking the target board b[]
    a + '' == b |                // yield a truthy result if a[] is matching b[]
    a.some((r, y) =>             // for each row r[] at position y in a[]:
      r.some((v, x, A, X, R) =>  //   for each value v at position x in r[]:
        [-1, 0, 1, 2]            //     list of directions (West, North, East, South)
        .some(h =>               //     for each direction h:
          ( A =                  //       A = a[y + dy]
            a[y + (R = ~-h % 2)] //       R = dy
            || 0                 //       use a dummy row if we're out of the board
          )[X = x + (h %= 2)]    //       h = dx, X = x + dx
          &                      //       yield 1 if there's a peg on the skipped cell
          ( R =                  //       R = target row
            a[y + R * 2]         //         = a[y + 2 * dy]
            || 0                 //       use a dummy row if we're out of the board
          )[h += x + h]          //       h = x + 2 * dx = target column
          < v                    //       yield 1 if there's no peg on the target cell
          &&                     //       and there's a peg on the source cell (0 < 1)
          g(                     //       if the above result is true, do a recursive call:
            b,                   //         pass b[] unchanged
            A[X] = r[x] =        //         clear the source and skipped cells
            R[h]++               //         set the target cell
          ) & (                  //       and then restore the board to its initial state:
            A[X] = r[x] =        //         set the source and skipped cells
            R[h]--               //         clear the target cell
          )                      //
        )                        //     end of some() over directions
      )                          //   end of some() over columns
    )                            // end of some() over rows
Arnauld
fuente
1

Limpio , 232 bytes

import StdEnv,Data.List
r=reverse
@[a:t=:[b,c:u]]=[[a:v]\\v<- @t]++take(a*b-c)[[0,0,1:u]];@l=[]

flip elem o\c=limit(iterate(nub o concatMap\l=[l]++[f(updateAt i p(f l))\\f<-[id,transpose],q<-f l&i<-[0..],p<- @q++(map r o@o r)q])[c])

Pruébalo en línea!

Esta es una de las raras ocasiones en que puedo utilizar composición y curry mientras guardo bytes.

Explicado:

@ :: [Int] -> [[Int]]es una función auxiliar que se utiliza para generar los diferentes potenciales nuevas filas / columnas que podrían resultar de un movimiento que se hizo. Evita la necesidad de un caso especial [1,1,0:_]al notar eso a*b-c>0solo cuando [a,b,c]=[1,1,0], y así lo take(a*b-c)...hace []al tomar -1o 0elementos para todas las configuraciones que no son un movimiento válido.

flip elem o...invierte el orden de los argumentos a elem(haciéndolo "si x contiene una y" en lugar de "es x un miembro de y") y aplica la función anónima cal primer argumento.

\c=limit(iterate(nub o concatMap ...)[c])genera todos los tableros potenciales que pueden resultar de la cunión al conjunto actual de tableros con todos los movimientos que pueden ocurrir en todos los tableros y elimina los duplicados, hasta que el resultado deja de cambiar.

\l=[l]++...antepone el tablero la la lista de todos los tableros nuevos potenciales a una distancia de un movimiento, generado al aplicar @a las filas de cada orientación del tablero (rotaciones de 0, 90, 180, 270 grados) y reemplazar la fila cambiada correspondiente con el nuevo fila.

Οurous
fuente