Anexo , 51 bytes
{[3,3]&Rotate[Sample[{Sum@_=_2}&_\BinBelow@8]'_,4]}
Experimente online!
Explicação
Igual a resposta J / APL de Galen , a técnica básica é gerar uma matriz de 1s e 0s com o número correto de minas, inserindo a entrada anexando-a ao final, girando a matriz de modo que a entrada fique no centro e depois remodelando em uma matriz 3x3.
Parte 1: gerando a matriz binária
Existem várias maneiras de fazer isso, mas eu deparei principalmente com dois tipos: força bruta e seleção.
O método primário de força bruta se parece com isso:
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
Isso gera matrizes aleatórias de 8 dígitos binários ( Random[8&2]
) enquanto suas somas não são iguais à entrada {Sum@_/=_2}&_
. Isso é um pouco detalhado, pois as seguintes partes enfatizadas do código existem "apenas para fazê-lo funcionar":
NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
^ ^^^^^ ^^^^
E eu descartei a ideia.
A seleção é mais interessante. O conceito principal é usar o BaseBelow[b, n]
builtin, que gera uma lista de todos os b
números inteiros base da larguran
(como matrizes de dígitos), de 0
até b^n-1
. Por exemplo, BaseBelow[3, 2]
gera todos os números inteiros ternários de largura 2:
A> BaseBelow[3, 2]
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
Nós usamos especificamente BaseBelow[2, 8]
para todos os números inteiros binários de largura 8. Eles representam todos os campos minados possíveis de todos os comprimentos. Este é o primeiro passo.
O segundo passo é selecionar todas essas matrizes apenas N
1s, onde N
está a entrada. Minha primeira idéia foi traduzir essa declaração em inglês diretamente no Attache:
Chunk[SortBy[Sum,BaseBelow[2,8]],Sum]@N@1
No entanto, isso não apenas resultou em 1 byte mais do que a abordagem mencionada, como também é altamente repetitivo - e ainda nem foi randomizado! Claro, eu provavelmente poderia economizar 1 byte reorganizando como BaseBelow
é chamado, mas simplesmente não vale a pena usar a abordagem.
Então, decidi matar dois coelhos com uma cajadada e usar uma Shuffle
abordagem baseada. A seguir, são apresentados todos os campos minados válidosN
em ordem aleatória:
{Sum@_=_2}&N\Shuffle[BaseBelow&8!2]
Então, tudo o que precisa ser feito é selecionar o primeiro. Mas posso fazer melhor - certamente seria melhor simplesmenteSample
a matriz filtrada? Essa abordagem acaba sendo algo assim:
Sample[{Sum@_=_2}&_\BaseBelow[2,8]]
Eu tive que reverter o BaseBelow&8!2
golfe porque \
a precedência é muito alta. Caso contrário, satisfeito, passei a cortar um byte disso:
Sample[{Sum@_=_2}&_\2&BaseBelow@8]
(Descobri outra maneira de chamar sucintamente uma função diádica aqui: x&f@y
é uma expressão de alta precedência que é avaliada como f[x, y]
).
No entanto, apesar disso, eu me lembrei que, o tempo todo, um alias para 2&BaseBelow
existido: BinBelow
. Então eu usei isso:
Sample[{Sum@_=_2}&_\BinBelow@8]
Isso gera o campo minado desejado. Estou convencido de que isso é quase ideal.
Parte 2: formando a matriz
Como dito anteriormente, a técnica de formação que usei é semelhante à resposta J / APL, portanto não entrarei em muitos detalhes. Suponha que MINEFIELD
é o resultado da última seção. A função então se torna:
{[3,3]&Rotate[MINEFIELD'_,4]}
MINEFIELD'_
concatena o campo minado com a entrada original _
, dando-nos algo como isto:
[1, 0, 0, 0, 1, 0, 0, 1, 3]
Em seguida, Rotate[MINEFIELD'_,4]
gire esta lista 4
vezes para a esquerda, colocando o centro:
[1, 0, 0, 1, 3, 1, 0, 0, 0]
A última etapa está sendo usada [3,3]&
para remodelar a lista em uma matriz 3x3:
1 0 0
1 3 1
0 0 0
1
e0
?