Je me rends compte que c'est un peu mathématique, mais - voilà.
En mathématiques, la séquence d'hyperopération est une séquence infinie d'opérations arithmétiques (appelées hyperopérations) qui commence par l'opération unaire du successeur, puis se poursuit par les opérations binaires d'addition, de multiplication et d'exponentiation, après quoi la séquence se poursuit avec d'autres opérations binaires s'étendant au-delà exponentiation, en utilisant l'associativité droite.
Votre objectif est d'écrire un programme qui prend en entrée trois entiers x, y et n et génère le résultat de la nième hyperopération sur x et y.
Par exemple
1 1 1
sorties 2
2 4 4
sorties 65536
3 3 4
sorties 7625597484987
- Le programme doit être écrit dans le bit de code le plus court.
- Vous pouvez prendre des entrées à partir
STDIN
ou à partir d'un fichier. - Fonctions de bibliothèque non autorisées.
- Contraintes d'entrée: n sera ≥ 1.
http://en.wikipedia.org/wiki/Tetration a une bonne explication au cas où vous ne pourriez pas vous en tenir compte.
la source
n=1
? Si c'estx+y
oux+1
,1 1 1
devrait revenir2
Réponses:
Rubis, lent,
86 8483 caractèresRubis, rapide,
96 9493 caractèresLa première version est beaucoup trop lente avec le dernier cas de test, j'ai donc ajouté une version qui utilise la multiplication comme cas de base au lieu de l'addition. La première version prend du temps à calculer
3 3 4
; la seconde est instantanée (dans la console IRB native; la version web est un peu plus lente).Plusieurs beautés de Ruby apparaissent ici:
Presque chaque déclaration est une expression en rubis. Ainsi, vous pouvez remplir des points-virgules à l'intérieur de l'opérateur ternaire, à condition que vous ayez suffisamment de parenthèses qui traînent. Coffeescript a emprunté celui-là. Il a également emprunté la syntaxe d'appel "sans parens nécessaire" de Ruby.
Retours implicites: il s'agit d'une fonctionnalité intéressante, qui découle de la précédente. En effet, commencer la dernière ligne d'une fonction avec
return
est considéré comme boiteux, même lorsqu'il ne joue pas au golf.Les nombres sont des objets en rubis (même
null
est un objet). En ruby, les entiers ont la méthodetimes
, qui exécute le bloc qui lui est passé plusieurs fois. Ceci n'est qu'une des nombreuses méthodes d'itérateur de Ruby. Ici, laupto
méthode nous permet d'enregistrer deux autres caractères sur ce quitimes
nous permet.unaire
*
est l'opérateur splat ici. Il transforme un tableau en liste d'arguments. Tout comme JavascriptFunction#apply
, mais il est plus court et meilleur.unaire
&
transforme une procédure en bloc. Bien que ce:to_i
soit un symbole, il se transforme assez bien en procédure. À savoir, il se transforme en une procédure qui fait appelto_i
à son argument et renvoie le résultat. Plus d'informations sur Stack Overflow.Il serait possible de l'obtenir encore plus rapidement en utilisant
n=3
comme cas de base, mais je crains que ce ne soit pas nécessaire. Cela ne coûterait que 11 caractères, cependant, grâce à une autre beauté de rubis: l'opérateur d'exponentiation**
. Python a cet opérateur, mais ce n'est pas le premier (comme l'a noté @ aka.nice - merci -, Fortran avait déjà cet opérateur).interprète de rubis en ligne disponible ici: http://repl.it/Ikj/1
la source
3 3 4
:) c'est très lent.APL, 62
{...}⎕
: Prend l'entrée évaluée (les nombres séparés par des espaces sont évalués dans un tableau numérique) et lui applique une fonction.1=3⌷⍵:
: Si n est égal à 1 ...2⌷+\⍵
: Retourne la somme des 2 premiers éléments (x + y) ...⋄0=2⌷⍵:
: Sinon si y est égal à 0 ...(⍵[3]⌊3)⌷⍵[1],0,1
: Crée un tableau numérique [x, 0,1] et retourne l'indexmin(n,3)
...⋄∇⍵[1],(∇⍵-0 1 0),3⌷⍵-1
: Sinon, retournez ∇ (x, ∇ (x, y-1, n), n-1). (∇ est auto-référence)J'ai un opérateur "hyper-raiser", qui prend une fonction et retourne la prochaine hyperopération
Par exemple,
+{⍺⍺/⊃⍴/⌽⍵}
serait la fonction de multiplication et les+{⍺⍺/⊃⍴/⌽⍵}5 3
sorties 15.Mais je ne peux pas le faire récuser. Peut-être que quelqu'un d'autre peut le faire.
la source
Python, 83
(Basé sur la réponse de Flornquake )
Très lent pour de grands résultats.
Car
2, 4, 4
la sortie est65536
.la source
Python,
9692Entrée:
3, 3, 4
Sortie:
7625597484987
Raccourci en utilisant quelques idées de @ WolframH .
la source
Golfscript, lent, 39 caractères
(lien en direct)
Il s'agit de l'algorithme récursif standard avec un cas de base de n = 1 (addition) (c'est-à-dire lent). Le même que j'ai utilisé dans ma solution Ruby
Voici une version avec mes annotations (principalement la conservation de la pile). Il ne comprend pas une optimisation que j'ai ajoutée plus tard:
~
est l'opérateur eval. Dans le cas de chaînes, il traite la chaîne comme un programme GolfScript. Heureusement, une liste d'entiers séparés par des espaces est un programme GolfScript valide qui pousse ces entiers sur la pile. Par rapport à cela, ma version précédente de la routine d'entrée (" "/{~}/
, divisée par espace et eval chacun) est assez boiteuse. En cas de fonctions, il appelle la fonction. Lorsqu'elle est précédée de.
(clone), elle appelle la fonction avec elle-même comme premier argument.Golfscript ne semble pas être parfaitement adapté à la création d'algorithmes récursifs. Si vous voulez un algorithme récursif qui ne soit pas optimisé pour les appels de queue, vous devez créer et détruire des cadres de pile pour préserver vos variables. Dans la plupart des langues, cela se fait automatiquement. Dans golfscript, vous devez réellement cloner les variables (en fait, les entrées de pile) et détruire les entrées de pile dont vous n'avez plus besoin. Golfscript n'a aucun concept de cadres de pile. Ai-je dit que GolfScript est un langage basé sur la pile?
La première exigence est compréhensible. Vous devez en quelque sorte spécifier les arguments. Ce n'est agréable que s'ils conservent également leur position d'origine. La deuxième exigence est regrettable, d'autant plus que la valeur de retour est au sommet de la pile, et golfscript n'a pas la possibilité de supprimer n'importe quel élément de la pile. Vous pouvez faire pivoter la pile et jeter le nouvel élément supérieur, mais cela s'accumule rapidement.
\;
c'est bien.\;\;\;\;\;
n'est pas. Vous pouvez le faire\;
en boucle ({\;}9*
; coût: 6 caractères pour éliminer jusqu'à 9 éléments, ou 7 caractères pour supprimer jusqu'à 99 éléments), mais nous pouvons faire mieux:Golfscript a des tableaux de première classe. Il a également la syntaxe littérale du tableau
[1 2 3 4]
. Ce qui est inattendu est que[
et]
ne sont pas en fait une partie de la syntaxe. Ce ne sont que deux opérateurs:[
marque la position actuelle sur la pile, et]
collecte chaque élément jusqu'à ce qu'il trouve la marque de début de tableau ou soit à court de pile, et rejette la marque. Vous pouvez même les déchirer et voir ce qui se passe. Eh bien, une chose assez intéressante:Ai-je dit que golfscript n'a pas de concept de cadres de pile? J'ai menti. Ceci est un cadre de pile:
[
. Vous pouvez jeter tout à la fois:];
. Mais que se passe-t-il si nous voulons conserver la valeur de retour? Vous pouvez fermer le cadre de pile à l'entrée de la fonction (alors nous avons une version légèrement modifiée du tableau de bord - ce n'est pas un concept intéressant), ou nous pouvons fermer le cadre de pile et prendre son dernier élément au lieu de le supprimer complètement:]-1=
ou nous peuvent uncons le dernier élément à la place, et puis jeter le cadre:])\;
. Ils ont la même longueur, mais ce dernier est légèrement plus frais, donc je l'utilise.Donc, au lieu de 6 ou 7 caractères pour faire un nettoyage, nous pouvons le faire avec 5. Je pense toujours que cela pourrait être joué plus, mais bon, nous avons sauvé un personnage.
la source
Smalltalk Squeak 4.x saveur de nombreux octets!
Je pourrais implémenter l'une des formes récursives dans Integer en 71 caractères
La lecture d'un fichier ou d'un fichier FileStream stdin me coûtera un bras ... Squeak n'a évidemment pas été conçu comme un langage de script. Je vais donc dépenser de nombreux octets pour créer mes propres utilitaires à usage général sans rapport avec le problème:
Implémenter cette méthode de 21 caractères dans Stream (pour ignorer les Seaparators)
Implémentez cette méthode de 20 caractères dans Behavior (pour lire une instance à partir d'un flux)
Puis 28 caractères en chaîne (pour créer un descripteur de fichier)
Puis 59 caractères dans FileDirectory (pour créer un readStream)
Puis 33 caractères dans BlockClosure (pour l'évaluer n fois)
Puis 63 caractères dans le tableau (évaluer l'argument avec le récepteur et les arguments tirés du tableau)
puis résolvez le problème en évaluant cet extrait de 31 caractères n'importe où pour lire à partir du fichier nommé x
Même sans compter les utilitaires, c'est déjà 71 + 31 = 102 caractères ...
Maintenant, comme je suis sûr de perdre le codeGolf, j'ai une implémentation plus amusante dans Integer:
Cette méthode définira (compilera) un message binaire en n + s'il n'existe pas (n'est pas compris par le destinataire du message m), et recommencera l'exécution au début du contexte émetteur. J'ai inséré un retour chariot supplémentaire et des espaces pour plus de lisibilité.
Notez que
(m selector size-2min:1)hex last
c'est une forme abrégée de(m selector size>2)asBit printString
.Si ce n'était pas pour démontrer les super-pouvoirs maléfiques de Smalltalk, la dernière déclaration pourrait être remplacée par une plus courte et plus simple
Maintenant, implémentez l'utilitaire 28 caractères dans Caractère (pour le répéter n fois dans une chaîne)
Évaluez ensuite cette expression de 43 caractères:
Nous pouvons accélérer avec 10 caractères supplémentaires en implémentant Integer:
et dans ce cas, nous avons également un code plus court, car nous pouvons remplacer
^',(m selector size-2min:1)hex last
par^1'
Pour un prix aussi élevé, le code fonctionne avec un deuxième entier = 0 :)
la source
Groovy - 77
Remarque: il nécessite des quantités obscènes de pile (et de temps) pour des arguments non minuscules.
la source
Système d'algèbre informatique AXIOM, octets 69
tester:
Cela éliminerait une certaine récursivité ... Possible que j'échange en x et y en retour ... y a-t-il d'autres valeurs de test?
la source
APL (NARS), caractères 61, octets 122
tester:
la source