Numéros auto-sommés


12

Convertir un nombre en une somme de chiffres

Pas de somme: nous avons besoin de la somme la plus courte
Pas de chiffres: vous ne pouvez utiliser que les chiffres du nombre

Exemple
On vous donnera en entrée un entiern>0

Disons n=27. Vous devez exprimer 27sous forme de somme , en utilisant uniquement les chiffres [2,7] , de la manière la plus courte possible. Vous n'êtes pas obligé d'utiliser tous les chiffres du numéro donné!

Alors 27=2+2+2+7+7+7. Nous avons ensuite prendre ces chiffres et les compte : [2,2,2,7,7,7].
La réponse finale n=27est6

Un autre exemple pour n=195obtenir la somme la plus courte, nous devons utiliser les chiffres suivants:
[5,5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]et la réponse est23

Le défi

Étant donné un entier n>0, affichez le nombre minimum de chiffres (contenus dans le nombre) qui résument ce nombre

Cas de test

Input->Output

1->1  
2->1  
10->10  
58->8  
874->110  
1259->142  
12347->1765  
123456->20576  
3456789->384088  

C'est le . La réponse la plus courte en octets gagne!


Y a-t-il des chiffres qui ne peuvent pas s'additionner / seront-ils entrés?
Stephen

1
@Stephen Ils le peuvent tous!

7
@Stephen Parce que chaque nombre peut être exprimé comme d_0 + 10 * d_1 + 100 * d_2, etc ...
geokavel

Pouvons-nous prendre l'entrée en tant que chaîne, tableau de caractères ou tableau d'entiers?
Kevin Cruijssen

1
@KevinCruijssen La chaîne est correcte. char-array ou integer-array ne le sont pas.

Réponses:


4

Husk , 12 octets

Lḟo=⁰ΣṁΠḣ∞d⁰

Gère les nombres à deux chiffres assez rapidement. Essayez-le en ligne!

Explication

Lḟo=⁰ΣṁΠḣ∞d⁰  Input is n, say n = 13.
          d⁰  Digits of n: [1,3]
         ∞    Repeat infinitely: [[1,3],[1,3],[1,3],[1,3]...
        ḣ     Prefixes: [[],[[1,3]],[[1,3],[1,3]],[[1,3],[1,3],[1,3]],...
      ṁ       Map and concatenate
       Π      Cartesian product: [[],[1],[3],[1,1],[3,1],[1,3],[3,3],[1,1,1],[3,1,1],...
 ḟo           Find the first element
     Σ        whose sum
   =⁰         equals n: [3,3,3,3,1]
L             Return its length: 5

2

Pyth , 12 octets

lef!-TsM`Q./

Essayez-le en ligne!

Malheureusement, il y a des erreurs de mémoire sur des entrées aussi grandes que 58.

Explication

lef!-TsM`Q./
          ./    All lists of integers that sum to [the input]
  f             Filter for:
    -TsM`Q           Remove all occurrences of the digits in the input
   !                 Check if falsey (i.e. an empty list)
le              Length of the last occurrence, which is the shortest because all the
                filtered partitions share the same digit pool

Pourriez-vous ajouter une explication?
Jonah

@ Explication Jonah ajoutée.
notjagan

1
Merci. Intéressant que Pyth ait une primitive qui résout essentiellement le problème dans./
Jonah

Alternative à 12 octets: lef<.{TjQ;./(filtre - sous-ensemble approprié - des chiffres de l'entrée)
M. Xcoder

2

Mathematica, 78 octets

(t=1;While[(s=IntegerPartitions[x=#,t,IntegerDigits@x])=={},t++];Tr[1^#&@@s])&  

trouve le dernier cas de test en 5 sec


Un peu plus court:Length@IntegerPartitions[#, All, Sort@DeleteCases[0]@IntegerDigits@#, 1][[1]] &
Kuba

2

R , 78 octets

function(n){while(all(F-n)){F=outer(F,n%/%10^(0:nchar(n))%%10,"+")
T=T+1}
T-1}

Essayez-le en ligne! (version golfée)

Algorithme de force brute pur, donc il ne résout pas réellement tous les cas de test, et je pense qu'il a essayé d'allouer 40 000 Go pour le dernier cas de test ...

Tdans R par défaut 1, nous obtenons donc une erreur de coup par coup que nous corrigeons à l'étape de retour, mais nous obtenons également les Fdéfauts par défaut 0.

explication non golfée:

function(n){
 d <- n%/%10^(0:nchar(n))%%10   # digit list with a 0 appended at end
 d <- unique(d[d>0])            # filter zeros (not technically necessary)
                                # and get unique digits
 x <- 0                         # storage for sums
 i <- 0                         # counter for number of sums done
 while(!any(x==n)){             # until we find a combination
  x <- outer(x,d,"+")           # take all sums of x and d, store as x
  i <- i + 1}                   # increment counter
i}                              # return counter

Essayez-le en ligne! (version moins golfy)


2

Python 2, 168 155 144 octets

Ce n'est pas le plus court possible, mais c'est le meilleur avant tout et pas vraiment mauvais, en termes d'exécution.

n=input()
g=sorted(set(n)-{0})[::-1]
def h(k):
 if k<0:return
 if`k`in g:return 1
 for d in g:
  f=h(k-int(d))
  if f:return 1+f
print h(int(n)) 

Le filter(None...est de supprimer 0 comme chiffre, ce que j'ai appris que je pouvais faire en faisant cela.

Le plus gros problème est les cadres de pile python, qui ne me permettent pas de l'exécuter sur les plus grandes entrées. Donc, ce n'est pas une solution valable, vraiment, j'ai joué avec l'augmentation de la limite de récursivité qui a juste conduit à des défauts de segmentation. Cela doit être fait avec une boucle et une pile ou avec beaucoup plus d'intelligence pour travailler en python.

edit: Merci à caird et Chas Brown pour 13 octets!


Vous pouvez utiliser inputet exiger que l'entrée soit entourée de guillemets.
caird coinheringaahing

2
Il est parfaitement acceptable d'échouer en raison de limitations physiques, tant qu'il réussit en théorie, ce qui est le cas.
Jonathan Allan

Économisez 9 octets en remplaçant filter(None,sorted(map(int,set(n)))[::-1])par sorted(set(map(int,n))-{0})[::-1](bien que la Nonechose soit assez agréable à savoir).
Chas Brown

@ChasBrown Dans la plupart des cas, vous pouvez utiliser filter(len,...)pour les listes et les chaînes et filter(abs,...)pour les entiers et les flottants.
2017


0

JavaScript (ES6), 82 octets

f=(n,l=0,a=n,[c,...b]=a)=>n?1/c?Math.min(!+c|+c>n?1/0:f(n-c,l+1,a),f(n,l,b)):1/0:l
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Prend l'entrée sous forme de chaîne.


Pouvez-vous expliquer pourquoi vous utilisez 1/0?
Zacharý

1
@ Zacharý Je veux la somme la plus courte, c'est-à-dire le nombre minimum de chiffres. Les tentatives qui conduisent à une solution invalide ne doivent pas compter, donc pour les exclure, elles marquent Infinity, ce qui n'affecte pas le minimum.
Neil

Oh, je ne savais pas que c'était récursif.
Zacharý

@ Zacharý Le f=au début est un grand indice, puisque vous n'en avez pas besoin pour les lambdas non récursifs.
Neil

0

Rubis , 70 octets

->n{w,s=n.digits,0;s+=1while !w.product(*[w]*s).find{|x|x.sum==n};s+1}

Très lent, essayez toutes les combinaisons possibles en augmentant la taille jusqu'à arriver à une solution.

Merci Dennis pour Ruby 2.4 sur TIO.

Essayez-le en ligne!


0

Gelée , 23 octets

D;0ṗµḟ€0
ÇS€=µT
Çị1ĿL€Ṃ

Essayez-le en ligne!

C'est tellement inefficace, qu'il ne s'exécute pas pour les cas de test après le troisième sur TIO en raison d'une limite de temps> _ <

Tous les conseils de golf sont les bienvenus!


0

Python 2 , 183 176 172 172 166 161 octets

def f(n,D=0,p=0,b=0):
	D=D or set(map(int,`n`))-{0}
	d=min(D);c=0;D=D-{d}
	q=[p+n/d,b][n%d>0]
	while c<min(D or{0}):q=b=f(n-c*d,D,p+c,b);c+=1
	return[q,b][q>b>0]

Essayez-le en ligne!

Plus long que l'autre réponse Python, mais effectue tous les cas de test combinés plus 987654321en moins d'une seconde sur TIO.

Profite du fait que si d1<d2sont des chiffres, alors il doit y avoir au plus d2-1 d1dans la somme (puisque les d2instances de d1peuvent être remplacées par des d1instances de d2pour une somme plus courte). Ainsi, en triant les chiffres par ordre croissant, il n'y a "que" tout au plus 9! = 362880des sommes possibles à considérer; et une profondeur de récursivité maximale de 9(quelle que soit la valeur de n).


0

Haskell , 91 octets

f n=[read[c]|c<-show n,c>'0']#n!!0
s#n|n>0,x:m<-(s#).(n-)=<<s=[1+minimum(x:m)]|1<3=[0|n==0]

Essayez-le en ligne! Exemple d'utilisation: f 58rendements 8. Rapide pour les nombres à deux chiffres, horriblement lent pour les entrées plus grandes.

La fonction fconvertit le numéro d'entrée nen une liste de chiffres tout en filtrant les zéros. Ensuite, cette liste et nelle-même sont transmises à la (#)fonction, qui retourne une liste singleton. !!0renvoie l'élément de cette liste singleton.

(#)utilise des listes singleton et vides comme type d'option. Étant donné l'entrée de n=58et s=[5,8], l'idée est de soustraire tous les chiffres sde n, puis d'appliquer récursivement (#)et de vérifier quel chiffre a entraîné le nombre minimum d'étapes et de retourner un plus ce minimum comme résultat. La première partie est calculée par (s#).(n-)=<<s, qui est la même que concat(map(s#)(map(n-)s)). Ainsi, dans notre exemple, le premier [58-5,58-8]est calculé, suivi par [[5,8]#53,[5,8]#50]lequel résulte en [[7],[7]]ou [7,7]après concat. Le résultat est mis en correspondance sur le modèle x:mpour vous assurer que la liste contient au moins un élément ( minimuméchoue sinon), puis la liste singleton de 1 plus le minimum du résultat est réaccordée. Sinétait inférieur à zéro ou l'appel récursif a renvoyé une liste vide, nous sommes dans une branche défaillante de la recherche et une liste vide est renvoyée. Si n==0la branche a réussi et [0]est retournée.


Haskell , 101 octets

f n=[d|d<-[9,8..1],show d!!0`elem`show n]#n!!0
s@(d:r)#n|n>=d,[x]<-s#(n-d)=[x+1]|1<3=r#n
s#n=[0|n==0]

Essayez-le en ligne! Une approche beaucoup plus efficace, vérifie tous les cas de test en moins d'une seconde.

Cette fois, la liste des chiffres de l'entrée est calculée pour être décroissante, ce qui permet (#)d'essayer d'utiliser le plus grand chiffre aussi souvent que possible, puis le deuxième plus grand, et ainsi jusqu'à ce qu'une solution soit trouvée. La première solution trouvée de cette manière est également garantie d'être la plus petite.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.