Votre tâche - si vous choisissez de l'accepter - est de créer un programme qui analyse et évalue une chaîne (de gauche à droite et de longueur arbitraire) de jetons qui donnent des directions - à gauche ou à droite. Voici les quatre jetons possibles et leurs significations:
> go right one single step
< go left one single step
-> go right the total amount of single steps that you've gone right, plus one,
before you previously encountered this token and reset this counter to zero
<- go left the total amount of single steps that you've gone left, plus one,
before you previously encountered this token and reset this counter to zero
Il y a cependant un hic - les jetons des directions que votre programme devrait être en mesure d'analyser seront présentés sous cette forme:
<<->-><<->->>->>->
... en d'autres termes, ils sont concaténés, et c'est la tâche de votre programme de déterminer la priorité correcte des directions et la quantité de mesures à prendre (en regardant vers l'avenir). L'ordre de priorité est le suivant (de la priorité la plus élevée à la plus faible):
->
<-
>
<
Si vous rencontrez <-
alors qu'aucune étape vers la gauche n'avait été effectuée depuis le début ou depuis la dernière réinitialisation, faites un pas vers la gauche. La même règle s'applique à ->
, mais ensuite pour aller à droite.
Votre programme doit commencer à 0 et son résultat doit être un entier signé représentant la position finale finale.
Vous pouvez vous attendre à ce que l'entrée soit toujours valide (donc rien de tel <--->>--<
, par exemple).
Exemple d'entrée:
><->><-<-><-<>>->
Étapes dans cet exemple:
step | token | amount | end position
------+-------+--------+--------------
1. | > | +1 | 1
2. | < | -1 | 0
3. | -> | +2 | 2
4. | > | +1 | 3
5. | <- | -2 | 1
6. | < | -1 | 0
7. | -> | +2 | 2
8. | <- | -2 | 0
9. | < | -1 | -1
10. | > | +1 | 0
11. | > | +1 | 1
12. | -> | +3 | 4
Pour plus de précision: la sortie du programme ne doit être que la position finale finale sous forme d'entier signé. Le tableau ci-dessus est juste là pour illustrer les étapes de mon exemple. Pas besoin de sortir un tel tableau, une ligne de tableau ou même simplement les positions finales des étapes. Seule la position finale finale, sous forme d'entier signé, est requise.
Le code le plus court, après une semaine, gagne.
<-
est si elle est immédiatement suivie d'un<
ou d'un->
. Il n'y a aucun moyen dans ce langage de représenter la séquence<-
alors>
- ce qui le seraitgo left the total amount of single steps that you've gone left, plus one, then go right one single step
. Est-ce correct et par conception?Réponses:
GolfScript, 46 caractères
C'est l'un des programmes GolfScript les plus linéaires que j'ai jamais écrits - il n'y a pas une seule boucle, affectation conditionnelle ou variable. Tout se fait en utilisant la manipulation de chaînes:
Tout d'abord, je remplace chaque occurrence de
->
par)
. Puisque l'entrée est garantie pour être valide, cela garantit que toute occurrence restante de-
doit faire partie de<-
.Ensuite, je fais deux copies de la chaîne. Dès la première copie, je retire les caractères
<
et-
, ne laissant que>
et)
. Je duplique ensuite le résultat, supprime tous les)
s et tous les>
suivants du dernier)
de la deuxième copie, les concatène et compte les caractères. Ainsi, en effet, je compte:)
,>
après le dernier)
, et>
avant le dernier)
.Ensuite, je fais de même pour l'autre copie, sauf cette fois en comptant
<
et<-
au lieu de>
et)
, et en supprimant les-
s avant le décompte final des caractères. Ainsi, je compte:<-
,<
après le dernier<-
, et<
avant le dernier<-
.Enfin, je soustrais le deuxième décompte du premier et affiche le résultat.
la source
Python 2,7 -
154147134128 octetsDe sérieux changements ont été apportés au fonctionnement de ce programme. J'ai supprimé l'ancienne explication, qui se trouve toujours dans l'historique des modifications de cette réponse.
Celui-ci est dégoûtant.
Cela fonctionne à peu près de la même manière que les autres réponses à cette question, en remplaçant les caractères dans l'entrée par des instructions valides dans cette langue et en les exécutant. Il y a cependant une différence majeure:
replace
c'est un long mot. Vis ça.@ProgrammerDan dans le chat a eu l'idée d'utiliser un tuple avec la chaîne
;').replace('
4 fois, pour utiliser la pré-str.format()
méthode de formatage du texte. Quatre instances de%s
sont dans la chaîne sur la deuxième ligne, chacune tirant sa valeur de l'élément associé du tuple à la fin. Comme ils sont tous identiques, chacun%s
est remplacé par;').replace('
. Lorsque vous effectuez les opérations, vous obtenez cette chaîne:C'est maintenant du code python valide qui peut être exécuté avec
exec
. C'est vrai, bébé: les imbriquésexec
me permettent d'utiliser des opérations de chaîne sur du code qui doit effectuer des opérations de chaîne sur du code . Quelqu'un, s'il vous plaît, tuez-moi.Le reste est assez simple: chaque commande est remplacée par du code qui garde la trace de trois variables: la position actuelle, le nombre de droits depuis la dernière
->
, et la même chose pour les gauches et les<-
. Le tout est exécuté et la position est imprimée.Vous remarquerez que je fais
raw_input(';')
, en utilisant ';' comme une invite, plutôt queraw_input()
qui n'a pas d'invite. Cela permet d'économiser des caractères d'une manière peu intuitive: si je le faisaisraw_input()
, je devrais avoir le tuple rempli).replace('
, et chaque instance de%s
aurait '; \' 'devant, sauf la première . Avoir une invite crée plus de redondance afin que je puisse enregistrer plus de caractères dans l'ensemble.la source
list.index()
retourne-1
quand il ne trouve pas le personnage" .. erm no. Cela soulève unIndexError
. Vous l'avez peut-être confondu avecstr.find
. En fait, vous pourriez remplacer[list('><rl').index(c)]
par['><rl'.find(c)]
.Perl,
134131...9995 octetsPrend l'entrée en une seule ligne sur stdin, par exemple:
ou:
J'ai divisé les instructions en opérateurs "à droite" (">" et "->") et en opérateurs "gauche" ("<" et "<-"). Les avantages de ceci sont qu'il est plus facile d'exploiter le parallélisme entre les opérateurs gauche et droit, et nous n'avons rien à faire de fantaisie pour symboliser la chaîne. Chaque "direction" est traitée comme une opération de substitution où nous ajustons le total cumulé par le nombre de pas effectués dans cette direction, en ignorant la direction inverse qui est prise en charge par l'autre opération de substitution. Voici un ancêtre moins golfé de ce code comme une sorte de documentation:
Dans une itération antérieure de ce code, les substitutions étaient toutes effectuées en un seul passage. Cela avait l'avantage de conserver un mappage direct entre $ p / $ pos et la position qui serait retournée à un moment donné, mais prenait plus d'octets de code.
Si vous souhaitez utiliser () 5.10.0, vous pouvez s / print / say / pour raser 2 autres caractères du décompte, mais ce n'est pas vraiment mon style.
la source
Perl,
8877 octetsL'entrée est attendue via STDIN, par exemple:
Mise à jour
Il n'est pas nécessaire de convertir la chaîne en une somme, car cela
s//
compte déjà. :-)Première version
L'entrée est attendue via STDIN, exemple:
Explication:
L'idée est de convertir la chaîne de direction en une somme de sorte que le résultat soit sorti par un simple
print eval
.>
avant que chacun ne->
prenne deux mesures, l'une à la fois et l'autre à la suivante->
. Peu importe, lequel de->
temps il suit au moins l'un d'entre eux. Le compteur interne est remis à zéro après le suivant->
,>
ne provoque donc pas d'autres étapes, le maximum est de deux étapes.->
Ajoute ensuite une étape pour lui-même et tout autre reste>
après la dernière->
.Il en va de même pour la direction arrière avec un nombre de pas négatif plutôt que positif.
Par exemple:
><->><-<-><-<>>->
s/->/+1/
: Commencez par la direction avant, car->
a la priorité la plus élevée.Par exemple:
><+1><-<+1<-<>>+1
s/>(?=.*1)/+2/g
: Le modèle d'anticipation garantit que seuls les éléments>
avant->
sont convertis.Par exemple:
+2<+1+2<-<+1<-<+2+2+1
s/>/+1/g
: Maintenant, les autres>
sont couverts.Par exemple:
+2<+1+2<-<+1<-<+2+2+1
s/<-/-1/g
: Analogique vers l'arrière.Par exemple:
+2<+1+2-1<+1-1<+2+2+1
s/<(?=.*-)/-2/g
: Dans le modèle d'anticipation,-1
le premier<-
n'est pas nécessaire, car il ne reste aucun-
symbole de direction.Par exemple:
+2-2+1+2-1-2+1-1<+2+2+1
s/</-1/g
: Les restants<
après le dernier<-
sont convertis.Par exemple:
+2-2+1+2-1-2+1-1-1+2+2+1
print eval
: Calculer et sortir le résultat.Par exemple:
4
la source
-p
: 74 octets J'ai changé votres/>//g
poury/>//
sauver un octet dans chaque cas qui a permis également pour le retrait des parens dans l'expression.Rubis, 141 octets
Non golfé:
la source
l=1;r=1
peuvent êtrel=r=1
et$><<o
peuvent êtrep o
. Je pense que vous pourriez vous raser beaucoup en remplaçant cette déclaration de cas par quelque chose de moins volumineux, peut-être quelque chose dans le sens deeval %w(o-=1;l+=1 o+=1;r+=1 o-=l;l=1 o+=r;r=1)['<>LR'.index c]
l=r=1;o=0;gets.gsub('->',??).scan(/<-|./){eval"o+=#{%w[-1;l+ -l;l 1;r+ r;r][$&[-1].ord%4]}=1"};p o
vous pouvez descendre à 94 en utilisantruby -p
D - 243
Golfé :
Non golfé :
la source
C,
148141140140:
141:
148:
Avec espace:
Probablement beaucoup plus d'espace pour jouer au golf. J'ai surtout renoncé à essayer de manipuler 4 variables dans les ternaires qui capturaient les valeurs (cela continuait de sortir plus longtemps et de plus en plus tard), mais ce n'était pas une mauvaise première passe. Passage de tableau assez simple. Prend l'entrée comme argument de ligne de commande, les sorties via la valeur de retour.
Vous aurez besoin du
-std=c99
drapeau pour le compiler avec gcc.EDIT: Oui, il est tard - j'ai raté des choses évidentes.
la source
main
:main(char*x,char**v)
. Ensuite, vous avez 138 au lieu de 140.>><-
donne 0 au lieu de 1 ou><->
donne 0 au lieu de 2.char
et*
, et remplacez(*(x+1)==45)?(x++,o-=l+2,l=0):(o--,l++)
par(*++x==45)?(o-=l+2,l=0):(x--,o--,l++)
.JavaScript, 136
Non minifié:
Comment ça fonctionne
Étant donné une chaîne entrée
s
comme ceci:Il utilise une Regex pour remplacer chaque commande par un ensemble d'instructions qui modifient
z
(la position finale),l
(les mouvements de gauche stockés) etr
les mouvements de droite stockés. Chaque Regex est effectuée par ordre de priorité.Pour l'entrée ci-dessus, cela se convertit
s
en:Joli, n'est-ce pas.
Enfin, nous devons
eval(s)
exécuter les instructions et l'alertez
qui contient la position finale.la source
Javascript (116,
122,130)116:
122:
130:
la source
JavaScript [217 octets]
Elle pourrait probablement être raccourcie un peu plus ...
la source
PHP,
284282Aucun regex.
Non golfé:
la source
str_split($i)
(1
est la valeur par défaut pour le deuxième argument.) Et$i
devrait probablement l'être$c
, n'est -ce pas?$i
): P Fixe!Une autre solution Perl, 113 caractères
Il y a déjà deux réponses qui ont battu cela, c'est juste pour des rires. Il utilise une approche basée sur l'observation d'Ilmari sur la valeur des jetons:
Explosé un peu:
la source