Resuelve el rompecabezas cromático

35

En nuestros amigos de Puzzling.SE , se publicó el siguiente rompecabezas: ¿Este rompecabezas cromático siempre tiene solución? por Edgar G. Puedes jugarlo aquí .

Explicación del rompecabezas

Dada una m x ncuadrícula con mosaicos de tres colores diferentes, puede seleccionar dos mosaicos adyacentes , si sus colores son diferentes . Estas dos fichas se convierten al tercer color, es decir, el único color no representado por estas dos fichas. El rompecabezas se resuelve si todas las fichas tienen el mismo color . Al parecer, se puede demostrar que este rompecabezas es siempre solucionable, si ninguno m, ni nson divisible por 3.

Rompecabezas tricolor 8x8

Por supuesto, esto exige un algoritmo de resolución. Escribirás una función o programa que resuelva este rompecabezas. Tenga en cuenta que las funciones con 'efectos secundarios' (es decir, la salida está activada en stdoutlugar de en algún valor de retorno de tipo de datos incómodo) están explícitamente permitidas.

De entrada y salida

La entrada será una m x nmatriz que consiste de los números enteros 1, 2y 3(o 0, 1, 2si es conveniente). Puede tomar esta entrada en cualquier formato cuerdo. Ambos my nson >1y no son divisibles por 3. Puede suponer que el rompecabezas no está resuelto

Entonces resolverás el rompecabezas. Esto implicará una selección repetida de dos mosaicos adyacentes para ser 'convertidos' (ver arriba). Producirá las dos coordenadas de estos mosaicos para cada paso que tomó su algoritmo de resolución. Esto también puede estar en cualquier formato de salida sano. Puede elegir entre la indexación de sus coordenadas basada en 0 y en 1, y si las filas o columnas se indexan primero. Sin embargo, mencione esto en su respuesta.

Su algoritmo debe ejecutarse dentro de un tiempo razonable en el caso original de 8x8. Forzarlo por completo está explícitamente prohibido, es decir, su algoritmo debe ejecutarse O(k^[m*(n-1)+(m-1)*n])con kla cantidad de pasos necesarios para la solución. Sin embargo, no se requiere que la solución sea ​​óptima. La prueba dada en la pregunta vinculada puede darle una idea de cómo hacer esto (por ejemplo, primero haga todas las columnas usando solo mosaicos adyacentes verticalmente y luego haga todas las filas)

Casos de prueba

En estos casos de prueba, las coordenadas se basan en 1 y las filas se indexan primero (como MATLAB / Octave y probablemente muchas otras).

Input: 
[1 2]
Output: (result: all 3's)
[1 1],[1,2]


Input:
[ 1 2
  3 1 ]
Output: (result: all 1's)
[1 1],[2 1]        (turn left column into 2's)
[2 1],[2 2]        (turn right column into 3's)
[1 1],[1 2]        (turn top row into 1's)
[2 1],[2 2]        (turn bottom row into 1's)

Input:
[1 2 3 2
 3 2 1 1]

Output: (result: all 3's)
[1 1],[1 2] 
[1 3],[1 4] 
[1 2],[1 3] 
[1 1],[1 2] 
[1 2],[1 3] 
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]

Si lo desea, puedo publicar una pastebin de casos de prueba más grandes, pero creo que esto debería ser suficiente.

Sanchises
fuente
Me encantaría ver una versión de desafío de código de esto, donde el objetivo es resolver un conjunto de acertijos con los movimientos menos totales.
Mego
@Mego definitivamente lo consideré. Sin embargo, me temo que esto se convertirá en un DFS o BFS que tardará una eternidad en ejecutarse; o, para evitar esto, un conjunto de restricciones vagas (como 'debe ejecutarse dentro de una hora' que favorece a las personas con una computadora masiva, o que requerirá que pruebe todas las soluciones). Y además, el desafío actual tiene cero respuestas, por lo que dudo que una versión aún más difícil que requiera heurística, etc. resulte ser más popular ... Pero tal vez si este desafío toma impulso, puedo publicar un desafío para hermanos como tú. describir.
Sanchises
Creo que intentaré hacer eso en Lua, pero puede ser más largo que tu solución de 324 Bytes ^^
Katenkyo
@Katenkyo ¡Solo hay una forma de averiguarlo! Espero ver su solución.
Sanchises
Tendrás que esperar un poco tristemente, evitaste la solución de fuerza bruta, así que tengo que encontrar una solución que sea corta en lua: p
Katenkyo

Respuestas:

5

Rubí, 266 bytes

Más o menos solo un puerto de la solución Octave, excepto que primero resuelve las filas en lugar de las columnas. La entrada es una matriz de matrices, siendo las matrices internas las filas. Los movimientos de salida son [row, column, row, column]. Banco de pruebas

->m{t=->v{v.size*v.inject(:+)%3}
s=->a,x,r{g=t[a]
(q=(r=0..a.size-2).find{|i|a[i]!=a[i+1]&&g!=a[i]}||r.find{|i|a[i]!=a[i+1]}
a[q,2]=[t[a[q,2]]]*2
p r ?[x,q,x,q+1]:[q,x,q+1,x])while[]!=a-[g]}
m.size.times{|i|s[m[i],i,1]}
m=m.shift.zip *m
m.size.times{|i|s[m[i],i,p]}}

Sin disculpas con la explicación

->m{                                  # Start lambda function, argument `m`
  t=->v{v.size*v.inject(:+)%3}        # Target color function
  s=->a,x,r{                          # Function to determine proper moves
                                      #   a = row array, x = row index, r = horizontal
    g=t[a]                            # Obtain target color
    (
      q=(r=0..a.size-2).find{|i|      # Find the first index `i` from 0 to a.size-2 where...
        a[i]!=a[i+1]                  # ...that element at `i` is different from the next...
        &&g!=a[i]                     # ...and it is not the same as the target color
      } || r.find{|i|a[i]!=a[i+1]}    # If none found just find for different colors
      a[q,2]=[t[a[q,2]]]*2            # Do the color flipping operation
      p r ?[x,q,x,q+1]:[q,x,q+1,x]    # Print the next move based on if `r` is truthy
    ) while[]!=a-[g]}                 # While row is not all the same target color, repeat
m.size.times{|i|                      # For each index `i` within the matrix's rows...
  s[m[i],i,1]                         # ...run the solving function on that row
                                      #   (`r` is truthy so the moves printed are for rows)
}
m=m.shift.zip *m                      # Dark magic to transpose the matrix
m.size.times{|i|s[m[i],i,p]}}         # Run the solving function on all the columns now
                                      #   (`r` is falsy so the moves printed are for columns)
Tinta de valor
fuente
Es interesante ver que un puerto entre dos idiomas que no son de golf todavía puede marcar una diferencia de ~ 20%. ¿Podría quizás agregar una breve explicación? (Especialmente la línea 3 - Espero secretamente poder usar eso en mi respuesta ya que intersectes una palabra clave tan voluminosa)
Sanchises
@sanchises se agregó una explicación. En cuanto a intersecteso, no sé si puede arreglar la forma en que funciona la mía porque Ruby findbásicamente opera en funciones, y su functionpalabra clave es igual de voluminosa.
Value Ink
De hecho, aún podría usar tu método para find... ¡gracias! Aún así, nada cerca de
golpearte
13

Octava, 334 313 bytes

Dado que el desafío puede parecer un poco desalentador, presento mi propia solución. No probé formalmente que este método funciona (supongo que se reducirá a probar que el algoritmo nunca se quedará atrapado en un bucle), pero hasta ahora funciona perfectamente, haciendo 100x100 casos de prueba en 15 segundos. Tenga en cuenta que elegí usar una función con efectos secundarios en lugar de una que devuelva todas las coordenadas, ya que eso me ahorró algunos bytes. Las coordenadas son principales de fila, basadas en 1 y formateadas como row1 col1 row2 col2. Los colores de entrada son 0,1,2ya que esto funciona mejor mod, a costa de tener que usar en numellugar de nnz. Versión de golf: Editar: guardó otros pocos bytes utilizando una técnica de la respuesta de Kevin Lau.

function P(p)
k=0;[m,n]=size(p);t=@(v)mod(sum(v)*numel(v),3);for c=1:n
p(:,c)=V(p(:,c));end
k=1;for r=1:m
p(r,:)=V(p(r,:));end
function a=V(a)
while any(a-(g=t(a)))
isempty(q=find(diff(a)&a(1:end-1)-g,1))&&(q=find(diff(a),1));
a([q q+1])=t(a([q q+1]));if k
disp([r q r q+1])
else
disp([q c q+1 c])
end;end;end;end

Ejemplo de GIF del algoritmo de resolución:

ingrese la descripción de la imagen aquí

Versión sin golf:

function solveChromaticPuzzle(p)
[m,n]=size(p);                           % Get size
t=@(v)mod(sum(v)*numel(v),3);            % Target colour function
for c=1:n                                % Loop over columns
    p(:,c)=solveVec(p(:,c));             % Solve vector
end
for r=1:m                                % Loop over rows
    p(r,:)=solveVec(p(r,:));
end
    function a=solveVec(a)               % Nested function to get globals
        g=t(a);                          % Determine target colour
        while(any(a~=g))                 % While any is diff from target...
            % Do the finding magic. Working left-to-right, we find the
            % first pair that can be flipped (nonzero diff) that does not
            % have the left colour different from our goal colour
            q=min(intersect(find(diff(a)),find(a~=g)));
            if(isempty(q))               % In case we get stuck...
                q=find(diff(a),1);       % ... just flip the first possible
            end;
            a([q q+1])=t(a([q q+1]));    % Do the actual flipping.
            if(exist('r'))               % If we're working per row
                disp([r q r q+1])        % Print the pair, using global row
            else
                disp([q c q+1 c])        % Print the pari, using global col
            end
        end
    end
end
Sanchises
fuente
Acabo de darme cuenta, pero mi nombre no es Kenny Lau ... ese es otro usuario y mi nombre de usuario indica específicamente que no soy Kenny
Value Ink
7

Lua, 594 575 559 Bytes

Advertencia ¡ Todavía hay mucho trabajo antes de que termine este golf! Debería poder tomar eso por debajo de 500 Bytes, como mínimo. Por el momento, es la primera solución que funcionó, y todavía estoy trabajando en ello.

Proporcionaré una explicación completa una vez que haya terminado.

function f(t)s=#t a=","for i=1,s do p=t[i]for i=1,s
do p.Q=p.Q and p.Q+p[i]or p[i]end p.Q=(p.Q*#p)%3 for i=1,s do for j=1,#p-1 do
x=p[j]y=p[j+1]u=x~=y and(p.S and p.R==p.S or x~=p.Q)v=(x+y)*2p[j]=u and v%3or x
p[j+1]=u and v%3or y print(i..a..j,i..a..j+1)end
p.R=p.S p.S=table.concat(p)end end
for i=1,s do Q=Q and Q+t[i][1]or t[i][1]end Q=(Q*s)%3 for i=1,s
do for j=1,s-1 do p=t[j]q=t[j+1]x=p[1]y=q[1]u=x~=y and(S and R==S or x~=Q)v=(x+y)*2
for k=1,#p do p[k]=u and v%3or x q[k]=u and v%3or y
print(j..a..k,j+1..a..k)end Y=Y and Y..x or x end
R=S S=Y end end
Katenkyo
fuente
5

Óxido, 496 495 bytes

Lamentablemente, no puedo vencer a OP, pero para una respuesta de Rust, estoy bastante satisfecho con el bytecount.

let s=|mut v:Vec<_>,c|{
let p=|v:&mut[_],f,t|{
let x=|v:&mut[_],i|{
let n=v[i]^v[i+1];v[i]=n;v[i+1]=n;
for k in f..t+1{print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});}};
let l=v.len();let t=(1..4).find(|x|l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
let mut i=0;while i<l{let c=v[i];if c==t{i+=1;}else if c==v[i+1]{
let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};x(v,j);}else{x(v,i);}}t};
p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|{p(x,i,i)}).collect::<Vec<_>>(),0,c-1usize)};

Entrada: un vector de números, así como el número de columnas. P.ej

s(vec!{1,2,1,3},2);

salidas

 (row1,col1,row2,col2)

a la línea de comando.

Primero resuelvo cada fila y luego resuelvo la columna resultante solo una vez, pero imprimo los pasos para todas las columnas. Por lo tanto, en realidad es bastante eficiente :-P.

Con formateo:

let s=|mut v:Vec<_>,c|{  
    let p=|v:&mut[_],f,t|{     // solves a single row/column
        let x=|v:&mut[_],i|{   // makes a move and prints it 
            let n=v[i]^v[i+1]; // use xor to calculate the new color
            v[i]=n;
            v[i+1]=n;
            for k in f..t{
                print!("{:?}",if f==t{(k,i,k,i+1)}else{(i,k,i+1,k)});
            }
        };
        let l=v.len();
        // find target color
        // oh man i am so looking forward to sum() being stabilized
        let t=(1..4).find(|x|(l*x)%3==v.iter().fold(0,|a,b|a+b)%3).unwrap();
        let mut i=0;
        while i<l{
            let c=v[i];
            if c==t{             // if the color is target color move on
                i+=1;
            }else if c==v[i+1]{ // if the next color is the same
                                // find the next possible move
                let j=if let Some(x)=(i+1..l).find(|j|v[j+1]!=c){x}else{i-=1;i};
                x(v,j);
            }else{              // colors are different so we can make a move
                x(v,i);         
            }
        }
        t
    };
    // first solve all rows and than sovle the resulting column c times 
    p(&mut (0..).zip(v.chunks_mut(c)).map(|(i,x)|p(x,i,i)).collect::<Vec<_>>(),0,c-1usize)
};

Editar: ahora devuelve el color de la solución que me ahorra un punto y coma ^^

desigual
fuente
5

Befunge , 197 368 696 754 Bytes


(sí, estoy haciendo golf de código inverso, cuantos más bytes, mejor)


Estaba pensando que podría ser un desafío escribir este algoritmo en Befunge y que podría ser divertido

Me gustaría que fuera un programa comunitario, así que si alguien quiere trabajar en él, por favor, hágalo.

Al final, hice todo solo hasta ahora, así que terminaré por mi cuenta (está casi listo)


Lo que está hecho todavía: un código en forma de troll

&:19p&:09p:v:p94g92g90  <
 v94+1:g94&_$59g1+59p1-:|
 >p59gp1-: ^    vp95g93$<
v94\-1<v:g<     >  v
>g:1+v^_$v^90p94g92<
v5p94<   3>1+59p   ^
>9gg+\:^ %g   v93:g95<           v3_2         v
v1pg95g94<^95<>g-v>$v^           v ^-%3*2\gg9<
>9g39g+59g-1-|v-1_^ #^pg95+g92g90<1_09g:29g+5^
       ;  >  >  09g:29g+59gg\3%-# !^v         <
          ^p95<                  ^  <
     v  p96-1+g90g92<
     v                  p95_@
            >59g1+:39g-19g-^
     v    >p 79g:59gg\1+59gp$$$$$29g49pv
    > p59g^ |<<<<<<<<<<<<<<<<<<!-g96g94<
>:79^>29g49p>69g1+59gg49g:59gg\1+49p- v
^\-\6+gg95+1\g< v         !-g96:<-1g94_^
>"]",52*,::59g^v_::1+59gg\59gg-v^ <
^ .-g93g95,.-g<>:69g- v  v-g96:_1+^
>+" [,]",,,\29^       >#v_$:49g2-v
^1:.-g93g95,.-g92\,"[ ":<        <

(sí, es un troll, créeme)


Básicamente, lee una matriz y calcula el movimiento a realizar para resolver las filas, dada una entrada como

(number of rows) (number of columns) 1 2 3 1 1 3 2 1 2 ....

(toda la matriz se pasa como una lista [fila1, fila2, fila3, ...])

la salida es

[col row],[col',row']
[col2 row2],[col2',row2']
...

las filas y los cols comienzan en 0.


Ahora que las filas están resueltas, ¡está casi listo! ¡Hurra!


Explicación: (se actualizará más adelante)

imagen

Entonces hay 5 partes principales:

  • El primero, en verde, lee la línea de entrada y escribe una fila de la matriz
  • El segundo, en naranja, pasa a la siguiente fila de la matriz.
  • El tercero, en azul, suma una fila.
  • El cuarto, en rosa fuerte, toma el módulo 3 de la suma, lo guarda a la derecha de la fila en cuestión y pasa a la siguiente fila
  • Finalmente, en rojo, la parte que calcula el color objetivo a partir del número calculado previamente. Esta parte es muy tonta y probablemente debería reescribirse, pero no descubrí cómo podría hacerlo de una manera agradable (pasó de 197 bytes a 368 con solo esa parte)

Las partes grises son inicializaciones


Aquí hay una explicación más profunda del módulo que encuentra las casillas para combinar (que está codificada aquí, por cierto)

                                       B
            @                          v
            |                  !-g96g94<
ENTRY>29g49p>69g1+59gg49g:59gg\1+49p- v
                v         !-g96:<-1g94_^
               v_::1+59gg\59gg-v^ <
               >:69g- v  v-g96:_1+^
                      >#v_$:49g2-v
                    CALL<        <

La parte CALL es cuando el puntero de instrucción va a otro módulo, para combinar en cajas. Vuelve a este módulo a través de la entrada 'B'

Aquí hay un pseudocódigo: (currentx está relacionado con la lectura de la matriz) Para:

    69g1+59gg  // read target color
    49g:59gg\1+49p // read current color and THEN shift the currentx to the next box
    if ( top != top ){  // if the current color is bad
        49g1-          //  put the current place  (or currentx - 1) in the stack
        While:
            if ( :top != 69g ){   // if you didn't reach the end of the list
                ::1+              // copy twice, add 1
                if ( 59gg == \59gg ){ // if the next color is the same than current
                   1+                // iterate
                   break While;
                }
            }

        : // copies j (the previous raw iterator)
        if ( top == 69g ){  // if you reached the end of the row (which mean you can't swap with the color after that point)
            $:              // discard j's copy and copy target
            49g2-           // put the place just before the color change on the stack
            combine_with_next;
        } else {
            combine_with_next;
        }
        29g49p   // back to the beginning of the row (there was some changes int the row)
    }

    if ( 49g != 69g ) // if you didn't reach the end of the list
        break For:

Tenga en cuenta que si desea probarlo, tendrá que poner algo de espacio final y nuevas líneas finales para que haya suficiente espacio para almacenar la matriz, si desea utilizar la interpretación que vinculé. 22 + el número de filas en la entrada como líneas finales, y 34 + el número de columnas como espacios finales en una línea debería estar bien.

Maliafo
fuente
Por curiosidad, ¿por qué esto no es competitivo?
Value Ink
Debido a esta parte: "Me gustaría que fuera un programa comunitario". Pensé que sería un poco tramposo de lo contrario
Maliafo
Tengo un resultado de 197 Bytes, ¿trabajas bajo Windows? (y contado en \r\nlugar de \nsolo?)
Katenkyo
Hm, supongo que copié algo pegado al contar los bytes, gracias
Maliafo
Si al final soy el único que lo hizo, borraré la mención, pero espero no hacerlo
Maliafo
2

C, 404 bytes

Mi primer código de golf, estoy bastante contento con cómo resultó. Sin embargo, tomó demasiado tiempo. No es completamente C estándar, solo lo que sea que se compilará bajo gcc sin banderas especiales (e ignorando las advertencias). Entonces hay una función anidada allí. La función ftoma las dimensiones my ncomo sus primeros argumentos, y como su tercer argumento toma toma un (int puntero) a una matriz de tamaño m× n(indexado por filas primero). Los otros argumentos son argumentos ficticios, no necesita pasarlos, solo están allí para guardar bytes en la declaración de variables. Escribe cada par modificado en STDOUT en el formato row1,col1:row1,col1;, con el punto y coma que separa los pares. Utiliza indexación basada en 0.

#define A a[i*o+p
#define B A*c
f(m,n,a,i,j,o,p,b,c,d)int*a;{
int t(x){printf("%d,%d:%d,%d;",b?i:c+x,b?c+x:i,b?i:c+1+x,b?c+1+x:i);}
o=n;p=b=1;for(;~b;b--){
for(i=0;i<m;i++){c=j=0;
for(;j<n;)c+=A*j++];d=c*n%3;
for(j=0;j<n-1;j++) 
while(A*j]^d|A*j+p]^d){
for(c=j;B]==B+p];c++);
if(c<n-2&B]==d&2*(B+p]+A*(c+2)])%3==d)
B+p]=A*(c+2)]=d,t(1);else
B]=B+p]=2*(B]+B+p])%3,
t(0);}}o=m;p=m=n;n=o;o=1;}}

Utilicé un algoritmo ligeramente diferente al OP para resolver filas / columnas individuales. Va algo como esto (pseudocódigo):

for j in range [0, rowlength):
    while row[j] != targetCol or row[j+1] != targetCol:
        e=j
        while row[e] == row[e+1]:
            e++             //e will never go out of bounds
        if e<=rowLength-3 and row[e] == targetCol 
                and (row[e+1] != row[e+2] != targetCol):
            row.changeColor(e+1, e+2)
        else:
            row.changeColor(e, e+1)

El for(;~b;b--)bucle se ejecuta exactamente dos veces, en la segunda pasada resuelve columnas en lugar de filas. Esto se realiza intercambiando ny m, y cambiando los valores de oy pque se utilizan en la aritmética del puntero para abordar la matriz.

Aquí hay una versión que no tiene golf, con una prueba principal, e imprime toda la matriz después de cada movimiento (presione enter para el paso 1 a su vez):

#define s(x,y)b?x:y,b?y:x
#define A a[i*o+p
#define B A*e
f(m,n,a,i,j,o,p,b,c,d,e)int*a;{

    int t(x){
        printf("%d,%d:%d,%d;\n",s(i,e+x),s(i,e+1+x));
        getchar();
        printf("\n");
        for(int i2=0;i2<(b?m:n);i2++){
            for(int j2=0;j2<(b?n:m);j2++){
                printf("%d ",a[i2*(b?n:m)+j2]);
            }
            printf("\n");
        }
        printf("\n");
    }

    printf("\n");
    b=1;
    for(int i2=0;i2<(b?m:n);i2++){
        for(int j2=0;j2<(b?n:m);j2++){
            printf("%d ",a[i2*(b?n:m)+j2]);
        }
        printf("\n");
    }
    printf("\n");

    o=n;p=1;
    for(b=1;~b;b--){
        for(i=0;i<m;i++){
            c=0;
            for(j=0;j<n;j++) c+= a[i*o+p*j];
            d=0;
            d = (c*n)%3;
            for(j=0;j<n-1;j++) {
                while(a[i*o+p*j]!=d||a[i*o+p*j+p]!=d){
                    for(e=j;a[i*o+p*e]==a[i*o+p*e+p];e++);
                    if(e<=n-3 && a[i*o+p*e]==d 
                            && 2*(a[i*o+p*e+p]+a[i*o+p*(e+2)])%3==d){
                        a[i*o+p*e+p]=a[i*o+p*(e+2)]=d;
                        t(1);
                    }else{
                        a[i*o+p*e]=a[i*o+p*e+p] = 2*(a[i*o+p*e]+a[i*o+p*e+p])%3;
                        t(0);
                    }
                }
            }
        }
        o=m;p=m=n;n=o;o=1;
    }
}

main(){
    int g[11][11] = 
    {
        {0,2,1,2,2,1,0,1,1,0,2},
        {2,1,1,0,1,1,2,0,2,1,0},
        {1,0,2,1,0,1,0,2,1,2,0},
        {0,0,2,1,2,0,1,2,0,0,1},
        {0,2,1,2,2,1,0,0,0,2,1},
        {2,1,1,0,1,1,2,1,0,0,2},
        {1,0,2,1,0,1,0,2,2,1,2},
        {0,0,2,1,2,0,1,0,1,2,0},
        {1,2,0,1,2,0,0,2,1,2,0},
        {2,1,1,0,1,1,2,1,0,0,2},
        {0,2,1,0,1,0,2,1,0,0,2},
    };
    #define M 4
    #define N 7
    int grid[M][N];
    for(int i=0;i<M;i++) {
        for(int j=0;j<N;j++) {
            grid[i][j] = g[i][j];
        }
    }
    f(M,N,grid[0],0,0,0,0,0,0,0,0);
};
Norg74
fuente
Solo por curiosidad: ¿por qué elegiste un algoritmo diferente (en términos de ahorro de bytes)?
Sanchises
1
Creo que es más interesante cuando las personas encuentran diferentes soluciones, y de algunas pruebas rápidas supuse que los dos métodos serían casi iguales en el recuento de bytes. Probablemente probaré tu algoritmo también y veré si puedo bajar.
Norg74
Publicar esto aquí porque no tengo suficiente representante para comentar la pregunta. ¿Sería válido aplicar fuerza bruta a cada fila, luego a cada columna individualmente? Eso técnicamente no es "forzarlo por completo" y debería ser inferior al límite de complejidad de tiempo especificado. De hecho, consideré hacer eso.
Norg74
La mención de fuerza bruta estaba destinada a intensificar el comentario de "tiempo razonable", así que véalo como t «O (...). Sé que hay un área gris entre la fuerza bruta y un algoritmo razonable, así que usa tu propio juicio sobre si sientes que está trabajando para resolver el rompecabezas o si es solo una ligera modificación en DFS o BFS que son agnósticos de 'progreso', por así decirlo .
Sanchises