StickStack est un langage de programmation basé sur une pile très simple avec seulement deux instructions:
|
pousse la longueur de la pile sur la pile-
sort les deux premiers éléments de la pile et repousse leur différence (second topmost - topmost
)
Détails sur la langue
- La pile est vide au début du programme.
- Toutes les instructions sont exécutées séquentiellement de gauche à droite.
- S'il y a moins de 2 nombres sur la pile, l'
-
instruction est illégale. - À la fin de l'exécution, la pile doit contenir exactement un numéro .
Tout entier peut être généré par un programme StickStack. Par exemple:
|||--||-- generates the number 2 through the following stack states:
[]
[0]
[0, 1]
[0, 1, 2]
[0, -1]
[1]
[1, 1]
[1, 1, 2]
[1, -1]
[2]
Pour évaluer votre code StickStack, vous pouvez utiliser cet évaluateur en ligne (CJam) . (Merci pour @Martin pour le code.)
La tâche
Vous devez écrire un programme ou une fonction qui a donné un nombre entier comme sorties d'entrée ou renvoie une chaîne représentant un programme StickStack qui sort le nombre donné.
Notation
- Votre score principal est la durée totale des programmes StickStack pour les cas de test donnés ci-dessous. Un score plus bas est meilleur.
- Votre soumission n'est valide que si vous avez exécuté votre programme sur tous les cas de test et compté votre score.
- Votre score secondaire (bris d'égalité) est la durée de votre programme ou fonction de génération.
Cas de test d'entrée
(Chaque numéro est un cas de test différent.)
-8607 -6615 -6439 -4596 -4195 -1285 -72 12 254 1331 3366 3956 5075 5518 5971 7184 7639 8630 9201 9730
Votre programme devrait fonctionner pour tous les entiers (que votre type de données peut gérer) et pas seulement pour les cas de test donnés. Les solutions pour les numéros de test ne doivent pas être codées en dur dans votre programme. En cas de doute sur le codage en dur, les numéros de test seront modifiés.
la source
Réponses:
Python 2 - 5188
Assez efficace dans le temps, et semble être (probablement) la solution optimale. J'ai observé qu'un motif tel que
|||||-|||-|-|-|------
(une solution optimale pour 25)peut être délimité comme
où chaque valeur totale à la fin est la somme de (la valeur de chaque niveau multipliée par le nombre de «|»). Ainsi, par exemple ci-dessus, nous avons
-1*1 + 2*1 - 3*1 + 4*2 - 5*1 + 6*4 = 25
. En utilisant cela, j'ai écrit cette solution qui produit une sortie similaire à d'autres réponses, et en un temps trivial.Je crois que c'est la solution optimale, car je teste toutes les hauteurs optimales possibles (j'en teste beaucoup plus que nécessaire) et je suis presque sûr que la solution implique toujours au plus une couche avec deux '|' en plus de la dernière (je peux garantir cela pour les nombres positifs mais pas sûr à 100% des négatifs).
Voici le code que j'ai utilisé pour le tester
la source
Java, 5208
524053066152Il s'agit d'une fonction récursive qui se rapproche de la cible, avec des cas de base pour quand elle se rapproche de 5 (ce qui n'est souvent qu'une étape).
Fondamentalement, vous pouvez obtenir
(a*b)+(a/2)
des(a+b)*2
bâtons avec un motif simple. Sia
est impair, le résultat sera négatif, ce qui conduit à une logique étrange.Cela prend environ une minute pour 2 31 -1, avec pour résultat une longueur de 185 367. Cela fonctionne cependant presque instantanément pour tous les cas de test. Il marque
4*(sqrt|n|)
en moyenne. Le cas de test individuel le plus long est9730
, ce qui donne une pile de bâtons de 397 longueurs:Mise à jour:
Trouvé un moyen plus court pour ajouter / soustraire du modèle de base. De retour en tête (pour l'instant)!
Avec un harnais et des cas de test:
Jouera au golf (plus) dans le cas peu probable d'une égalité exacte.
la source
JavaScript (ES6) 5296
6572Modifier Comme je l'ai dit dans mon explication, je ne suis pas bon pour résoudre des équations entières. Ma supposition de la valeur b n'était pas si bonne, j'ai donc élargi la plage de valeurs pour essayer.
Et (wow) je mène maintenant.Edit 2 Correction de bogue, mêmes résultats. J'ai une idée, mais je ne peux pas la clouer.
Octets: ~ 460, assez golfé. Il fonctionne sur des entiers 32 bits, un temps d'exécution proche de 0.
Le code est la fonction F (masquée dans l'extrait) ci-dessous.
Exécutez l'extrait de code à tester (dans FireFox).
Afficher l'extrait de code
Explication
Des nombres positifs, pour commencer. Commencez avec une "base" (essayez dans CJam si vous le souhaitez, espaces autorisés)
Résumé: 1 bâton, puis b * 2 bâtons, puis b * 2 tirets
Essayez ensuite d'ajouter un ou plusieurs '- |' dans la fente du milieu. Chacun ajoute un incrément fixe qui est deux fois la base de départ et peut être répété plusieurs fois. Nous avons donc une formule, avec b = base et r = incrémenter le facteur de répétition
Voir? La valeur ajoutée augmente rapidement et chaque ajout ne fait toujours que 2 caractères. L'incrément de base donne 4 caractères supplémentaires à chaque fois.
Étant donné v et notre formule v = b + r * 2 * b, nous devons trouver 2 entiers b et r. Je ne suis pas un expert dans ce genre d'équation, mais b = int sqrt (v / 2) est une bonne supposition de départ.
Nous avons alors un r et un b qui donnent ensemble une valeur proche de v. Nous atteignons v exactement avec un incrément répété (|| -) ou un décrément (| -).
Suivez le même raisonnement pour les nombres négatifs, hélas la formule est similaire mais pas égale.
la source
JavaScript, 398710
94 octets / caractères de code
J'ai trouvé une solution! ... puis j'ai lu la réponse de Sparr et c'était exactement la même chose.
Je pensais que je le publierais de toute façon, car js permet un peu moins de caractères.
Voici une version non réduite du code:
la source
Python, 398710 (71 octets)
Je pense que la solution la plus simple possible. Utilise 4 * n (+/- 1) caractères de stickstack pour représenter n.
la source