Diese Herausforderung ist inspiriert von einem Brettspiel, das ich vor einiger Zeit gespielt habe.
Die Geschichte dieser Herausforderung muss nicht unbedingt gelesen werden, das Ziel des Herausforderungsabschnitts sollte alles Notwendige erklären.
Die Geschichte
Die Menschen sind in einem großen Raum mit einem menschenfressenden Monster eingesperrt. Die Wände des Raumes sind verzaubert und teleportieren Objekte durch den Raum, wenn sie berührt werden. Das Monster marschiert durch den Raum und sucht nach Fleisch. Der erste Mensch in seinen Augen wird von seinen scharfen Zähnen verzehrt.
Das Ziel der Herausforderung
Sie erhalten die Karte des Raums, einschließlich des Standorts der Menschen und des Monsters.
%%%KLMNOPQRSTA%
%%J B
%I % C
H D
G %% E
F F
E % G
D H
C % I%
B J%%
%ATSRQPONMLK%%%
Lassen Sie uns die Komponenten der Karte aufschlüsseln.
- Buchstaben von
A
bisT
: Wenn das Monster auf eines dieser Buchstaben tritt, wird es zum zweiten Erscheinen dieses Buchstabens teleportiert und ändert nicht seine Richtung. Es werden immer nur null oder zwei Buchstaben auf der Tafel sein. %
: Wandfliesen. Nur zur Formatierung und zum schönen Aussehen.#
: Der Startort des Monsters.*
: Die Standorte der Menschen.
Einige zusätzliche Dinge, die Sie über die Karte beachten sollten:
- Die Kartenabmessungen und die Objektposition sind nicht konstant, daher muss sich Ihr Code dynamisch daran anpassen.
Das Monster bewegt sich immer in die Richtung, in die es gerade zeigt (zu Beginn nach Westen), es sei denn, es entdeckt einen Menschen. In diesem Fall wendet es sich dem nächsten Menschen zu.
Das Monster entdeckt einen Menschen, wenn sich keine Wand- oder Teleporterplättchen in einer geraden horizontalen oder vertikalen Linie zwischen ihm und dem Menschen befinden.
Eine andere Sache, die zu beachten ist, ist, dass wenn sich das Monster vor einer festen Wand befindet ( %
) oder sich zwischen zwei Menschen entscheiden muss, es immer rechts vor links priorisiert .
Wenn das Monster aus irgendeinem Grund nicht nach rechts abbiegen und einen Schritt nach vorne machen kann , wird es stattdessen nach links abbiegen .
Am Ende würde die Reihenfolge, in der das Monster Richtungen priorisiert, vorwärts, rechts, links, rückwärts gehen.
Eingang
- Die Karte, einschließlich des Startorts des Monsters und der Positionen der Leute als ihre jeweiligen Charaktere. Es sollte keine andere Eingabe als die Map-Zeichenfolge oder das Array von Zeichenfolgen oder Zeichen geben.
Die Eingabe kann in jedem vernünftigen Format empfangen werden; eine einzelne Zeichenfolge oder ein Array von Zeichenfolgen für die Karte.
Ausgabe
Die Koordinate der Person, die zuerst vom Monster gefressen wird.
Die Koordinaten beginnen in der oberen linken Ecke und sind 0-indiziert, sodass die erste Kachel die Koordinaten (0 | 0) enthält. Wenn Sie die 1-Indizierung verwenden, geben Sie dies bitte in Ihrer Antwort an.
Regeln
- Dies ist Code-Golf , der kürzeste Code in Bytes in einer Sprache gewinnt.
- Standardlücken sind verboten.
- Sie können davon ausgehen, dass das Monster immer einen Menschen erreichen kann.
Testfälle
Eingang:
%%%KLMNOPQRSTA%
%%J B
%I %* C
H * D
G %% E
F # F
E % G
D * H
C % I%
B J%%
%ATSRQPONMLK%%%
Ausgabe: (10,2)
Da das Monster die beiden anderen Personen nicht sehen kann, wenn es an ihnen vorbeirennt, wird es zur anderen F
Wand teleportiert , wo es dann die letzte Person sieht.
Eingang:
%%%KLMNOPQRSTA%
%%J B
%I * C
H %%% * D
G #% E
F %%% % F
E G
D % H
C * I%
B * J%%
%ATSRQPONMLK%%%
Ausgabe: (12,3)
Eingang:
%%%KLMNOPQRSTA%
%%J B
%I %%% C
H *%#% D
G E
F F
E % G
D H
C I%
B J%%
%ATSRQPONMLK%%%
Ausgabe: (6, 3)
Eingang:
%%%%%%%%%%%%%%%
%#% %%% %
%A%ABCD %*% %
%*F G %%% %
% %BC% FD %
% % % %%%%
% % % %%
% % %% G %
% %
%*% % % %
%%%%%%%%%%%%%%%
Ausgabe: (1,9)
Viel Glück!
Antworten:
Python 2 ,
565 .. 422 445 1 .. 444 463 2 .. 468467463 BytesProbieren Sie es online aus!
Dank Halvard , Ian und Jonathan wurden viele Bytes gespeichert
1: Wurde länger, um den Fall des zweimaligen Wenden zu beheben und den Ort des Monsters zu finden.
2: Noch länger. Monster sollte beim Teleportieren nicht die Richtung ändern.
quelle
l.replace('#',' ')
->l.replace(*"# ")
.Perl 6 ,
343334333328322308 BytesProbieren Sie es online aus!
(Der eigentliche Code enthält keine Zeilenumbrüche. Ich habe sie nur eingefügt, um die Zeilen zum leichteren Lesen umzubrechen.)
Dies ist nicht in der Lage, Karten zu verarbeiten, bei denen es möglich ist, außerhalb der Kartengrenzen zu sehen. (D. H. Karten mit Leerzeichen an der Grenze.) Wenn dies wichtig ist, +5 Bytes. Aber da die Teleporter LoS jetzt blockieren, sollte es nicht.
Erläuterung : Diese Funktion verwendet die Karte als Liste von Zeichenlisten. Lassen Sie es uns in Aussagen aufteilen:
my \m=%((^@^a X ^@a[0]).map:{.[0]i+.[1]=>@a[.[0]][.[1]]});
: Lassen Sie uns einen Hash ("Wörterbuch" für Pythonisten) mit dem Namenm
(es ist eine sigillose Variable, daher müssen wir explizit einen Hash zuweisen) zuweisen,%(...)
der komplexe Formschlüsselx+iy
mit Zeichen in dery
dritten und drittenx
Spalte verknüpft der Karte.my \a=m<>:k.classify({m{$_}});
: Dies macht ein "inverses Wörterbuch" ausm
, genannta
: Es gibt einen Schlüssel, der jedem Wert in entsprichtm
, und der Wert ist eine Liste komplexer Koordinaten (Schlüssel inm
), die dieses Zeichen enthalten. So erhalten Sie beispielsweisea{"#"}
eine Liste aller Koordinaten, bei denen sich#
auf der Karte eine befindet. (Dies ist auch eine Siegellose Variable, aber wir haben Glück, da sieclassify
einen Hash zurückgibt.)my$m=a<#>[0];my$d=-1
: Stelle die anfängliche Monsterposition ein. Wir schauen uns#
den umgekehrten Hash ana
. Wir müssen verwenden,[0]
daa<#>
es sich immer noch um eine Liste handelt, auch wenn sie nur 1 Element enthält. Das$d
enthält die Richtung des Monsters; Wir setzen es nach Westen. (Die Richtung ist ebenfalls eine komplexe Zahl, ebenso-1
wie der Westen.)OK, die nächste Aussage ist ziemlich böse. Schauen wir uns zunächst Folgendes an:
{$^q;first ?*,map {(((my$u=m{my$t=$m+$_*$q})~~"%")*(1+!($_-1))+($u~~"A".."Z"))*m+($u~~"*")*abs($t-$m)},^m}
Dies ist eine Routine, die LoS in der angegebenen Richtung bewertet. Befindet sich ein Mensch in dieser Richtung, gibt er die Entfernung zum Menschen zurück. Wenn sich in dieser Richtung eine Wand oder ein Teleport befindet, wird die Gesamtzahl der Quadrate der Karte zurückgegeben. (Es geht darum, eine so hohe Zahl anzugeben, dass sie größer ist als jede legitime Entfernung zu einem Menschen.) Wenn sich die Wand in dieser Richtung und in Entfernung 1 befindet, geben wir schließlich die 2 × Gesamtzahl der Quadrate der Karte zurück. (Wir wollen niemals durch Wände rennen, daher benötigen diese eine noch größere Punktzahl. Wir werden in Kürze das Minimum auswählen.)Wir verwenden dies im Konstrukt
$d=($d,i*$d,-i*$d,-$d).min( LoS deciding block );
. Da wir für alles komplexe Zahlen verwenden, können wir leicht Richtungen erhalten, die relativ vorwärts, rechts, links und rückwärts von der ursprünglichen Richtung sind, indem wir sie einfach mit 1, i, -i multiplizieren (denken Sie daran, dass diey
Achse in die andere Richtung verläuft verwendet werden, um aus Mathe) bzw. -1. Also bilden wir die Liste der Richtungen in dieser Reihenfolge und finden die Richtung, die den minimalen "Abstand zu einem Menschen" hat (gemäß dem obigen Block), wodurch sichergestellt wird, dass jeder Mensch eine Wand schlägt und alles eine Wand schlägt, die richtig ist unter der Nase des Monsters. Wir nutzen die Tatsache, dass diemin
Funktion die erste gibtminimaler Wert. Wenn zwischen verschiedenen Richtungen ein Gleichstand besteht, wird das Monster es vorziehen, von rechts nach links nach hinten zu wechseln, was genau das ist, was wir wollen. So bekommen wir eine neue Richtung, die dann zugewiesen wird$d
.$m+=$d;
macht das Monster nur einen Schritt in die neue Richtung.$m=$d+(a{m{$m}}∖~$m).pick while m{$m}~~"A".."Z"
kümmert sich um die Teleports. Nehmen wir an, das Monster ist bei einem TeleportA
. Zuerst suchen wirA
im inversen Hash%a
und das zeigt die beiden Positionen des Teleports aufA
, dann verwerfen wir die aktuelle Position mit dem eingestellten Differenzoperator (der wie ein Backslash aussieht). Da es auf der Karte genau 2 Vorkommen jedes Teleports gibt und das Monster sicher auf einem steht, wird der Unterschied ein Satz mit 1 Element sein. Wir.pick
wählen dann ein zufälliges Element aus (ob Sie es glauben oder nicht, aber dies ist der kürzeste Weg, um das Element einer 1-Element-Menge zu erhalten :-)). So etwas passiert, bis das Monster irgendwo landet, wo es nicht in einem Portal ist.Alles in den letzten 4 Absätzen beschreibt eine massive Formkonstruktion
{change direction; step; handle teleports}...{m{$m}~~"*"}
. Dies ist eine Sequenz, die den Block links von aufruft,...
bis die Bedingung rechts von erfüllt...
ist. Und das ist wahr, wenn sich das Monster mit einem Menschen auf einem Feld befindet. Die Liste selbst enthält Rückgabewerte des großen Blocks auf der linken Seite, der (höchstwahrscheinlich(Any)
) Müll ist, da er am Ende den Wert der while-Schleife zurückgibt. Im Wesentlichen verwenden wir es als billigere while-Schleife. Der Wert der Liste wird verworfen (und der Compiler stöhnt über eine "nutzlose Verwendung...
in einem Sink-Wettbewerb", aber wen interessiert das?). Wenn dies alles erledigt ist, kehren wir zurück$m
- die Position des Monsters, nachdem es einen Menschen gefunden hat, immer noch als komplexe Zahl (also geben wir für den ersten Test10+2i
und so weiter).quelle
JavaScript (ES6),
258245Weniger Golf gespielt
Prüfung
quelle