Texte de saveur
L'esolang Underload basé sur la pile a des liens intéressants avec la programmation fonctionnelle. L'un d'eux est son traitement du type de données numérique - comme le calcul lambda, vous représentez le nombre naturel N par une fonction qui effectue une action N fois.
Pour simplifier les choses, nous ne considérerons que le sous-ensemble suivant de commandes Underload:
:
- Cette commande duplique l'élément supérieur de la pile.*
- Cette commande concatène les deux premiers éléments de la pile en un seul élément.
Nous définissons un nombre de sous-charge N comme une chaîne de :
et *
qui, lorsqu'il est exécuté, consomme l'élément supérieur de la pile et produit N copies de cet élément concaténées ensemble. Quelques exemples:
- Il n'y a pas de chiffres de sous-charge 0, -1, 1/2, π.
- La chaîne vide
est le chiffre Underload 1, car elle laisse la pile intacte.
:*
est le nombre de sous-charge 2, car il duplique l'élément supérieur, puis concatène ces deux copies ensemble en un seul élément:(A):*
=(A)(A)*
=(AA)
.::**
est le chiffre de sous-charge 3:(A)::**
=(A)(A):**
=(A)(AA)*
=(AAA)
.:::***
est le chiffre de sous-charge 4.:*:*
est également le chiffre de sous-charge 4:(A):*:*
=(AA):*
=(AA)(AA)*
=(AAAA)
.
En général, vous constaterez que, si M
et N
sont les nombres de sous-charge M et N, alors :N*
est le chiffre N + 1, et MN
est le chiffre M × N.
Le défi
Votre tâche consiste à écrire le programme le plus court (en prenant l'entrée sur STDIN) ou la fonction (en prenant l'entrée via un argument) qui produit la représentation la plus courte du nombre de sous-charge pour son entrée sous forme de chaîne. Autrement dit, si l'entrée est un nombre naturel positif N> 1, vous devez produire un nombre de sous-charge N dont la longueur en caractères est inférieure ou égale à celle de tous les autres nombres de sous-charge N.
Exemples d'entrées et de sorties: ("Input - OUTPUT
.")
- 1 -
.
- 2 -
:*
. - 5 -
::*:**
(2 × 2 + 1). - 7 -
::*::***
(2 × 3 + 1) ou:::**:**
(3 × 2 + 1). - 33 -
::*:*:*:*:**
(2 × 2 × 2 × 2 × 2 + 1). - 49 -
::*:*:*:*::***
(16 × 3 + 1, longueur 14) mais pas::*::***::*::***
(7 × 7, longueur 16).
Si l'entrée n'est pas un nombre naturel positif, vous êtes libre de renvoyer une erreur, de produire un comportement indéfini ou même de ne pas terminer. Une explication de la méthode de votre soumission pour trouver la réponse est appréciée.
Des restrictions d'échappatoire standard s'appliquent: aucune entrée supplémentaire, aucune demande Web, la valeur de sortie / retour doit être exactement la réponse et non un flux aléatoire infini de :
et *
, etc.
x
est celle2*A117498(x)
où A117498 donne la combinaison optimale de méthodes binaires et factorielles pour trouver une chaîne d'addition.Réponses:
GolfScript (
61 60 55 5453 caractères)C'est moins compliqué que ma version précédente et adopte une approche légèrement différente, mais c'est toujours de la force brute. Nous savons que
':'X*'*'X*+
c'est une solution candidate, donc si nous générons toutes les chaînes bien équilibrées jusqu'à cette longueur et prenons la plus courte qui évalue à la bonne chose, nous pouvons être certains d'en trouver une.Merci à Howard, de la solution duquel j'ai volé quelques réglages de 1 caractère.
la source
.&
juste après la boucle intérieure (c'est-à-dire entre~}%
et}*
.GolfScript (
5453 caractères)C'est une approche qui est dans l'esprit d'Howard (construire des chaînes qui évaluent à la valeur correcte et sélectionner la plus courte, plutôt que la force brute à travers les chaînes candidates pour trouver celles qui évaluent à la valeur correcte), mais est suffisamment différente pour que je pense il appartient à une réponse séparée.
La démonstration en ligne n'est pas disponible car elle exécute une version boguée de l'interpréteur.
la source
3+
par)
(en exploitant le fait qu'il[]0=
ne reste rien sur la pile) si ce n'était pas le cas, cela[]2>
entraîne une erreur.[]2>
donne[]
sans erreur.'1'
.((=
lieu de-1=
.Python 2.7 -
878492Explication:
il s'agit d'une solution assez simple. Il teste récursivement toutes les représentations possibles de n comme le produit de deux nombres ou comme
:(n-1)*
, puis trouve la solution de longueur minimale. la plage (2, n) est nécessaire pour que la récursivité ait une profondeur limitée, et n <2 donne le cas de base.Remarques:
i et n / i sont les deux facteurs de n. Le remplacement ... et ... ou ... de ... si ... sinon ... ne fonctionne pas car '' est évalué comme faux. min de chaînes donne l'une des chaînes les plus courtes. Python 2.7 enregistre 1 caractère en utilisant / au lieu de //.
Edit: Déplacement du cas de base à l'arrière de l'expression, me permettant d'utiliser ... et ... ou ... et de raser quelques espaces.
Cas de test:
la source
key=len
. Il donne la chaîne lexicographiquement la plus ancienne. ( Exemple ). Puisque'*' < ':'
cela signifie que vous avez un parti pris pour les solutions impliquant des puissances de 2, mais sont-elles toujours les plus courtes?u(33)
, pour lequel le tri lexicographique donne le 14 caractères::**::*::*:***
mais le tri par longueur donne le 12 caractères::*:*:*:*:**
GolfScript,
635856 caractèresLe code prend l'entrée sur STDIN et imprime le résultat.
Exemples:
Vous pouvez tester vos propres cas en ligne .
la source
:x(=
bout. En outre, +1 pour pouvoir exécuter 49 dans un délai raisonnable.x,2>{x\%!},
donne tous les vrais diviseurs dex
,{.v=x@/v=+}/
puis concatène les solutions pourd
etx/d
pour tous les diviseursd
.{,}$
les trie par longueur et0=
prend le plus court d'entre eux (plus le:(x-1)*
cas initial ).Brachylog 2 , 30 (peut-être finalement 26) octets, défi de postdates de langue
Voici une fonction qui fonctionne avec l'implémentation actuelle de Brachylog 2 (et retourne une liste de codes de caractères car l'implémentation actuelle a quelques problèmes avec la gestion des chaînes):
Essayez-le en ligne!
La langue est encore très nouvelle. Voici une version de 26 octets du programme qui devrait fonctionner selon la spécification, mais utilise des fonctionnalités non implémentées, et n'est donc pas encore valide, mais le sera peut-être à l'avenir (il est également encore moins efficace):
Explication
L'idée de base est assez simple: nous alternons entre décomposer le nombre en (1 ou plusieurs) facteurs (pas nécessairement des facteurs premiers, mais les facteurs de 1 ne sont pas autorisés), et exprimer chacun de ceux-ci comme 1 + (une représentation obtenue à partir d'un récursif appel). Ceci est garanti pour rechercher toutes les représentations de sous-charge possibles du nombre (nous pouvons appliquer une étape de multiplication "deux fois de suite" en multipliant ensemble plus de 2 nombres, et une étape d'incrémentation deux fois de suite en les séparant avec une étape de multiplication qui se multiplie ensemble un seul numéro). Nous n'avons pas besoin d'un cas de base explicite, car la décomposition de 1 en facteurs premiers nous donne une liste vide, et donc nous la construisons avec une étape de multiplication qui multiplie les nombres nuls ensemble.
Le programme est assez inefficace, en particulier parce que le conseil d'ordre d'évaluation que j'ai donné (générer des réponses du plus court au plus long en termes de taille de la sortie éventuelle), tout en résolvant la partie "la plus courte" de la question, n'est pas terrible en termes de en fait, le programme se termine rapidement (un indice beaucoup plus utile serait de «générer uniquement la réponse la plus courte à chaque étape récursive», mais cela prend plus d'octets…). De plus, il
ḋp~c×ᵐ
peut générer plusieurs fois des partitions multiplicatives, ce qui fait que le programme fait beaucoup de travail redondant.la source
J - 81 car
Pour la postérité, c'était le mieux que je pouvais faire en J.
Nous créons une liste de résultats, en commençant par deux chaînes vides (c'est le
,~
eta:
) représentant 0 (jamais utilisé) et 1, puis nous répétons un verbe dessus (utilisation sournoise de crochets, de trains et&
) qui ajoute la représentation la plus courte du numéro suivant.Le verbe réel que nous itérons utilise la longueur de la liste comme indicateur du nombre sur lequel nous opérons. Tout d'abord, nous factorisons ce nombre en paires de facteurs (
#(#~]-:"1<.)@(],.%)2}.i.@#
) et récupérons chaque paire en tirant du tableau ({~
). Nous transformons chacune de ces paires (il pourrait y en avoir 0 si le nombre est premier) en chaînes simples (<@;"1
).Ensuite, nous ajoutons à cette liste l'entrée pour le résultat précédent entre crochets par
:
et*
, et trions cette liste par longueur ((/:#&>)
). Enfin, nous prenons le premier résultat de cette liste (0{
) et l'ajoutons à la fin du tableau de base ([,
). Lorsque la boucle est terminée, nous avons une liste de longueur 2 de plus que l'entrée, commençant à 0. Donc, ce que nous devons renvoyer est l'avant-dernière chaîne (_2{::
).la source
Jelly , 33 octets, défi de postdates de langue
Essayez-le en ligne!
Une solution simple de force brute.
Explication
Programme principal
Le programme principal utilise la fonction d'assistance pour énumérer toutes les manières possibles de produire la valeur par multiplication, puis essaie de produire la valeur par addition et renvoie la possibilité la plus courte. Il gère également le cas de base (une entrée de
1
).Fonction d'assistance
La fonction d'assistance essaie toutes les méthodes possibles pour exprimer l'entrée comme une multiplication de deux nombres, et appelle mutuellement récursivement le programme principal afin d'obtenir leurs représentations les plus courtes.
la source
GNU Prolog, 96 octets
La première ligne est une grammaire qui implémente l'évaluation de la sous-charge et fonctionne dans le sens inverse (en fait, elle ne fonctionne pas tout à fait en raison de la
A#<B
contrainte; changez-la enA#<N
pour un programme plus lent qui fonctionne dans les deux sens). La deuxième ligne définit le prédicat de type fonctions
(qui est la fonction implémentée comme solution à ce programme) qui trouve la chaîne la plus courte possible qui évalue le nombre donné en entrée (c'est frustrant pour ce qui est une tâche relativement simple, mais c'est Prolog pour vous…).Le programme devrait être assez explicite, étant donné qu'il s'agit plus ou moins d'une traduction directe de la spécification en grammaire, puis en syntaxe Prolog; la définition de
v
dit queN
est 1 dans une chaîne vide, ouN
estA
×B
(avecA
moins deB
moins queN
) et la chaîne est la concaténation dev(A)
etv(B)
, ouN
est signifie "S a une certaine longueur", mais en spécifiant cela comme la première chose sur la La ligne agit comme un indice pour l'implémentation de Prolog qu'elle doit d'abord vérifier les longueurs les plus courtes (ce qui signifie que nous obtiendrons la longueur la plus courte possible pour une valeur de retour).M
+ 1 et la chaîne est:
concaténée avecv(M)
concaténée avec*
. La deuxième ligne est un peu plus subtile;length(S,_)
la source