Calcular a 3BV de uma prancha de minas

17

A 3BV de uma placa Minesweeper representa o número mínimo de cliques esquerdos necessários para resolver a placa, se você já conhece a solução. Significa "Valor de referência do conselho da Bechtel". Aqui está o site dele explicando isso.

Abaixo está uma placa do Campo Minado resolvida. As bandeiras indicam minas; ladrilhos sem minas indicam a contagem de minas adjacentes, inclusive na diagonal, exceto que os ladrilhos que deveriam ter "0" são deixados em branco. A imagem mostra em quais blocos é necessário clicar para resolver o quadro.

Os cliques contados no 3BV são:

• Um para cada área cheia de ladrilhos em branco (zero minas adjacentes) e seus vizinhos não em branco.

Outro exemplo (3BV = 39)

Dada uma matriz de valores 2D, `0`para clear e `1`para uma mina (ou um booleano), retorne o 3BV .

As dimensões de uma placa terão pelo menos 8x8 e, no máximo, 24x30, inclusive. Seu programa deve lidar com todas as placas possíveis, não apenas com os exemplos.

Nota: Um tabuleiro nunca conterá apenas minas.

Exemplo de E / S:

``````[[0,0,0,0,0,0,0,0],
[0,0,0,1,0,0,0,0],
[0,0,0,1,0,0,1,0],
[0,1,0,0,1,0,0,0],
[0,0,1,0,0,0,0,1],
[0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,1]]

23

[[0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0],
[0,0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,0],
[0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,1,0,0,0,1,0,1,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,1,0,0,1,1,0,0,0],
[0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,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,1,0,1,0,0,1,1,0,1],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1],
[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,1,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
[0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0],
[1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1],
[0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,0,0,0,0,1,1,0,0],
[0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,1,1,0,0,0,1,0,0,0,1,1,0,0],
[0,1,1,1,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],
[0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,0],
[0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0]]

187
``````

Uma matriz de números inteiros está correta como entrada? Cada número inteiro codifica uma linha.
Karl Napf

@KarlNapf Não. A entrada deve ser reconhecível como uma placa, como mostrado.
mbomb007

Você poderia fornecer mais casos de teste, possivelmente incluindo a entrada com base nas imagens exibidas, e talvez um caso de teste de dimensões máximas?
milhas

Respostas:

15

MATLAB, 92 90 86 83 79 74 72 bytes

``````x=input('');I=@(x)~imdilate(x,ones(3));[C,N]=bwlabel(I(x));nnz(I(C)-x)+N
``````

Esta solução aceita a entrada na forma de uma matriz 2D de 0 e 1 e exibirá o valor de 3 VB para a entrada fornecida.

Aqui está uma demonstração ligeiramente modificada no Octave para aqueles que não têm o MATLAB.

Explicação

A matriz de entrada é dilatada usando uma matriz de 3 x 3 de `1`'s e depois invertida (usando `~`) que identifica todos os pontos que não possuem minas como vizinhos ( `1`) ou fazem ( `0`). Para determinar o número de regiões conectadas, usamos `bwlabel`para rotular cada região conectada de `1`'s. A primeira saída é a matriz de rótulo ( `0`onde a entrada era zero e qualquer valor no intervalo `1...N`em que havia um `1`na entrada onde `N`está o índice do grupo conectado ao qual ele pertence). A segunda saída é o número de regiões (o número de cliques necessários para abri-las). O resultado `bwlabel`é mostrado na imagem à esquerda.

Expandimos a primeira saída do `bwlabel`uso `imdilate`(todos os não-zeros são expandidos) usando uma matriz de 3 x 3 de `1`'s. O resultado é mostrado na imagem ao meio.

Para determinar os cliques restantes, contamos os quadrados que não estão nessa região expandida ( `~imdilate()`) e não são uma mina ( `-x`) (quadrados brancos na imagem à direita) e adicionamos isso ao número total de regiões abertas (o número de cores diferentes na imagem à esquerda) para obter o 3BV.

9

Oitava, 86 84 79 66 bytes

``````@(x)nnz(~imdilate(c=imerode(~x,o=ones(3)),o)-x)+max(bwlabel(c)(:))
``````

Esta solução cria uma função anônima nomeada `ans`que pode ser passada para uma matriz 2D de `0`'s `1`' e 's. A lógica é a mesma da minha resposta do MATLAB, mas usa alguns truques que o Octave tem a oferecer para economizar espaço.

Esta solução requer que o `image`pacote esteja instalado.

Demonstração aqui

2

MATL, 24 22 21 bytes (não concorrente)

1 byte salvo graças a @Luis

``````4Y6Z+~l2#ZIw7MZ+G+~z+
``````

Experimente no MATL Online

Explicação

Novamente, isso é semelhante às minhas respostas MATLAB e Octave a esta pergunta.

``````        % Implicitly grab input array
4Y6     % Push the literal [1 1 1; 1 1 1; 1 1 1] to the stack
Z+      % Perform 2D convolution of the input with this array
~       % Negate the result
l2#ZI   % Call bwlabeln which dilates each open region and the second output
% returns the number of open regions
w       % Flip the top two stack elements
7M      % Push the literal [1 1 1; 1 1 1; 1 1 1] to the stack again
Z+      % Perform 2D convolution
G+      % Explicitly grab the input and add it to the result
~z      % Count the number of 0's in the result (the remaining number of clicks)
+       % Add the total number of remaining clicks to the number of open regions
``````

Por que não é competitivo?
CalculatorFeline

11
@CalculatorFeline Infelizmente, a `bwlabeln`funcionalidade foi introduzida no MATL após o lançamento do desafio.
Suever
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.