introduction
Vous avez le malheur d'être coincé dans une voiture en fuite sur un parcours d'obstacles. Toutes les fonctionnalités de la voiture sont non réactives, à l'exception du système de direction, qui est endommagé. Il peut rouler droit ou tourner à droite. La voiture peut-elle être guidée vers la sécurité?
Mécanique
Votre voiture commence dans le coin supérieur gauche d'une carte 8x8 et tente de se mettre en sécurité dans le coin inférieur droit. La voiture a une orientation (initialement à droite), mesurée par incréments de 90 degrés. La voiture peut effectuer l'une des deux actions suivantes:
- Conduire une case en avant, ou
- Tourner de 90 degrés dans le sens des aiguilles d'une montre, puis avancer d'un carré
Notez que la voiture est incapable de tourner suffisamment brusquement pour effectuer un virage à 180 degrés sur une seule case.
Certaines des places sont des obstacles. Si la voiture pénètre dans un obstacle, elle se bloque. Tout ce qui se trouve en dehors du parcours 8x8 est supposé être un obstacle. Par conséquent, quitter le parcours équivaut à un accident.
Le carré en bas à droite est le coffre-fort, qui permet à la voiture d'échapper au parcours du combattant. La case de départ et la case de sécurité sont supposées ne pas être des obstacles.
Tâche
Vous devez écrire un programme ou une fonction prenant en entrée un tableau 8x8 (matrice, liste de listes, etc.) représentant le parcours du combattant. Le programme retourne ou imprime un booléen, ou quelque chose de similaire. S'il est possible pour la voiture de se rendre à la case de sécurité sans se planter (c'est-à-dire si la carte est résoluble), la sortie l'est True
, sinon False
.
Notation
Règles de golf de code standard - le gagnant est le code avec le moins d'octets.
Bonus:
Si, pour une carte résoluble, votre code génère une série valide d'entrées de conducteur qui guident la voiture vers le coffre-fort, déduisez 10 points de pourcentage de votre score. Un exemple de format de sortie pourrait être
SRSSR
(indiquant droite, droite, droite, droite, droite). Cette sortie remplacerait laTrue
sortie standard .Si, pour une carte insoluble, la sortie de votre code établit une distinction entre les situations dans lesquelles un accident est inévitable et les situations dans lesquelles il est possible de contourner le parcours du combattant pour toujours, déduisez 10 points de pourcentage de votre score. Un exemple de sortie pourrait être
Crash
si un accident est inévitable, ouStuck
si la voiture est bloquée dans le parcours du combattant pour toujours. Ces sorties remplaceraient laFalse
sortie standard pour une carte insoluble.
Exemple
Si le programme reçoit un tableau 8x8 tel que celui-ci:
[[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[1, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 1, 0, 0, 0, 1, 0]]
Cela serait interprété comme une carte comme celle-ci, avec des carrés noirs indiquant les obstacles:
Et une solution possible pourrait être:
Puisqu'une solution existe, le programme doit retourner / imprimer True
pour cette carte. La séquence de mouvements illustrée ici est SSSSRSRRRSRSSRRRSSRSSS
.
Crash
etStuck
. Ils sont ici à cause de combien de temps ils sont. Rangée 2 remplie, tout le reste vide ->Crash
. Rangée 7 remplie, tout le reste vide ->Stuck
Réponses:
JavaScript (ES6) - 122
124148octets162172 172178187190193208Merci à Optimizer et DocMax pour leurs suggestions utiles sur la façon d’améliorer ce code:
Retours
true
(vérité) pour résolvable etfalse
(falsy) pour insoluble.Fonctionne uniquement dans Firefox à partir d'aujourd'hui en raison des fonctionnalités de JavaScript 1.7.
Test Board
la source
D=(x,y,d,t,a)=>!t[i=x+y*8+d*64]&&(t[i]=1,x+=d==0?1:d==2?-1:0,y+=d==1?1:d==3?-1:0,x==7&&y==7||!((x|y)&~7||a[y][x])&&G(x,y,d,t,a));G=(x,y,d,t,a)=>D(x,y,d,t,a)||D(x,y,d+1&3,t,a);F=a=>G(0,0,0,[],a)
.D=d=>!t[i=x+y*8+d/4]&&(t[i]=1,x+=d?d^2?0:-1:1,y+=d^1?d^3?0:-1:1,x==7&&y==7||!((x|y)&~7||b[y][x])&&G(x,y,d));G=(X,Y,d)=>D(d,x=X,y=Y)||D(d+1&3,x=X,y=Y);F=a=>G(0,0,0,b=a,t={})
- Testé.[[0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]
. Cela devrait donner de faux.x
ety
sont globaux, vous ne pouvez pas exécuter deux cas de test avant de recharger la page ...x+=d?d^2?0:-1:1
parx+=d&1?0:1-d
ety+=d^1?d^3?0:-1:1
avecy+=d&1&&2-d
.Python 2 - 123
125 133 146 148 150 154 160True
en cas de succès,False
en cas d'échec.Vous devez fournir des entrées comme
f(b=var_containing_board)
.Version Lambda - 154
Renvoie
0
(falsy) en cas d'échec, enTrue
cas de succès.Merci à Will et Brandon d’avoir rendu la fonction plus courte que le lambda. Aussi pour ajouter plus de défilement horizontal: D
Merci à xnor pour son traitement et sa logique supérieurs au bit!
Edit note: Je suis raisonnablement confiant que
b[y][x]
ne sera jamais exécuté lorsque vous sortez de la plage. Puisque nous sommes en dehors du tableau, la vérification de l'historique les in c
seraFalse
. Ensuite, la vérification des limites(x|y)&8
sera8
. Ensuite, python ne vérifiera même pas la dernière valeur de==
car les deux premières sont déjà différentes.la source
x|y>7or
fonctionne maisx|y<0or
ne ...0o
.C (GNU-C), 163 octets * 0.9 = 146.7
#C (GNU-C), 186 octets * 0.9 = 167.4Ma nouvelle version utilise un entier signé plutôt que non signé. Un peu plus tôt, j'avais peur du décalage vers la droite signé, mais je me suis rendu compte que puisque le poteau de signalisation est le carré du but, peu importe ce qui se passera après.
La fonction prend un tableau de bits (ceux-ci représentent des carrés bloqués) sous la forme d'un entier de 64 bits. Les bits sont classés par ordre de signification, de la même manière que vous lisiez un livre. Il renvoie -1 en cas d’accident, 0 en cas de conduite illimitée ou 1 en cas d’évasion dans le coin inférieur droit.
Programme de test
Sortie
Convertisseur tableau à hexadécimal Python:
la source
memset(&M,~1,8)
(15 caractères) parM=~(-1ULL/255)
(14 caractères).P(0x00fefefefefefefe);
= (Devrait être un coup droit en haut à droite, un tour, droit au coin. Même chose pourP(0x00eeeeeeeeeeeeee);
(impasse au 4ème col). Je ne pense pas que vous deviez assignera
initialement.0x7f7f7f7f7f7f7f00
. De plus, il est nécessaire d’initialisera
car plus tard, il n’est modifié que par ORing en bits supplémentaires, je ne peux donc pas me permettre de définir un bit indésirable au départ.Python, 187
213207 caractères, 10% de bonus pour le chemin d'impression
Sur l'entrée de test, il trouve un chemin légèrement différent:
SSSSRSRSRRSSRSSRRSRSSRSSSSS
L’approche générale est d’abord de transformer l’entrée en espaces et
o
s. Les espaces ont un hex de20
, les quatre bits inférieurs ne sont donc pas définis.o
a un hex de6F
, alors les quatre bits bas sont tous mis.Une bordure de
o
s est placée autour du tableau afin que nous n'ayons pas à nous soucier des mauvais indices.Lorsque nous marchons sur le plateau, nous utilisons les bits dans chaque tuile pour voir si nous sommes autorisés à passer lorsque nous venons de ce côté. De cette façon, nous évitons les boucles infinies. Il ne suffit pas d'avoir un seul booléen par tuile, car la direction de votre sortie dépend de la direction de votre entrée. Vous pouvez donc visiter les tuiles deux fois.
Nous effectuons ensuite une recherche récursive pour trouver un chemin sécurisé.
la source
9
en dur à la place dew=len(b[0])+1
, etc.?p==79
parp-79
. J'ai eu une erreur de syntaxe en faisant cela dans les deux sens sans espace avant leelse
. Je pense que cette astuce ne fonctionne qu'avecif
.-~x
==x+1
mais les deux opérateurs unaires ont une priorité plus élevée que la multiplication, la division et le module! Alors(d+1)%4
pourrait être-~d%4
! Cela fonctionnerait aussi avecx-1
mais utiliseriez juste à la~-x
place.Javascript -
270 - 20% = 216262 - 20% = 210 octetsPuisqu'il devrait y avoir au moins une solution qui gagne les deux bonus (et ne conduit pas à une profondeur de pile ridicule;) ...
Minified:
Étendu:
v
est une table de hachage avec des clés qui sont des triples d'état(x,y,d)
correspondant à la coordonnée et à la direction d'entrée (x, y)d
. Chaque clé a une valeur associée qui correspond à la chaîne de mouvementsS
(droits) etR
(tourner à droite) requis pour atteindre l'état représenté par la clé.Le code conserve également une pile de triples (variable
n
) qui n’ont pas encore été traités. La pile ne contient initialement que le triple (0,0,0), correspondant à l'état auquel la voiture fait face dans la cellule (0,0). Dans la boucle externefor( S = ... )
, la routine vérifie s'il reste des triplets non traités. Si oui, il fonctionne chaque triple non traité à travers la boucle intérieure,n.map( ...
.La boucle intérieure fait cinq choses:
K
(bloqué), car nous avons trouvé au moins une boucle dans laquelle la voiture peut continuer à tourner pour toujours sans se planter.v
) et à la pile de triplets non traités (m
) pour le prochain passage de la boucle extérieurev
, sa valeur est définie sur la valeur de l'état d'origine (la séquence de déplacements) plusR
ouS
sur la base du déplacement actuelx
ety
sont7
, la valeur de l'état d'origine (la séquence de déplacements effectués pour atteindre l'état d'origine) est copiée dansS
, car cette séquence de mouvements est une solution au problèmeUne fois la boucle interne terminée,
n
la pile est remplacée parm
la nouvelle pile.Une fois la boucle externe terminée (aucun nouvel état n'a été atteint), la fonction renvoie sa sortie. Si la cellule (7,7) a été atteinte,
S
contiendra une séquence de mouvements menant à cette cellule, qui sera sortie. Si la cellule n'a pas été atteinte,S
la chaîne sera vide et la routine tombera en sortieO
, ce qui contiendraK
(bloqué) si et seulement si une boucle a été trouvée, ouC
(crash) si la voiture va inévitablement tomber en panne.la source
Python 339 - 10% = 305 octets
J'ai utilisé une recherche en profondeur d'abord récursive, qui se termine tôt en cas de succès via
exit
. Aussi impression chemin sur le succès sous la forme de00001010101010101010101110100111001000
,0
pour droit,1
pour droit. La réponse sera plus longue que la meilleure, car il s'agit d'abord de la profondeur. Je suis sûr que certaines optimisations de l'algorithme pourraient réduire considérablement le compte d'octets.la source
a
lafor
boucle in . Vous n'avez également pas besoin d'espaces autour des opérateurs, par exemple(v+1) % 4
->(v+1)%4
. Vous pouvez également joindre plusieurs déclarations sur une ligne en utilisant;
s'il n'y a pas deif
oufor
, etc. sur la ligne, par exemplec(l+"0");c(l+"1")
. D'autres Golfs:x,y,v=0,0,2
,x|y>7 or x|y<0
,x==y==7
. Bonne chance :)