Additionner les puissances à n

14

instructions

Écrivez un programme qui, étant donné un entier d'entrée n ( n >= 0), sort le plus petit entier positif m où:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • aet bsont des séquences finies de la même longueur
  • tous les éléments de asont inférieurs àm
  • tous les éléments de bsont inférieurs àm
  • tous les éléments de asont différents et entiersa[x] >= 0
  • tous les éléments de bsont différents et entiersb[x] >= 0
  • a[x]et b[x]ne sont pas tous les deux 0 (puisque 0 ^ 0 est indéterminé)

Il s'agit de , donc le moins d'octets gagne.

Exemples

In 0 -> Out 1
Possible Sum: 

In 1 -> Out 2
Possible Sum: 1^0

In 2 -> Out 3
Possible Sum: 2^1

In 3 -> Out 3
Possible Sum: 2^1 + 1^0

In 6 -> Out 4
Possible Sum: 2^2 + 3^0 + 1^1

In 16 -> Out 5
Possible Sum: 2^4

In 17 -> Out 4
Possible Sum: 3^2 + 2^3

In 23 -> Out 6
Possible Sum: 5^1 + 3^0 + 2^4 + 1^3

In 24 -> Out 5
Possible Sum: 4^2 + 2^3

In 27 -> Out 4
Possible Sum: 3^3

In 330 -> Out 7
Possible Sum: 6^1 + 4^3 + 3^5 + 2^4 + 1^0
kukac67
la source
Comment sommes-nous censés faire une séquence d'entiers uniques et non négatifs qui a une somme non infinie?
feersum
De plus, le premier cas n'a pas de sens car une somme avec 0 termes suffirait.
feersum
@feersum Je ne comprends pas très bien votre question. Ma solution à cela est une recherche par force brute de toutes les combinaisons où m<2puis m<3alors m<4etc. jusqu'à ce que je trouve une somme égale n. Aussi, j'ai pensé à ne pas avoir de somme 0, mais quelle est la sortie? m>?
kukac67
1
Pour les séquences finies, vous feriez généralement quelque chose comme n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k].
Volatilité
1
Bonne question. Juste une petite critique sur le premier cas de test: aet bsont des séquences finies de longueur 0, donc il n'y a pas d'entier mqui ne satisfait pas aux contraintes, et comme il n'y a pas de plus petit entier, la réponse n'est pas définie. Les correctifs possibles seraient de demander le plus petit nombre naturel m(auquel cas vous devriez y changer la réponse attendue 0) ou le plus petit entier positif m.
Peter Taylor

Réponses:

2

GolfScript (59 caractères)

~:T),{),.0{2$0-{2${{4$2$^}2*@3$\?4$+f~}%\;~}%+\;\;}:f~T&}?)

Démo en ligne

Cela utilise la récursivité pour énumérer les valeurs réalisables pour une donnée met recherche la première mqui fonctionne. Il est légèrement inspiré par la réponse de xnor mais tout à fait différent dans la mise en œuvre.

Dissection

~:T                  # Evaluate input and store in T (for Target)
),{                  # Search [0 1 ... T] for the first m which matches a predicate
  ),.0               #   Push [0 ... m] to the stack twice and then 0
                     #   Stack holds: possibleAs possibleBs sum
  {                  #   Define the recursive function f
    2$0-{            #     Map over A in possibleAs (except 0)
      2${            #       Map over B in possibleBs (except 0)
        {4$2$^}2*    #         Duplicate respective possibles and remove selected values
        @3$\?4$+     #         Compute sum' = sum + A^B
        f            #         Recursive call gives an array [sums]
        ~            #         Push the sums to the stack individually
        }%           #       End map: this collects the sums into a combined array
      \;             #       Pop A, leaving just the combined [sums] inside the map
      ~              #       Repeat the trick: push to the stack individually
    }%               #     End map, collecting into a combined array
                     #     Stack now holds: possibleAs possibleBs sum [sums]
    +                #     Include the original sum in the array of reachable sums
    \;\;             #     Pop possibleAs and possibleBs
  }:f                #   End function definition
  ~                  #   Evaluate the function
  T&                 #   Test whether the sums contain T
}?                   # End search
)                    # Increment to get m
Peter Taylor
la source
6

Python, 120

f=lambda n,A,B:n*all(f(n-a**b,A-{a},B-{b})for a in A for b in B)
g=lambda n,m=1,M={0}:f(n,M-{0},M)and g(n,m+1,M|{m})or m

La fonction fest une fonction auxiliaire qui vérifie si elle nen peut pas être exprimée comme une somme de puissances avec des bases distinctes Aet des exposants deB . Il utilise une stratégie récursive naturelle: ndoit être différente de zéro, et nous essayons tous les choix possibles de base et d'exposant et ils doivent tous échouer. Nous les supprimons des listes autorisées et diminuonsn du montant correspondant.

La fonction gest la fonction principale. Il recherche un mqui fonctionne. Mest l'ensemble des valeurs autorisées jusqu'à m-1. Nous supprimons 0des exposants autorisés à arrêter 0**0(que Python évalue à 1) d'être utilisés. Cela ne fait rien de mal Parce que 0**xc'est inutile 0pour tous les autres x.

xnor
la source
Vous pourriez probablement changer n and all()pour n*all().
grc
@grc Ah, vous n'avez pas vraiment besoin du court-circuit, car il se termine. Merci pour l'amélioration.
xnor
4

Python 2, 138 octets

from itertools import*
S=lambda n,m=0,R=[]:m*any(n==sum(map(pow,*C))for k in R for C in product(*tee(permutations(R,k))))or S(n,m+1,R+[m])

(Merci à @Jakube pour tous les conseils)

Je n'ai jamais autant appris sur le itertoolsmodule que sur cette seule question. Le dernier cas prend environ une minute.

Nous commençons par rechercher m = 1et incrémenter jusqu'à ce que nous obtenions une solution. Pour rechercher une solution, nous parcourons:

  • k = 0 to m-1, où kest le nombre de termes dans la solution
  • Toutes les combinaisons possibles de termes (en zippant ensemble deux permutations de sous-ensembles de [0, 1, ... m-1]taille k), puis en additionnant et en vérifiant si nous avonsn

Notez que nous répétons kjusqu'à m-1- même si techniquement des mtermes sont possibles au total, il y a toujours une solution avec des m-1termes comme cela 0^0n'est pas autorisé et 0^bne contribue rien. C'est en fait important car il 0^0est traité comme 1 par Python, ce qui semble être un problème, mais cela n'a pas d'importance!

Voici pourquoi.

Supposons qu'une solution trouvée utilise par erreur 0^0comme 1, par exemple 3^2 + 1^1 + 0^0 = 11. Puisque nous ne générons que des m-1termes, il doit y en avoir certains que jnous n'utilisons pas comme base (ici j = 2). Nous pouvons échanger la base 0 pour jobtenir une solution valide, ici 3^2 + 1^1 + 2^0 = 11.

Si nous avions répété tous les mtermes, alors nous aurions pu obtenir des solutions incorrectes comme m = 2pour n = 2, via 0^0 + 1^1 = 2.

Sp3000
la source
Joli. Vous pouvez cependant économiser 4 octets en utilisant imap. imap(pow,C,D) ... for C,D in
Jakube
@Jakube Je suis en train de regarder le document itertoolsen ce moment: PI a déjà une autre économie - tee.
Sp3000
Moi aussi. Aussi, mon erreur. Pourquoi quelqu'un suggérerait imap-il quand il y en a map? -1 octet
Jakube
Le paramètre par défaut de teeest déjà n=2. Enregistre 2 octets.
Jakube
@Jakube Ahaha merci. C'est probablement la première fois que je l'utilise mapavec plus d'un itérable, et en fait, cette question fait ressortir beaucoup de premières pour moi.
Sp3000
4

GolfScript ( 90 84 octets)

[0.,.]](~:T),(+{:x;{:|2,{:c)|=x),^{c[1$x]=:A^x^:-;[|~-+@A-?+@A+@]}%}/+~}%.[]*T&}?)\;

Démo en ligne

Dissection

[0.,.]             # Base case: [sum As Bs] is [0 [] []]
](~:T              # Collect it in an array of cases; fetch parameter, eval, store in T.
),(+               # Create array [1 2 ... T 0]. Putting 0 at the end means that it won't
                   # be reached except when T is 0, and nicely handles that special case.
{                  # Loop over the values from that array...
  :x;              #   ...assigning each in turn to x (and popping it from the stack)
  {                #   Stack holds array of [sum As Bs] cases; map them...

    :|             #     Store [sum As Bs] in |
    2,{:c          #     For c in [0 1]...
      )|=x),^      #       Get [0 1 ... x]^ either As or Bs, depending on c
      {            #       Map these legal new As or Bs respectively...
        c[1$x]=:A  #         Work out which of that value or x is the new A
        ^x^:-;     #         And the other one is the new B
        [          #         Begin gathering in an array
          |~       #           Push sum As Bs to the stack
          -+       #           Add - to Bs to get Bs'
          @A-?+    #           Rotate sum to top and add A^- to get sum'
          @A+      #           Rotate As to top and add A to get As'
          @        #           Final rotation to put elements in the right order
        ]          #         Gather in array [sum' As' Bs']
      }%           #       End map
    }/             #     End for
    +~             #     Push all the elements corresponding to x^B and A^x on to the stack
  }%               #   End map, collecting the untouched [sum As Bs] and all the new
                   #   [sum' As' Bs'] arrays into a new array of reached cases.
  .[]*T&           #   Flatten a copy of that array and filter to values equal to T.
                   #   This gives a truthy value iff we've found a way to make T.
}?                 # Loop until we get a truthy value, and push the corresponding x
)\;                # Increment to get the value of m and discard the array of cases

L'astuce la plus élégante est la manipulation du boîtier spécial pour 0.

Peter Taylor
la source
Je suis vraiment heureux que CJam soit cette fois pas beaucoup plus court que le python standard = P
flawr
@flawr, c'est GolfScript, pas CJam. CJam peut probablement être un peu plus court car il a une fonction intégrée pour les produits cartésiens. Et il se pourrait que l'idée de xnor d'une fonction récursive donne également un GolfScript plus court.
Peter Taylor
Oh désolé, viens de les confondre =)
flawr
4

Haskell, 143 130

import Data.List
p n=head$[1..]>>=(\m->[m|let x=permutations[0..m-1]>>=inits,a<-x,b<-x,sum(zipWith(\x y->x^y*signum(x+y))a b)==n])

Exemple d'utilisation: p 23-> 6.

Il s'agit d'une simple recherche par force brute. Pour chaque liste, [0..0], [0..1], [0..2] ... [0..∞]prenez tous les segments initiaux des permutations (par exemple [0..2]: permutations:, [012], [102], [210], [120], [201], [021]segments initiaux pour la 1ère permutation:, [0], [01], [012]2e:, [1], [10], [102]etc.). Pour chaque combinaison de 2 de ces listes, calculez la somme des puissances. Arrêtez lorsque le premier est égal à n.

nimi
la source
vous devez utiliser >>=plutôt que concatMap. ce sont les mêmes, mais les arguments sont inversés.
fier haskeller du
@proudhaskeller: Oui, merci!
nimi
2

Python: 166 caractères

from itertools import*;p=permutations
f=lambda n,r=[0]:any(n==sum(map(lambda x,y:(x+y>0)*x**y,a,b))for j in r for a,b in product(p(r,j),p(r,j)))*1or 1+f(n,r+[len(r)])

Explication

La fonction fcrée tous les entiers possibles, qui peuvent être exprimés comme la somme des puissances des nombres dans r. Si commence par r = [0]. Si l'un de ces entiers est égal à n, il renvoie la longueur de r, sinon il s'appelle récursivement avec un étendu r.

Le calcul de tous les entiers, qui peuvent être exprimés en somme, se fait avec deux boucles. La première boucle est la for j in r, qui nous indique la longueur de l'expression (2 ^ 3 + 1 ^ 2 a la longueur 2). La boucle intérieure itère sur toutes les combinaisons de permutations rde longueur j. Pour chacun, je calcule la somme des puissances.

Jakube
la source
2

JavaScript (ES6) 219 224

Fonction récursive. En commençant par m = 1, j'essaie toutes les combinaisons d'entier 1..m pour les bases et 0..m pour les exposants (0 base est inutile étant donné 0 ^ 0 == indéfini).
Si aucune solution n'est trouvée, augmentez m et réessayez.
Cas particulier pour l'entrée 0 (à mon avis c'est quand même une erreur dans les spécifications)

La fonction C génère récursivement toutes les combinaisons à partir d'un tableau de longueur donnée, de sorte que

C(3, [1,2,3]) --> [[3,2,1], [3,1,2], [2,3,1], [2,1,3], [1,3,2], [1,2,3]]

Le troisième niveau everyest utilisé pour compresser ensemble le tableau a de bases et b d'exposants (il n'y a pas de zipfonction en JavaScript). En utilisantevery d'arrêter tôt lorsqu'il existe une solution n'utilisant pas tous les éléments des deux tableaux.

F=(n,j=1,k=[],
  C=(l,a,o=[],P=(l,a,i=l)=>{
    for(l||o.push(a);i--;)
      e=[...a],P(l-1,e.concat(e.splice(i,1)))
  })=>P(l,a)||o
)=>n&&C(k.push(j++),k)[E='every'](a=>C(j,[0,...k])[E](b=>a[E](x=>t-=Math.pow(x,b.pop()),t=n)))
?F(n,j,k):j

Test dans la console FireFox / FireBug

;[0,1,2,3,6,16,17,23,24,27,330].map(x=>[x,F(x)])

Production

[[0, 1], [1, 2], [2, 3], [3, 3], [6, 4], [16, 5], [17, 4], [23, 6], [ 24, 5], [27, 4], [330, 7]]

edc65
la source