Peg solitaire é um jogo popular geralmente jogado sozinho. O jogo consiste em algum número de pinos e um tabuleiro dividido em uma grade - geralmente o tabuleiro não é retangular, mas para esse desafio, assumiremos isso.
Cada jogada válida permite remover um único pino e o objetivo é jogar de uma maneira, de modo que exista um único pino. Agora, um movimento válido deve estar em uma única direção (norte, leste, sul ou leste) e pular sobre uma estaca que pode ser removida.
Exemplos
Sejam .
espaços vazios no quadro e os números são pinos, o movimento a seguir se moverá 1
um para a direita e será removido 2
do quadro:
..... .....
.12.. -> ...1.
..... .....
Uma jogada sempre terá que pular um único pino, portanto o seguinte não é válido:
...... ......
.123.. -> ....1.
...... ......
Aqui estão algumas configurações válidas após um movimento cada:
...1... ...1... ..71... ..71...
.2.34.5 ---> .24...5 ---> .2....5 ---> ......5
.678... (4W) .678... (7N) .6.8... (2S) ...8...
....... ....... ....... .2.....
Desafio
Dada uma configuração inicial da placa e alguma outra configuração, verifique se a outra configuração pode ser alcançada movendo os pinos sucessivamente, como descrito acima.
Regras
- A entrada será uma matriz / lista de listas / ... de valores indicando um espaço vazio (por exemplo, zero ou falso) ou pegs (por exemplo, diferente de zero ou verdadeiro)
- você pode assumir que e
- você pode usar true / diferente de zero para indicar espaços vazios e vice-versa, se isso ajudar
- Saída será duas distinta (um dos valores pode ser diferente) valores que indicam se a configuração final pode ser atingido (por exemplo. Falsas / truthy ,
[]
/[list of moves]
..)
Casos de teste
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
7
no seu exemplo? Por que desaparece depois de2
se mudar para o sul?Respostas:
JavaScript (ES6),
184 178173 bytes(initial_board)(target_board)
Experimente online!
(removeu os dois últimos casos de teste que levam muito tempo para o TIO)
Comentado
fonte
Limpo , 232 bytes
Experimente online!
Essa é uma das raras ocasiões em que posso utilizar composição e curry enquanto poupando bytes.
Explicado:
@ :: [Int] -> [[Int]]
é uma função auxiliar usada para gerar as diferentes novas linhas / colunas em potencial que podem resultar de uma movimentação. Isso evita a necessidade de um caso especial[1,1,0:_]
, notando quea*b-c>0
somente quando[a,b,c]=[1,1,0]
e, portanto,take(a*b-c)...
fornece[]
capturas-1
ou0
elementos para todas as configurações que não são válidas.flip elem o...
reverte a ordem dos argumentos paraelem
(fazer com que "x contenha um y" em vez de "é xa membro de y") e aplica a função anônimac
ao primeiro argumento.\c=limit(iterate(nub o concatMap ...)[c])
gera todos os painéis potenciais que podem resultar dissoc
, juntando o conjunto atual de painéis com todos os movimentos que podem ocorrer em todos os painéis e removendo as duplicatas, até que o resultado pare de mudar.\l=[l]++...
anexa o quadrol
à lista de todas as possíveis novas placas a uma distância de distância, geradas aplicando@
às linhas de cada orientação do quadro (rotações de 0, 90, 180, 270 graus) e substituindo a linha alterada correspondente pelo novo linha.fonte