Changement de base héréditaire

9

Contexte

Dans ce défi, une représentation de baseb d'un entier nest une expression de ncomme une somme de puissances de b, où chaque terme se produit le plus b-1souvent. Par exemple, la 4représentation de base de 2015est

4^5 + 3*4^4 + 3*4^3 + 4^2 + 3*4 + 3

Maintenant, la représentation héréditaire de base bde nest obtenue en convertissant les exposants en leurs breprésentations de base , puis en convertissant leurs exposants, et ainsi de suite récursivement. Ainsi, la 4représentation héréditaire de la base 2015est

4^(4 + 1) + 3*4^4 + 3*4^3 + 4^2 + 3*4 + 3

Comme exemple plus complexe, la 3représentation héréditaire de la

7981676788374679859068493351144698070458

est

2*3^(3^(3 + 1) + 2) + 3 + 1

Le changement de base héréditaire de nde bàc , noté H(b, c, n), est le nombre obtenu en prenant la breprésentation de base héréditaire de n, en remplaçant chaque bpar cet en évaluant l'expression résultante. Par exemple, la valeur de

H(3, 2, 7981676788374679859068493351144698070458)

est

2*2^(2^(2 + 1) + 2) + 2 + 1 = 2051

Le défi

On vous donne en entrée trois entiers b, c, n, pour lequel vous pouvez prendre pour acquis n >= 0et b, c > 1. Votre sortie est H(b, c, n). Le nombre d'octets le plus court l'emporte et les failles standard sont interdites. Vous pouvez écrire soit une fonction soit un programme complet. Vous devez être capable de gérer des entrées et des sorties arbitrairement grandes (bignums).

Cas de test

4 2 3 -> 3
2 4 3 -> 5
2 4 10 -> 1028
4 4 40000 -> 40000
4 5 40000 -> 906375
5 4 40000 -> 3584
3 2 7981676788374679859068493351144698070458 -> 56761
2 3 2051 -> 35917545547686059365808220080151141317047

Fait amusant

Pour tout entier n, la séquence obtenue par

n1 = n
n2 = H(2, 3, n1) - 1
n3 = H(3, 4, n2) - 1
n4 = H(4, 5, n3) - 1
....

atteint finalement 0. Ceci est connu comme le théorème de Goodstein .

Zgarb
la source

Réponses:

6

CJam, 60 58 45 43 41 38 36 octets

Merci à Optimizer pour avoir économisé deux octets.

l~:C;:B;{Bb)1$,,@f{1$~=C@)F#*+}~}:F~

Testez-le ici.

Prend entrée dans l'ordre n b c.

Vous pouvez l'utiliser pour tester exécuter tous les cas de test:

"3 4 2 
3 2 4 
10 2 4 
40000 4 4 
40000 4 5 
40000 5 4 
7981676788374679859068493351144698070458 3 2 
2051 2 3 "N/
{
~:C;:B;{Bb)1$,,@f{1$~=C@)F#*+}~}:F~
p}/

Explication

Il s'agit d'une implémentation assez directe du processus expliqué dans le défi, sauf que j'entrelace l'expansion de base récursive, la substitution de base et le calcul du résultat final:

l~:C;:B;{Bb)1$,,@f{1$~=C@)F#*+}~}:F~
l~:C;:B;                             "Read and evaluate input, store b and c in B and C.";
        {                       }:F  "Define a block F. This performs the required conversion.";
         Bb                          "Get digits of input number in base B.";
           )                         "Split off 0-power digit.";
            1$,                      "Copy remaining digits. Get their length n.";
               ,                     "Make array [0 1 ... n-1].";
                @                    "Pull up remaining digits.";
                 f{           }      "Map this block onto the range, passing in the digits
                                      as a second argument each time.";
                   1$~=              "Copy current i, bitwise complement, access digit array.
                                      This accesses the digits in reverse order.";
                       C             "Push the new base C.";
                        @)           "Pull up current i and increment to get power.";
                          F          "Apply F recursively.":
                           ~         "Raise C to the resulting power.";
                            *        "Multiply by digit.";
                             +       "Add to running total.";
                               ~     "The result will be in an array. Unwrap it.";
                                   ~ "Execute F on the input n.";
Martin Ender
la source
8

Python 2, 55

H=lambda b,c,n,s=0:n and n%b*c**H(b,c,s)+H(b,c,n/b,s+1)

Une solution récursive. Comme l'algorithme récursif pour convertir entre les bases, sauf qu'il se reproduit également sur l'exposant.

Nous nous divisons nen deux parties, le chiffre actuel n%bet tous les autres chiffres n/b. La valeur de position actuelle est stockée dans le paramètre facultatif s. Le chiffre actuel est converti en base cavec c**et l'exposant sest converti récursivement. Le reste est ensuite converti de la même manière, +H(b,c,n/b,s+1)mais la valeur de position sest supérieure.

Contrairement à la conversion de base, la conversion de base héréditaire nécessitait de se rappeler la valeur de position actuelle dans la récursivité pour qu'elle soit convertie.

Pour faciliter la lecture, voici à quoi cela ressemble quand bet csont des constantes globales fixes.

H=lambda n,s=0:n and n%b*c**H(s)+H(n/b,s+1)
xnor
la source
J'ai posté ce surtout parce que je ne savais pas que vous pouvez utiliser des arguments nommés dans pyth: D(GHY=Z0)R&Y+*%YG^H(GHZ)(GH/YGhZ. N'hésitez pas à l'ajouter si vous le souhaitez (je m'en vais aux astuces pour jouer au golf en pyth: D)
FryAmTheEggman