Votre tâche consiste à écrire un interpréteur RoboZZle. Si vous n'êtes pas familier avec le jeu, veuillez regarder la vidéo sur robozzle.com ou lire ma description ci-dessous.
Un robot vit sur une grille rectangulaire de carrés de couleur rouge, verte, bleue ou noire. Les carrés noirs sont inaccessibles. Les autres sont accessibles et certains contiennent une étoile. Le but est de collecter toutes les étoiles sans marcher sur les carrés noirs ni tomber de la carte. Le robot occupe une case et fait face à une direction particulière - gauche, droite, haut ou bas. Il suit les instructions de type assemblage regroupées en sous-programmes F1, F2, ..., F5. Une instruction est une paire de prédicats ("aucun", "si rouge", "si vert", "si bleu") et une action ("aller de l'avant", "tourner à gauche", "tourner à droite", "peindre le carré actuel en rouge", "peindre en vert", "peindre en bleu", "ne rien faire", "appeler F1", ..., "appeler F5"). Les appels aux sous-programmes utilisent une pile et peuvent être récursifs. Tout comme dans la programmation conventionnelle, une fois la dernière instruction d'un sous-programme terminée, l'exécution se poursuit à partir du point où le sous-programme a été appelé. L'exécution commence à partir de la première instruction de F1 et se poursuit jusqu'à ce que le robot ait visité toutes les cases avec des étoiles, ou lorsque le robot marche sur un carré noir ou à l'extérieur de la carte, ou que 1000 instructions aient été exécutées (prédicats en échec et actions "ne rien faire" ne compte pas), ou il n'y a plus d'instructions à exécuter (sous-dépassement de pile).
Contributions:
a
- une matrice de 12x16 caractères (comme généralement représentée dans votre langue, par exemple un tableau de chaînes) qui code une carte -'#'
pour les carrés inaccessibles (noirs),'*'
pour les carrés avec une étoile,'.'
pour le restec
- une matrice de 12x16 caractères décrivant les couleurs des carrés accessibles -'R'
(rouge),'G'
(vert) ou'B'
(bleu). Les carrés inaccessibles seront représentés par une lettre arbitraire des trois.y
etx
- la ligne et la colonne de base 0 du robot;a[y][x]
est garanti d'être'.'
d
- la direction du robot est tourné vers:0 1 2 3
pour la droite, vers le bas, à gauche, en haut, à savoir vers(y,x+1)
,(y+1,x)
,(y,x-1)
,(y-1,x)
f
- une seule chaîne, les implémentations concaténées de F1 ... F5. Chaque implémentation est une séquence (éventuellement vide) de paires action-prédicat (au plus 10 paires par sous-programme), terminée par un'|'
.prédicats:
'_'
aucun,'r'
rouge,'g'
vert,'b'
bleuactions:
'F'
avancer,'L'
tourner à gauche,'R'
tourner à droite,'r'
peindre rouge,'g'
peindre vert,'b'
peindre bleu,'1'
appeler F1, ...,'5'
appeler F5,'_'
ne rien faire
Vous n'avez pas besoin de nommer vos entrées comme ci-dessus, mais leurs valeurs doivent être telles que spécifiées.
Sortie: 1
(ou true
) si le robot recueille toutes les étoiles selon les règles, 0
( false
) sinon.
Exemple :
a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2
// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)
Un autre exemple , impliquant des instructions de "peinture":
a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1
Pour générer votre propre test, accédez à un puzzle de la liste sur robozzle.com , essayez de le résoudre (ou de ne pas le résoudre), appuyez sur F12 dans votre navigateur, tapez dans la console JS:
r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))
et reformatez le résultat pour votre langue.
Victoires les plus courtes. Pas de failles.
Réponses:
Prolog (SWI) , 574 octets
Essayez-le en ligne!
Cela définit un prédicat qui, lorsqu'il est appelé, réussit si toutes les étoiles sont collectées avec succès et échoue autrement. Le prédicat prend les arguments en tant que tels:
a+c+f+x^y^d.
.a
etc
doit être une liste de chaînes entre guillemets, tandis quef
doit être une chaîne entre guillemets doubles.Explication
Ce programme contient trois prédicats,
*/2
,^/2
et+/2
. Les*/2
prédicats définis sur la première ligne sont responsables d'une partie du traitement d'entrée. Le^/2
prédicat calcule récursivement comment le robot se déplace pas à pas et réussit si le robot recueille légalement toutes les étoiles et échoue dans le cas contraire. Le+/2
prédicat est le prédicat principal du programme et prépare l'entrée du^/2
prédicat avec l'aide du*/2
prédicat. Notez que chacun de ces prédicats ne prend techniquement que deux arguments, mais en utilisant des opérateurs et une correspondance de modèle, ils peuvent se comporter comme s'ils avaient plus d'arguments (je discute ce phénomène plus en détail ici ).*/2
Ce prédicat prend deux arguments. Le premier est une liste de listes de codes de caractères (c'est ainsi que Prolog analyse les chaînes entre guillemets). La seconde est une carte associative des points de la carte 12x16 (représentée par
X^Y
) à 32 plus le code de caractère stocké à ce point dans la liste des listes de codes de caractère. Le 32 est ajouté à chacun des codes de caractères de sorte que pour la matrice de couleurs, il transformera les caractères de couleur majuscules en caractères de couleur minuscules.Pour ce faire, il génère une liste de paires de points et les codes de caractères à ce point à l'aide
findall/3
. Il utilise ensuitelist_to_assoc/2
pour créer la carte associative correspondante des points au code de caractère à ce point.Le
findall/3
prédicat est une fonction intégrée qui prend un "modèle" comme premier argument, un objectif comme deuxième argument et une liste comme troisième argument. Le prédicat remplit la liste avec toutes les valeurs possibles du modèle qui font réussir l'objectif. En raison de la priorité de l'opérateur, le modèle transmis àfindall/3
in*/2
est analysé comme(X^Y)-D
. L'-
opérateur représente une paire de deux valeurs dans Prolog, de sorte que le modèle représente l'emplacement du point (X^Y
) associé à 32 plus le code de caractère du point (D
). Notez que le^
utilisé pour représenter le point n'est en aucun cas connecté au^/2
prédicat.Considérons le but qui est passé au
findall/3
prédicat.L'objectif contient trois prédicats dont chacun doit réussir pour que l'objectif réussisse. Le
nth0/3
prédicat qui est utilisé deux fois est utilisé pour obtenir la valeur à un index particulier de la liste (le0
dans son nom indique qu'il est indexé zéro). Le premier appel à celui-ci stocke laY
e ligne de la matrice de caractères dansO
tandis que le deuxième appel stocke leX
e caractère de cette ligne dansC
. Le prédicat finalplus/3
réussit si ses deux premiers arguments résument son troisième argument. Ceci est utilisé pour rendre le code de caractères dans la paire est 32 supérieur au code de caractères dans la matrice de caractères qui, comme indiqué ci-dessus, transformera toutes les lettres majuscules en lettres minuscules.Enfin,
findall/3
stocke toutes lesX^Y-D
combinaisons qui font réussir son objectif dans la liste à partir deL
laquelle la carte associative est construite.Plus à venir bientôt...
la source
JavaScript (ES6),
298276264 octets8 octets enregistrés grâce à @ngn
Prend l'entrée comme
(a,c,x,y,d,f)
, oùa
etc
sont des tableaux de tableaux de caractères. Renvoie0
ou1
.Cas de test
Afficher l'extrait de code
Commenté
la source
x+='2101'[d&3]-1,y+='1210'[d&3]-1
->d&=3,x+=(1-d)%2,y+=(2-d)%2
x
les changements par au plus 1, donc je pense que vous pouvez remplacerx&~15
parx&16
APL (Dyalog Classic) ,
236233 octets-3 grâce à Erik l'Outgolfer
Maintenant que j'ai donné le bonus, je publie un exemple de solution à mon propre défi. Il y a place à amélioration ici - n'hésitez pas à copier et à jouer au golf plus loin.
Essayez-le en ligne!
Comme ci-dessus, développé avec des commentaires:
la source