Sua tarefa é desempenhar o papel de ambos os personagens nesta cena desde o início. Nele, Cobb desafia Ariadne:
Você tem dois minutos para projetar um labirinto que leva um minuto para resolver.
Algumas liberdades serão tomadas nessa descrição. Mais importante ainda, esse desafio não se baseia no tempo, mas as pontuações se baseiam na eficácia de seus labirintos e solucionadores de labirinto.
Peço desculpas pelas muitas edições deste desafio, pois iteramos em direção a um formato fácil e justo.
Parte I: Formato Labirinto
Todos os labirintos são quadrados. Uma célula no labirinto é representada como uma tupla indexada a zero row column
.
As paredes são representadas por duas cadeias binárias: uma para paredes horizontais (que bloqueiam o movimento entre linhas) e paredes verticais (vice-versa). Em um NxN
labirinto, existem Nx(N-1)
paredes possíveis de cada tipo. Vamos dar um exemplo 3x3 em que as células são rotuladas:
A B | C
---
D | E F
---
G H | I
todas as paredes verticais são possíveis: AB BC DE EF GH HI
. Traduzidas em uma sequência, as paredes mostradas são 011001
para paredes verticais e 010010
horizontais. Além disso, com "cadeia binária", quero dizer "os caracteres '0' e '1'".
O formato completo do labirinto é uma string que contém, nesta ordem:
- largura
- iniciar tupla de célula
- tupla da célula final
- paredes horizontais
- paredes verticais
Por exemplo, este labirinto:
0 1 2 3 4
_________
0 | | E| _|
1 | _|_|_ |
2 |_ _ _ | |
3 | _ _ | |
4 |____S|___|
start:(4,2)
end:(0,2)
está formatado para isso:
5
4 2
0 2
00001011101110001100
10100110000100010010
Parte II: O Arquiteto
O programa Architect cria o labirinto. Ele deve seguir as regras e fornecer um labirinto válido (aquele em que existe uma solução e o fim não está no topo do início).
Entrada: Dois números inteiros positivos:
size [random seed]
Onde size
estará [15, 50]
. Você é incentivado a usar a semente aleatória para que as correspondências possam ser repetidas, embora isso não seja necessário.
Saída: Um labirinto válido de tamanho x tamanho (quadrado) usando o formato descrito na Parte I. "válido" significa que existe uma solução e a célula inicial não é igual à célula final.
A pontuação de um arquiteto em um determinado labirinto é
# steps taken to solve
–––––––––––––––––––––––––––––
max(dist(start,end),(# walls))
Portanto, os arquitetos são recompensados por labirintos complexos, mas penalizados por cada parede construída (este é um substituto para a restrição de tempo de Ariadne). A dist()
função garante que um labirinto sem paredes não obtenha uma pontuação infinita. As bordas externas do labirinto não contribuem para a contagem de paredes.
Parte III: O Solver
O Solver tenta resolver labirintos gerados por arquitetos de outros. Existe uma espécie de nevoeiro de guerra: apenas paredes adjacentes às células visitadas são incluídas (todas as outras são substituídas por '?')
input: o mesmo formato de labirinto, mas com '?' onde as paredes são desconhecidas, uma linha extra para o local atual e uma lista separada por vírgulas de opções válidas desse local. (Esta é uma grande edição que visa facilitar a gravação de uma função de análise de labirinto)
exemplo (igual ao labirinto 5x5 acima depois de dar um passo à esquerda)
5
4 2
0 2
???????????????011??
????????????????001?
4 1
4 0,4 2
O que corresponde a algo assim, onde ?
está o nevoeiro:
0 1 2 3 4
_________
0 |????E????|
1 |?????????|
2 |?????????|
3 | ?_?_????|
4 |__C_S|_?_|
saída: uma das tuplas da lista de opções válidas
A pontuação de cada Solver é o inverso da pontuação do arquiteto.
Parte IV: Rei da Colina
Arquitetos e Solvers recebem pontuações separadas, então pode haver dois vencedores.
Cada par de arquitetos e solucionadores terá muitas chances de se superar. A pontuação será calculada sobre todos os testes e oponentes. Ao contrário do código das convenções de golfe, a pontuação média mais alta vence!
Pretendo que isso continue, mas não posso garantir testes contínuos para sempre! Digamos por enquanto que um vencedor será declarado em uma semana.
Parte V: Enviando
- Eu mantenho poder de veto sobre todos os envios - a inteligência é incentivada, mas não se quebrar a concorrência ou o meu computador! (Se eu não souber o que seu código faz, provavelmente vou vetá-lo)
- Crie um nome para o seu par Arquiteto / Solver. Poste seu código junto com instruções sobre como executá-lo.
Em breve: um kit de teste python atualizado para o novo formato. Ocorreram grandes mudanças para permitir envios de idiomas.
fonte
Respostas:
BuildFun e SolveFun
Bem, isso levou um bom tempo e não tenho certeza se o solucionador está trapaceando ou não. Embora tenha acesso a todo o labirinto o tempo todo, ele olha apenas para a célula em que está, as paredes ao redor e, se não houver uma parede entre elas, as células adjacentes a ela. Se isso for contra as regras, entre em contato e tentarei alterá-lo.
Enfim, aqui está o código:
Percebo que isso é ridiculamente longo e não é particularmente fácil de ler, mas sou preguiçoso, e é assim que as coisas ficam.
BuildFun
O arquiteto, BuildFun, é um programa bastante simples de geração de labirinto que sempre criará um labirinto 'perfeito' (um sem loops e onde dois pontos sempre terão exatamente um caminho entre eles). Ele baseia sua lógica na entrada de sementes, o que significa que os labirintos gerados são pseudo-aleatórios com o que geralmente parece ser padrões repetidos e, com a mesma semente e tamanho, o mesmo labirinto será criado.
Uma vez que o labirinto é gerado, o programa tentará maximizar a pontuação do labirinto procurando o ponto inicial e final que resultam no caminho mais longo entre eles. Para fazer isso, ele percorre todos os pontos de partida, espalha traçadores para encontrar o ponto final mais distante e escolhe a combinação com o caminho mais longo.
Depois disso, ele desenha o labirinto, conta as paredes e exibe as informações do labirinto. Este é o ponto inicial, final, distância entre eles, número de paredes e pontuação. Ele também formata essas informações no estilo descrito acima para tamanho, início e fim, paredes horizontais e paredes verticais e as salva em um arquivo de texto chamado Maze.txt para uso posterior.
SolveFun
O solucionador, o SolveFun, usa o arquivo de texto Maze.txt como entrada e funciona de maneira muito semelhante ao arquiteto. Para cada movimento, ele escolherá a direção que deseja seguir com base em sua posição relativa até o fim e, em seguida, examinará as paredes ao seu redor. Se não houver uma parede, ela verificará se esteve na célula adjacente a ela e, se não estiver, será adicionada como opção possível. Ele se moverá na direção mais próxima da direção preferida, desde que tenha opções. Se não tiver opções, retornará até que tenha. Isso continua até chegar ao fim.
À medida que se move, registra o caminho que está seguindo no caminho variável que é usado no final para gerar o número total de etapas. Ele também registra a quantidade de vezes que teve que voltar atrás usada para calcular etapas desperdiçadas no final. Quando chegar ao fim, ele produzirá o labirinto com o caminho mais curto do início ao fim marcado com
*
s.Como executar
Devido ao método de saída do labirinto (que inclui sublinhado de certos caracteres), isso deve ser executado a partir de uma linha de comando no formato
python -c 'import filename;filename.BuildFun(Size, Seed)'
e
python -c 'import filename;filename.SolveFun()'
onde Tamanho é um número inteiro entre 15 e 50 (inclusive) e Semente é um número inteiro entre 4 e Tamanho (inclusive).
fonte