Contexte
La plupart des éditeurs de texte (à moitié décents) vous permettent de parcourir le texte à l'aide des touches fléchées. Le haut et le bas vous permettent de naviguer dans les lignes, tandis que la gauche et la droite se déplacent sur une ligne, mais aussi de s'enrouler. De plus, si la ligne est plus courte que la position X de votre curseur, le curseur apparaît à la fin de la ligne mais revient à la même position X si vous continuez à monter ou à descendre. Peut-être que l'explication visuelle suivante vous aidera:
Exemples de mouvement
Un simple exemple de texte pourrait ressembler à ceci. Le curseur sera inséré entre deux caractères dans ce texte, ou à la fin.
-----
---
------
let's put the cursor here:
X-----
---
------
move down (v):
-----
X---
------
move left (<):
-----X
---
------
v
-----
---X
------
v (notice how the X position of the cursor has been maintained)
-----
---
-----X-
^
-----
---X
------
> (more line wrapping)
-----
---
X------
<
-----
---X
------
^ (the X-position from earlier is no longer maintained due to the left-right motion)
---X--
---
------
Le défi
Étant donné plusieurs lignes de test ASCII, recherchez le chemin le plus court entre l'emplacement de départ et l'emplacement de fin. L'emplacement de début est représenté par ^
et l'emplacement de fin est représenté par $
, et il n'y en aura qu'un de chaque. Ceux-ci ne sont pas considérés comme faisant partie du texte et ne contribuent pas à la «longueur» de cette ligne.
L'entrée consistera en plusieurs lignes de texte non vides. La sortie sera une série de ^v<>
caractères qui montrent l'un des chemins les plus courts. Vous pouvez éventuellement supposer une nouvelle ligne supplémentaire à la fin de chaque, mais qui n'est pas incluse dans le texte navigable.
Vous pouvez écrire un programme ou une fonction nommée. Le gagnant sera la soumission la plus courte, mesurée en octets.
Exemple d'E / S
^Squares
are
fun$ny
vv<v (which is better than the naive vv>>>)
Squares
^are
funny$
<vv
Alp$habet^
Song
v<^
Mary had a little lamb,
His fleece was white as snow,
And$ everywhere that ^Mary went,
The lamb was sure to go.
^^>>>>v>>>
$^degenerate case
(no output)
v<vv
, non? Ou cela se terminerait-il après le dernier caractère de cette ligne?Réponses:
CJam, 139 octets
Eh bien, cela a pris plusieurs heures pour arriver à quelque chose qui semble terminé. Il semble que le temps nécessaire pour optimiser agressivement le code CJam soit plus grand que O (n) qui concerne la taille du code ...
Vous pouvez l' essayer en ligne , mais pour toute entrée pour laquelle le meilleur chemin est d'au moins 6 opérations, vous devriez probablement l' essayer hors ligne avec un interprète plus rapide.
Écrasé:
Développé et commenté:
Dans l'ensemble, c'est une solution assez simple. Il "exécute" les chiffres de la représentation en base 5 d'un numéro de chemin qui est incrémenté à chaque itération, en commençant par 0, jusqu'à ce qu'un chemin fonctionne. Les chiffres
1
-4
mappent les opérations vers le haut, le bas, la gauche et la droite, et0
ne font rien. La première itération utilisant un chemin de0
capture juste le cas dégénéré. Tous les autres chemins qui contiennent un0
ne sont jamais sélectionnés car ce ne sont que des versions de chemins déjà testés avec des no-op ajoutés.L'état est modélisé de la manière la plus minimaliste possible: le texte avec les marqueurs de début et de fin supprimés, la position du curseur dans le texte et la «mémoire des colonnes». Les retours à la ligne sont généralement traités comme n'importe quel autre caractère, il n'y a donc pas de concept de ligne et la position du curseur n'est qu'un index. Cela rend les déplacements à gauche et à droite simples, qui sont simplement implémentés comme décrémentation et incrémentation (avec serrage à la taille du texte). Monter et descendre est un peu plus délicat, mais toujours gérable.
La réutilisation du code était une tactique d'optimisation assez vitale. En voici quelques exemples:
5
opération fictive au début de la chaîne de chemin d'accès, ce qui se produit également en utilisant la0
logique no-op en raison de l'indexation du tableau circulaire et qu'il n'y a que 5 opérations définies.Dans l'ensemble, je suis très heureux de la façon dont cela s'est produit. C'est certainement le plus de travail que j'ai mis dans une réponse de golf de code à ce jour (pour quelque chose qui tient dans un tweet!?). Le temps d'exécution est cependant assez épouvantable. CJam n'est pas exactement le langage le plus rapide pour commencer et cet algorithme a une complexité de quelque chose comme O (m * 5 n ) , où m est la taille de l'entrée et n est la taille de la sortie. Heureusement, la vitesse ne compte pas!
la source
Python 2: 446
Solution simple. J'effectue une recherche en premier.
t
itère sur tous les chemins différents. Je convertist
en base5
, mais n'utilise que les entrées, qui sont différentes de zéro.1
est en haut, en2
bas, à3
gauche et à4
droite.Je garde la position actuelle du curseur dans 3 variables
x
,y
etz
.x
est la ligne,y
la position de la colonne etz
la position de la colonne «cachée», si vous montez ou descendez et que la ligne est trop courte. De nombreux ifs décident de la façon dont la variable change lors d'un déplacement.Le prétraitement est vraiment long, les 4 premières lignes n'effectuent que cette tâche.
Le long testcase prend vraiment beaucoup de temps. L'algorithme a une complexité de O (N * 5 ^ N), où N est la longueur de la solution la plus courte.
Utilisation: Entrez les lignes comme une seule chaîne (lignes séparées par
\n
) comme"Alp$habet^\nSong"
la source
CJam - 274
Pas encore de réponse? Ok, en voici un :)
Essayez-le sur http://cjam.aditsu.net/ ... sauf pour l'exemple Mary ou quelque chose de cette taille, vous voudrez probablement l' interpréteur java .
la source