TL; DR : resolva esse desafio em particular, uma simulação de robô, pisando em todos os painéis brancos e evitando os painéis cinza. Você pode pisar em um painel branco quantas vezes quiser, desde que pisar em cada painel branco pelo menos uma vez. Soluções em idiomas como o Befunge com um ponteiro de instrução 2D também seriam aceitas, mas H vem com o programa uHerbert e suas especificações de idioma são fornecidas abaixo. Você não precisa do programa uHerbert para resolver isso, mas facilita muito a verificação da sua solução.
Aqui está a aparência do nível. Essa é uma grade de células 25x25, na qual o robô e cada bloco branco e cinza ocupam uma célula. O robô está inicialmente voltado para cima.
Informações sobre o uHerbert
Herbert é uma simulação de robô que encontrei pela primeira vez no desafio de programação online do IGF (Independent Games Festival) em 2008. Durante muito tempo, fiquei desapontado por não poder experimentar os desafios após o término do concurso. Felizmente, alguém deve ter lido minha mente e codificado esse pequeno programa: dHerbert (também conhecido como mu-Herbert ou micro-Herbert).
H (Especificações de idioma)
O programa é uma simulação de robô, mas também atua como intérprete para a linguagem de programação H, que serve apenas para mover o robô.
Existem três instruções:
- S: o robô dá um passo à frente
- L: o robô vira à esquerda 90 graus no lugar
- R: o robô vira à direita 90 graus no lugar
Existem três recursos de programação padrão à sua disposição: funções, parâmetros e recursão. Dois tipos diferentes de parâmetros são suportados.
Parâmetros numéricos
g(A):sslg(A-1)
Aqui, g é uma função com um parâmetro numérico. Este é o código da placa da caldeira; Depois disso, você pode escrever seu programa real chamando sua função e transmitindo um argumento:
g(4)
Isso chamaria sua função 4 vezes e a recursão será encerrada automaticamente quando seu parâmetro A
atingir um valor zero:
g(4) = sslg(4-1) = sslg(3) = sslsslg(2) = sslsslsslg(1) = sslsslsslssl
Parâmetros funcionais
Você também pode usar parâmetros funcionais, que basicamente reproduzem instruções que você passa:
f(A):rAlA
Portanto, se você chamar essa função e passar instruções, ele avaliaria:
f(ss) = rsslss
f(sslssr) = rsslssrlsslssr
Outra sintaxe
As funções podem ter mais de um parâmetro e também podem ter os dois tipos. Como alternativa, eles não podem ter parâmetros. A seguir, são duas funções válidas:
j:ssss
k(A,B):Ajjjk(A,B-1)
Como você pode ver, a função j não aceita parâmetros e a função k usa os dois tipos de parâmetros. A é um parâmetro funcional e B é um parâmetro numérico, como descrito acima.
Recursão infinita
A recursão infinita também é permitida, mas só pode ser iniciada uma vez e é efetivamente encerrada quando você pisar no bloco branco final (sem ter pisado em nenhum bloco cinza):
m:sslssrm
Resolver condição
O objetivo é fazer com que o robô pise em todas as almofadas brancas e evite pisar em qualquer uma das almofadas cinza. As almofadas brancas podem ser pisadas inúmeras vezes, desde que cada uma seja pisada pelo menos uma vez. O robô é capaz de pisar em qualquer ponto da grade que possa alcançar (alguns níveis têm paredes de barreira e, nesse nível, as almofadas cinza agem como uma barreira).
O quebra-cabeça mostrado anteriormente está disponível no site acima em level_pack2.zip e é chamado level3.txt . Tanto o programa uHerbert quanto o pacote de níveis ainda estão disponíveis no link acima a partir de hoje (o site foi arquivado, mas o mecanismo de arquivamento ainda o hospeda), mas não é necessário para uma solução.
Gostaria de ver a solução mais curta possível, conforme o código de golfe. Soluções em idiomas diferentes de H não serão aceitas como válidas. (Seria certamente interessante ver um exemplo de solução em um idioma como o Befunge, onde o ponteiro de instrução viaja em uma grade 2D, mas, por pontuação de golfe com código atômico, apenas as instruções H podem receber uma pontuação precisa. O ponteiro de instrução pode ser tratado como a posição do robô, por exemplo.) Uma solução válida é aquela em que o robô pisa em todas as almofadas brancas (cada uma pelo menos uma vez) e não nas almofadas cinza. Pisar em outras partes da grade é bom, mas neste quebra-cabeça em particular você não pode fazer isso sem pisar em um bloco cinza. A posição inicial do robô não pode ser alterada.
Devo também observar que soluções que saltam para uma célula não adjacente não serão aceitas. Isso não é possível para o robô na simulação e não representaria uma solução válida. H não permite isso de qualquer maneira. Portanto, uma solução válida deve ser composta por etapas únicas. Para cada célula na grade, existem apenas quatro células adjacentes: as ortogonais a ela (acima, abaixo e à esquerda e direita). Obviamente, isso não permitiria etapas na diagonal, mas como você só pode girar em incrementos de 90 graus, as etapas na diagonal nem são possíveis.
Se o robô recebe uma instrução que exige que ele se mova para uma barreira ou fora da grade, o resultado é basicamente "derp" - o robô bate na parede e permanece onde está, e o ponteiro da instrução passa para a próxima instrução (a instrução a instrução é basicamente ignorada).
Nota sobre o tamanho da solução
Quando você abre esse nível no programa, notará que é aparentemente possível resolver em 13 bytes. Estou totalmente confuso sobre como isso é possível, e curioso para ver o quão perto os outros são capazes de chegar a isso. Minha solução mais curta é 30 bytes em H. Se alguém quiser que eu a publique, eu o farei, mas gostaria de ver outras soluções antes de postar as minhas. O programa também fornece uma pontuação, mas a pontuação é irrelevante para esta pergunta. Soluções de qualquer pontuação serão aceitas.
Parece que o programa uHerbert não conta parênteses ou dois pontos como parte do seu programa (você verá isso quando contar os bytes). Portanto, para os fins desta pergunta, na linguagem H, parênteses e dois pontos não contarão como bytes para a sua solução, pois são principalmente delimitadores e puramente sintáticos em vez de semânticos.