Resolver o quebra-cabeça cromático


35

Em nossos amigos do Puzzling.SE , foi publicado o seguinte quebra-cabeça: Esse quebra-cabeça cromático é sempre solucionável? by Edgar G. Você pode reproduzi-lo aqui .

Explicação do quebra-cabeça

Dada uma m x ngrade com peças de três cores diferentes, você pode selecionar duas peças adjacentes , se as cores forem diferentes . Esses dois ladrilhos são convertidos para a terceira cor, ou seja, a única cor não representada por esses dois ladrilhos. O quebra-cabeça é resolvido se todas as peças tiverem a mesma cor . Aparentemente, pode-se provar que este quebra-cabeça é sempre solucionáveis, se nem mnem nsão divisíveis por 3.

Quebra-cabeça 8x8 de três cores

Obviamente, isso implora por um algoritmo de solução. Você escreverá uma função ou programa que resolve esse quebra-cabeça. Observe que funções com 'efeitos colaterais' (ou seja, a saída está ativada stdoute não em algum valor de retorno de tipo de dados estranho) são explicitamente permitidas.

Entrada e Saída

A entrada será uma m x nmatriz consistindo dos inteiros 1, 2e 3(ou 0, 1, 2se conveniente). Você pode receber esta entrada em qualquer formato são. Ambos me nsão >1e não são divisíveis por 3. Você pode assumir que o quebra-cabeça não foi resolvido

Você então resolverá o quebra-cabeça. Isso envolverá uma seleção repetida de dois blocos adjacentes a serem 'convertidos' (veja acima). Você produzirá as duas coordenadas desses blocos para cada etapa executada pelo algoritmo de resolução. Isso também pode estar em qualquer formato de saída sã. Você pode escolher entre a indexação com base em 0 e com base em 1 de suas coordenadas e se as linhas ou colunas são indexadas primeiro. Por favor, mencione isso em sua resposta.

Seu algoritmo deve ser executado dentro de um prazo razoável no gabinete 8x8 original. Forçar brutalmente completamente é explicitamente proibido, ou seja, seu algoritmo deve ser executado O(k^[m*(n-1)+(m-1)*n])com ko número de etapas necessárias para a solução. A solução, no entanto, não precisa ser ideal. A prova fornecida na pergunta vinculada pode fornecer uma idéia de como fazer isso (por exemplo, primeiro faça todas as colunas usando apenas blocos adjacentes verticalmente e, em seguida, todas as linhas)

Casos de teste

Nesses casos de teste, as coordenadas são baseadas em 1 e as linhas são indexadas primeiro (como MATLAB / Octave e provavelmente muitas outras).

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]

Se desejar, posso postar uma pasta de casos de teste maiores, mas acho que isso deve ser suficiente.


Eu adoraria ver uma versão de desafio de código disso, onde o objetivo é resolver um conjunto de quebra-cabeças com o mínimo de movimentos totais.
Mego

@ Mega definitivamente eu considerei isso. No entanto, receio que isso se transforme em um DFS ou BFS, que levará uma eternidade para ser executado; ou, para evitar isso, um conjunto de restrições vagas (como 'deve ser executado dentro de uma hora', que favorece as pessoas com um computador enorme ou que exige que eu teste todas as soluções). Além disso, o desafio atual tem zero respostas e não as minhas, por isso duvido que uma versão ainda mais difícil que exija heurísticas, etc., se mostre mais popular ... Mas, se esse desafio ganhar impulso, posso postar um desafio como você. descrever.
Sanchises

Acho que vou tentar fazer isso em Lua, mas pode ser maior que a sua solução de 324 bytes ^^
31416

@Katenkyo Apenas uma maneira de descobrir! Estou ansioso para ver sua solução.
Sanchises 07/07

Você vai ter que esperar solução de força bruta um pouco triste, você impedido por isso tenho de encontrar uma solução que é curto na lua: p
Katenkyo

Respostas:


5

Ruby, 266 bytes

Mais ou menos, apenas uma porta da solução Octave, exceto que ela resolve primeiro as linhas, em vez das colunas. Entrada é uma matriz de matrizes, com as matrizes internas sendo as linhas. Movimentos de saída são [row, column, row, column]. Suíte de teste

->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]}}

Ungolfed com explicação

->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)

Interessante ver que uma porta entre dois idiomas que não são de golfe ainda pode fazer uma diferença de ~ 20%. Talvez você possa adicionar uma breve explicação (especialmente linha 3 - Eu estou secretamente esperando que eu possa usar isso na minha resposta desde então? intersectÉ uma palavra-chave, tais volumosos)
Sanchises

@sanchises uma explicação foi adicionada. Em relação a intersect, não sei se você pode consertar isso da maneira como o meu funciona, porque Ruby findbasicamente opera em funções, e sua functionpalavra-chave é igualmente volumosa.
Value Ink

Na verdade, eu ainda poderia usar seu método para find- obrigado! Ainda assim, em nenhum lugar perto de bater-lhe ...
Sanchises

13

Oitava, 334 313 bytes

Como o desafio pode parecer um pouco assustador, apresento minha própria solução. Não provei formalmente que esse método funciona (acho que tudo se resume a provar que o algoritmo nunca ficará preso em um loop), mas até agora funciona perfeitamente, executando testes de 100x100 em 15 segundos. Observe que eu escolhi usar uma função com efeitos colaterais em vez de uma que retorna todas as coordenadas, pois isso me salvou alguns bytes. As coordenadas são de linha principal, com base em 1 e formatadas como row1 col1 row2 col2. As cores de entrada são 0,1,2uma vez que isso funciona melhor com mod, ao custo de ter que usar em numelvez dennz . Versão em golfe: Editar: salvou mais alguns bytes usando uma técnica da resposta 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

Exemplo de GIF do algoritmo de resolução:

insira a descrição da imagem aqui

Versão não destruída:

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

Só notei, mas meu nome não é Kenny Lau ... isso é outro usuário e meu nome de usuário afirma especificamente que eu não sou Kenny
Valor Ink

7

Lua, 594 575 559 bytes

Aviso Ainda há muito trabalho antes de terminar este golfe! Eu deveria ser capaz de suportar menos de 500 bytes, no mínimo. No momento, é a primeira solução que funcionou, e ainda estou trabalhando nisso.

Vou fornecer uma explicação completa quando terminar.

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

5

Ferrugem, 496 495 bytes

Infelizmente, não consigo vencer o OP, mas, para uma resposta do Rust, estou bastante satisfeito com o 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: um vetor de números, bem como o número de colunas. Por exemplo

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

saídas

 (row1,col1,row2,col2)

para a linha de comando.

Primeiro resolvo todas as linhas e depois resolvo a coluna resultante apenas uma vez, mas imprimo as etapas para todas as colunas. Portanto, é realmente bastante eficiente :-P.

Com formatação:

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)
};

Edit: agora retorna a cor da solução que me poupa ponto e vírgula ^^


5

Befunge , 197 368 696 754 Bytes


(sim, estou praticando golfe com código reverso, quanto mais bytes, melhor)


Eu estava pensando que poderia ser um desafio escrever esse algoritmo no Befunge e que poderia ser divertido

Eu gostaria que fosse um programa comunitário, portanto, se alguém quiser trabalhar nele, faça-o.

No final, eu fiz tudo sozinho até agora, então vou terminar por conta própria (está quase pronto)


O que foi feito ainda: um código em 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\,"[ ":<        <

(sim, é um troll, acredite em mim)


Basicamente, ele lê uma matriz e calcula a movimentação a ser feita para resolver as linhas, dada uma entrada como

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

(toda a matriz é passada como uma lista [linha1, linha2, linha3,…])

saída é

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

linhas e colunas começam em 0.


Agora que as linhas estão resolvidas, está quase pronto! Viva!


Explicação: (será atualizado posteriormente)

imagem

Portanto, existem 5 partes principais:

  • O primeiro, em verde, lê a linha de entrada e grava uma linha da matriz
  • O segundo, em laranja, passa para a próxima linha da matriz
  • O terceiro, no azul, soma uma linha
  • O quarto, em rosa quente, pega o módulo 3 da soma, salva à direita da linha em questão e passa para a próxima linha
  • Finalmente, no vermelho, a parte que calcula a cor de destino a partir do número calculado anteriormente. Esta parte é realmente idiota e provavelmente deveria ser reescrita, mas não descobri como poderia fazer isso de uma maneira agradável (passada de 197 bytes para 368 com apenas essa parte)

Peças cinzas são inicializações


Aqui está uma explicação mais profunda do módulo que encontra as caixas a serem combinadas (que são codificadas aqui, a propósito)

                                       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<        <

A parte CALL é quando o ponteiro da instrução está indo para outro módulo, para combinar com as caixas. Volta a este módulo através da entrada 'B'

Aqui está um pseudo-código: (currentx está relacionado à leitura da matriz)

    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:

Observe que, se você quiser testá-lo, terá que colocar algum espaço à direita e novas linhas à direita para que haja espaço suficiente para armazenar a matriz, se desejar usar a interpretação que eu vinculei. 22 + o número de linhas na entrada como linhas finais, e 34 + o número de colunas como espaços finais em uma linha deve estar ok.


Apenas curioso, por que isso não é competitivo?
Value Ink

Por causa desta parte: 'Eu gostaria que fosse um programa comunitário'. Eu pensei que seria um pouco de trapaça caso contrário
Maliafo 07/07

Eu tenho um resultado de 197 bytes, você trabalha no Windows? (e contado em \r\nvez de \napenas?) #
284

Hm, acho que copiar colado alguma fuga ao contar os bytes, obrigado
Maliafo

Se no final eu sou o único que fez isso, eu vou apagar a menção, mas eu espero que eu não vou
Maliafo

2

C, 404 bytes

No meu primeiro código de golfe, estou muito feliz com o resultado. Levou muito tempo, no entanto. Não é totalmente C padrão, o que quer que seja compilado no gcc sem sinalizadores especiais (e ignorando avisos). Portanto, há uma função aninhada lá. A função fassume as dimensões me, ncomo seu primeiro argumento, e, como seu terceiro argumento, leva um (ponteiro int) para uma matriz de tamanho m× n(indexada pelas linhas primeiro). Os outros argumentos são argumentos fictícios, você não precisa passá-los, eles estão lá apenas para salvar bytes em variáveis ​​declarantes. Ele grava cada par alterado em STDOUT no formato row1,col1:row1,col1;, com o ponto e vírgula separando os pares. Usa indexação baseada em 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;}}

Usei um algoritmo ligeiramente diferente do OP para resolver linhas / colunas individuais. É mais ou menos assim (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)

O for(;~b;b--)loop é executado exatamente duas vezes, na segunda passagem ele resolve colunas em vez de linhas. Isso é feito trocando ne malterando os valores de oe pque são usados ​​na aritmética do ponteiro para endereçar a matriz.

Aqui está uma versão não-destruída, com um teste principal, e imprime toda a matriz após cada movimento (pressione enter para a etapa 1 volta):

#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);
};

Apenas por curiosidade: por que você escolheu um algoritmo diferente (em termos de economia de bytes)?
Sanchises 9/07/2016

11
Eu acho que é mais interessante quando as pessoas apresentam soluções diferentes e, a partir de alguns testes rápidos, acho que os dois métodos seriam os mesmos na contagem de bytes. Provavelmente vou tentar seu algoritmo também e ver se consigo diminuir.
Norg74

Postando isso aqui porque não tenho representante suficiente para comentar a questão. Seria válido aplicar força bruta em cada linha e depois em cada coluna individualmente? Tecnicamente, isso não é "forçar brutalmente completamente" e deve ser menor que a complexidade de tempo especificada. Na verdade, eu considerei fazer isso.
Norg74

A menção forçadora bruta destinava-se a intensificar a observação do 'tempo razoável'; Eu sei que há uma área cinzenta entre a força bruta e um algoritmo razoável, então use seu próprio julgamento sobre se você acha que ele está trabalhando para resolver o quebra-cabeça ou se é apenas uma ligeira modificação no DFS ou no BFS que é independente do 'progresso', por assim dizer. .
Sanchises
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.