Écrivez un programme qui accepte une chaîne de longueur impaire contenant uniquement les caractères .
et :
. À l'aide d'une pile initialement vide , générez un nombre à partir de cette chaîne comme suit:
Pour chaque caractère c de la chaîne (de gauche à droite) ...
- Si c est
.
et que la pile contient moins de 2 éléments, appuyez sur 1 sur la pile. - Si c est
.
et que la pile a 2 éléments ou plus, sortez les deux premières valeurs de la pile et poussez leur somme sur la pile. - Si c est
:
et que la pile contient moins de 2 éléments, appuyez sur 2 sur la pile. - Si c est
:
et que la pile contient 2 éléments ou plus, sortez les deux valeurs supérieures de la pile et poussez leur produit sur la pile.
Le nombre résultant est la valeur en haut de la pile. Votre programme doit imprimer ce numéro sur stdout (avec un retour à la ligne facultatif).
(Une petite analyse montre qu'il ne reste qu'un seul nombre, sauf si la chaîne a une longueur égale, c'est pourquoi nous les ignorons. En fait, la pile n'a jamais plus de 2 éléments.)
Par exemple, le nombre de ::...:.:.
est 9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
Pour vérifier la santé mentale, voici les numéros de toutes les chaînes de longueur 1, 3 et 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
Le programme le plus court en octets gagne. Tiebreaker est un post antérieur.
- Vous pouvez supposer que l'entrée est toujours valide, c'est-à-dire une chaîne contenant uniquement
.
et:
dont la longueur est impaire. - Au lieu d'écrire un programme, vous pouvez écrire une fonction qui prend une chaîne valide et imprime ou renvoie le nombre généré.
Réponses:
CJam,
27 24 2322 octetsAssez simple. J'utilise la pile de CJam comme pile mentionnée dans la question;)
Algorithme
Voyons d'abord le code ASCII pour
.
et:
.Comme dans CJam, l'index s'enroule, permet de voir si nous pouvons utiliser ces valeurs directement pour obtenir l'opération souhaitée.
Je ne peux donc pas simplement utiliser les codes ASCII dans une chaîne d'opération de 4 longueurs. Permet d'essayer d'autres valeurs
qui sur une chaîne de 4 longueurs se résume à
Je peux utiliser cette opération mod 10 mais cela coûtera 2 octets. Essayons autre chose
Nice !, maintenant nous soustrayons juste 1 pour la condition de taille de pile pour obtenir les index
0, 1, 2 and 3
et utiliser un5
tableau de longueur ("1+2* "
) comme cas de commutateur. Le dernier espace est juste un remplissage pour le rendre de longueur 5. C'est juste 1 octet supplémentaire par rapport à l'opération de modding.Essayez-le en ligne ici
1 octet économisé grâce à cosechy
la source
> <> (Poisson) , 33 octets
Assez simple avec de petites astuces / optimisations.
Explication:
i
= point de code du prochain caractère d'entrée,-1
si la fin de l'entrée est atteinte;a
= 10;b
= 11;)
=>
i
point de code du premier caractère d'entrée,b%1-
top_of_stack mod 11 - 1
masques48 ('.') , 56 (':')
à1 , 2
i:1+?\~n;
si la fin de l'entrée est atteinte, imprimer le dernier résultat et terminerb%1-
masque d'entrée1 , 2
0@
pousser0
sous les deux chiffresi5a*)
lire la prochaine entrée et la masquer pour la0 , 1
comparer à50
1
(':'
) multiplie les deux premiers éléments créant une pile [0 produit][0 sum]
ou[0+product=product]
40.
sauter (boucle) en position(4,0)
, notre point4
,i:1+?\~n;
la source
Haskell,
7365 octetsUne solution simple, utilisant le fait que la pile n'a jamais plus de 2 éléments.
la source
C, 104 octets
Eh bien, c'est trop long.
la source
Pyth,
2524 octetsVous avez une idée en étudiant la solution de @ isaacg. Mais j'utilise une pile.
Démonstration en ligne ou suite de tests
Explication
La première chose que je fais est de convertir la chaîne d'entrée en 0 et 1. Un
"."
se convertit en un0
, un":"
en un1
.Ensuite, je réduis cette liste de nombres:
la source
JavaScript (ES6), 65
Nous utilisons seulement 2 cellules de notre pile.
Commencez à mettre une valeur dans s [0].
Ensuite, à chaque position impaire (à partir de 0) dans la chaîne d'entrée, mettez une valeur dans s [1].
À chaque position paire, exécutez un calcul (additionnez ou multipliez) et stockez le résultat dans s [0].
Alors oubliez la pile et utilisez seulement 2 variables, a et b.
Un test rapide
Sortie
la source
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pyth, 27 octets
Une pile? Qui a besoin d'une pile.
Manifestation.
la source
Rétine ,
1057573 octetsMon premier programme Retina! (Merci à Martin Büttner pour avoir économisé 2 octets, sans parler d'avoir inventé la langue en premier lieu.)
Chaque ligne doit aller dans un fichier séparé; ou, vous pouvez les mettre tous dans un seul fichier et utiliser l'
-s
indicateur. La<empty>
notation représente un fichier / ligne vide.Inspiré par la réponse de mbomb007 , mais j'adopte une approche quelque peu différente. Une différence majeure est que je construis la pile devant la chaîne pointillée (avec le haut de la pile orienté vers la droite). Cela facilite la conversion des symboles en nombres correspondants sur place. J'utilise également
a
au lieu de1
, en ne le remplaçant qu'à la fin, pour éviter d'analyser l'ambiguïté dans des séquences comme$1a
. Si une réponse commeaaaaaa
est acceptable comme nombre unaire, les deux dernières lignes / fichiers pourraient être éliminés pour économiser 4 octets.Explication:
Correspond s'il y a 0 ou 1 élément sur la pile (
(a+;)?
) suivi d'un point (\.
); si c'est le cas, il remplace la période para;
(c.-à-d. pousse un 1).Correspond s'il y a 0 ou 1 élément sur la pile suivi de deux points. Si c'est le cas, il remplace les deux points par
aa;
(c'est-à-dire pousse un 2).Correspond s'il y a deux éléments sur la pile suivis d'un point. Supprime le point et le point-virgule entre les éléments, les ajoutant ainsi.
Correspond s'il y a deux éléments sur la pile, dont le haut est un 2, suivi de deux points. Supprime le deux-points et le 2 et répète deux fois l'autre nombre, le multipliant ainsi par 2.
La regex correspond s'il y a deux éléments sur la pile, dont le haut est un 1, suivi de deux points. Supprime les deux points et le 1, laissant l'autre nombre inchangé (c'est-à-dire multiplié par 1).
)`
indique la fin d'une boucle. Si des modifications ont été apportées à la chaîne, le contrôle revient en haut du programme et réexécute les substitutions. Si la chaîne a cessé de changer, nous avons remplacé tous les points et les deux-points, et tout ce qui reste est le nettoyage ...Supprime le point-virgule restant.
Transforme tous les a en 1. Encore une fois, si les nombres unaires sont autorisés à utiliser n'importe quel symbole, cette étape n'est pas nécessaire.
la source
Rouille, 170 caractères
Encore une preuve que Rust est absolument terrible au golf. Code complet non golfé:
Voici une astuce intéressante que j'ai utilisée dans celui-ci. Vous pouvez raser un caractère dans une instruction if / else en lui faisant retourner une valeur qui est immédiatement supprimée, ce qui signifie que vous n'avez besoin que d'un point-virgule au lieu de deux.
Par exemple,
peut être changé en
qui sauve un personnage en rasant un point-virgule.
la source
Haskell,
888179 octetsIl semble que quelqu'un m'a battu jusqu'à la marque sur une solution Haskell, non seulement cela, leur solution est plus courte que la mienne. C'est dommage, mais je ne vois aucune raison de ne pas publier ce que j'ai trouvé.
la source
APL (50)
Je suis très désavantagé ici, car APL n'est pas un langage basé sur la pile. J'ai finalement pu abuser de la réduction pour raccourcir le programme.
La fonction interne prend une «commande» à gauche et une pile à droite, et l'applique, renvoyant la pile. La fonction externe le réduit sur la chaîne, en commençant par une pile vide.
Explication:
(⌽⍵),⊂⍬
: la liste initiale à réduire.⊂⍬
est une liste vide encadrée, qui représente la pile,(⌽⍵)
est l'inverse de l'entrée. (La réduction est appliquée de droite à gauche sur la liste, de sorte que la chaîne sera traitée de droite à gauche. Si vous inversez l'entrée au préalable, vous appliquez les caractères dans le bon ordre.){
...}
: la fonction intérieure. Il prend la pile à droite, un caractère à gauche et retourne la pile modifiée.F←'.:'⍳⍺
: l'index du caractère dans la chaîne.:
, ce sera 1 ou 2 selon la valeur.2>⍴⍵:F,⍵
: Si 2 est plus grand que la taille de pile actuelle, ajoutez simplement la valeur actuelle à la pile.⋄
: autrement,2↓⍵
: retirer les deux premiers éléments de la pile(
...)/2↑⍵
: réduisez une fonction donnée sur eux, et ajoutez-la à la pile.⍎F⌷'+×'
: la fonction est soit+
(addition) soit×
(multiplication), sélectionnée parF
.⊃
: enfin, renvoyez l'élément le plus haut de la pilela source
Rubis - 96 caractères
La pièce intéressante ici est
eval
.Mis à part cela, je fais l'hypothèse qu'après le premier caractère, la pile ira toujours 2, math, 2, math, .... Cela me permet d'utiliser moins de code en saisissant deux caractères à la fois - je n'ai jamais à comprendre savoir si un caractère est mathématique ou numérique. C'est positionnel.
Non golfé:
la source
TI-BASIC,
7873706966 octetsTI-BASIC est bon pour les lignes simples, car les parenthèses fermantes sont facultatives; à l'inverse, c'est un langage médiocre où le stockage de plusieurs valeurs est nécessaire car le stockage dans une variable prend de deux à quatre octets d'espace. Par conséquent, l'objectif est d'écrire autant de choses que possible sur chaque ligne. TI-BASIC est également horrible (pour un langage à jetons) pour la manipulation de chaînes de toutes sortes; même la lecture d'une sous-chaîne est longue.
Les astuces comprennent:
int(e^([boolean]
au lieu de1+(boolean
; enregistre un octetla source
".:.":prgmDOTTY
, économiser 4 octets.1+(":"=sub(Ans,1,1
Aller,
129115112 octets(un peu) non golfé:
Essayez-le en ligne ici: http://play.golang.org/p/B3GZonaG-y
la source
Python 3, 74
Transforme d'abord la liste d'entrée en une séquence de 1 et de 2, en prenant la première valeur comme valeur initiale
x
. Ensuite, décolle deux éléments à la fois de l'avant des
, en prenant le premier nombre et en ajoutant ou en multipliant par le nombre actuel selon que le second est 1 ou 2.la source
bien c'est une opération si facile, sophistiquée par l'op (intentionnellement)
c'est juste ...
Code: C (80 octets)
contribution
longueur = 2n + 1 vecteur V de type char '.' ou ':'
Sortie
un entier k
Une fonction
Simulation:
essayez-le ici
la source
*(V-1)
) est nul?Rétine,
181135129 octetsChaque ligne doit être dans un fichier séparé.
<empty>
représente un fichier vide. La sortie est en Unary.Quand${0}1
est utilisé, les accolades se séparent$0
du1
, sinon ce serait$01
le 1er groupe correspondant. J'ai essayé d'utiliser$001
, mais cela ne semble pas fonctionner dans la saveur .NET de l'expression régulière.Edit: Trouvé c'est
$&
la même chose que$0
.En pseudo-code, ce serait essentiellement une boucle do-while, comme indiqué ci-dessous. J'appuie sur le premier nombre, puis boucle: appuie sur le deuxième nombre, supprime l'opération (instruction), fais des maths, supprime l'op. Continuez à boucler. Notez que lorsqu'une opération est sautée, cela supprimera également l'espace une fois toutes les instructions terminées.
Commenté:
la source
(:)(.*)
->$1$2
, ce qui, je suis sûr, pourrait simplement être(:.*)
->$1
(car vous gardez les deux groupes dans le même ordre et ne faites rien d'autre avec eux ).Python 3, 122 octets
Non golfé:
En python, vous référencez l'index d'une liste comme ceci:
Vous pouvez y mettre une valeur booléenne,
True
est1
etFalse
est0
.Essayez-le en ligne ici
la source
Perl, 77 octets
étendu:
Le
@o
tableau mappe les chiffres aux opérateurs. Ensuite, nous substituons des paires de chiffres avec l'opérateur approprié, réorganisé en infixe. L'expression régulière commence par\B
donc nous ne correspondons pas au tout premier caractère. Le résultat des///g
nous indique le nombre de parens ouverts dont nous avons besoin au début. Ensuite, lorsque nous avons assemblé l'expression infixe complète, nous pouvons l'évaluer. (Supprimezeval
si vous souhaitez voir l'expression à la place).Voici le faisceau de test que j'ai utilisé pour vérifier les résultats:
L'entrée est la liste des expressions dotty et leurs valeurs (fournies dans la question) et la sortie est des paires de {réel, attendu}.
la source