Números auto sumados

12

Convierte un número en una suma de dígitos

Sin ninguna suma: necesitamos la suma más corta
Sin dígitos: solo puede usar dígitos del número

Ejemplo
Se le dará como entrada un número enteron>0

Digamos Vamos n=27. Debe expresar 27como una suma , utilizando solo los dígitos [2,7] , de la manera más corta posible. ¡No tiene que usar todos los dígitos del número dado!

Por lo tanto 27=2+2+2+7+7+7. A continuación, tomamos esos dígitos y lo considero como : [2,2,2,7,7,7].
La respuesta final para n=27es6

Un ejemplo más para n=195obtener la suma más corta tenemos que usar los siguientes dígitos:
[5,5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]y la respuesta es23

El reto

Dado un número entero n>0, genera el número mínimo de dígitos (contenido en el número) que suman este número

Casos de prueba

Input->Output

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

Este es el ¡La respuesta más corta en bytes gana!


fuente
¿Hay números que no puedan sumarse a sí mismos / serán ingresados?
Stephen
1
@Stephen ¡Todos pueden!
77
@Stephen Debido a que cada número se puede expresar como d_0 + 10 * d_1 + 100 * d_2, etc ...
geokavel
¿Podemos tomar la entrada como string, char-array o integer-array?
Kevin Cruijssen
1
@KevinCruijssen String está bien. char-array o integer-array no lo son.

Respuestas:

4

Casco , 12 bytes

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

Maneja números de dos dígitos bastante rápido. Pruébalo en línea!

Explicación

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
Zgarb
fuente
2

Pyth , 12 bytes

lef!-TsM`Q./

Pruébalo en línea!

Desafortunadamente, errores de memoria en entradas tan grandes como 58.

Explicación

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
notjagan
fuente
¿te importaría agregar una explicación?
Jonás
@Jonah Explicación agregada.
notjagan
1
Gracias. Es interesante que Pyth tenga una primitiva que esencialmente resuelva el problema en./
Jonás
Alternativa de 12 bytes: lef<.{TjQ;./(filtro - subconjunto apropiado - de dígitos de entrada)
Sr. Xcoder
2

Mathematica, 78 bytes

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

encuentra el último caso de prueba en 5 segundos

J42161217
fuente
Un poco más corto:Length@IntegerPartitions[#, All, Sort@DeleteCases[0]@IntegerDigits@#, 1][[1]] &
Kuba
2

R , 78 bytes

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

Pruébalo en línea! (versión golfizada)

Algoritmo de fuerza bruta puro, por lo que en realidad no resuelve todos los casos de prueba, y creo que trató de asignar 40,000 GB para el último caso de prueba ...

Ten R por defecto 1obtenemos un error off-by-one que corregimos en el paso de retorno, pero también obtenemos Fqué valores predeterminados a 0cuáles vale la pena.

explicación no golfista:

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

Pruébalo en línea! (versión menos golfista)

Giuseppe
fuente
2

Python 2, 168 155 144 bytes

No es lo más corto que podría ser, pero es el mejor primero y no es realmente malo, en tiempo de ejecución.

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)) 

El filter(None...es eliminar 0 como un dígito, lo que aprendí que podía hacer al hacer esto.

El mayor problema son los marcos de pila de Python, que en realidad no me permiten ejecutar esto en las entradas más grandes. Por lo tanto, no es una solución válida, realmente, jugué con aumentar el límite de recursión que solo condujo a fallas seg. Esto debe hacerse con un bucle y una pila o con mucha más inteligencia para trabajar en Python.

editar: ¡Gracias a caird y Chas Brown por 13 bytes!

Backerupper
fuente
Puede usar inputy requerir que la entrada esté entre comillas.
caird coinheringaahing
2
Es perfectamente aceptable fallar debido a limitaciones físicas, siempre y cuando tenga éxito en teoría, lo que hace.
Jonathan Allan
Ahorre 9 bytes reemplazándolos filter(None,sorted(map(int,set(n)))[::-1])con sorted(set(map(int,n))-{0})[::-1](aunque Nonees bastante bueno saberlo).
Chas Brown el
@ChasBrown En la mayoría de los casos, puede usar filter(len,...)para listas y cadenas y filter(abs,...)para enteros y flotantes.
ovs
0

JavaScript (ES6), 82 bytes

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>

Toma la entrada como una cadena.

Neil
fuente
¿Puedes explicar por qué lo estás usando 1/0?
Zacharý
1
@ Zacharý Quiero la suma más corta, es decir, el número mínimo de dígitos. Los intentos que conducen a una solución no válida no deben contar, por lo que para excluirlos, obtienen un puntaje de Infinito, que no afecta el mínimo.
Neil
Oh, no me di cuenta de que es recursivo.
Zacharý
@ Zacharý The f=al principio es una gran pista, ya que no lo necesitas para lambdas no recursivas.
Neil
0

Ruby , 70 bytes

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

Muy lento, intente todas las combinaciones posibles aumentando el tamaño hasta llegar a una solución.

Gracias Dennis por Ruby 2.4 en TIO.

Pruébalo en línea!

GB
fuente
0

Jalea , 23 bytes

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

Pruébalo en línea!

Esto es tan ineficiente que no se ejecuta para los casos de prueba después del tercero en TIO debido a un límite de tiempo> _ <

¡Cualquier consejo de golf es bienvenido!

Zacharý
fuente
0

Python 2 , 183 176 172 166 161 bytes

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]

Pruébalo en línea!

Más tiempo que la otra respuesta de Python, pero realiza todos los casos de prueba combinados más 987654321en menos de un segundo en TIO.

Aprovecha el hecho de que si d1<d2hay dígitos, entonces debe haber como máximo d2-1 d1's en la suma (ya que las d2instancias de d1se pueden reemplazar por d1instancias de d2una suma más corta). Por lo tanto, al ordenar los dígitos en orden ascendente, hay "solo" en la mayoría de 9! = 362880las sumas posibles a considerar; y una profundidad máxima de recursión de 9(independientemente del valor de n).

Chas Brown
fuente
0

Haskell , 91 bytes

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]

Pruébalo en línea! Ejemplo de uso: f 58rendimientos 8. Rápido para números de dos dígitos, horrendamente lento para entradas más grandes.

La función fconvierte el número de entrada nen una lista de dígitos mientras filtra los ceros. Luego, esta lista y en nsí se entregan a la (#)función, que devuelve una lista singleton. !!0devuelve el elemento de esta lista singleton.

(#)utiliza listas simples y vacías como tipo de opción. Dada una entrada de n=58y s=[5,8], la idea es restar todos los dígitos sde n, luego aplicar recursivamente (#)y verificar qué dígito resultó en el número mínimo de pasos y devolver uno más este mínimo como resultado. La primera parte se calcula por (s#).(n-)=<<s, que es lo mismo que concat(map(s#)(map(n-)s)). Entonces, en nuestro ejemplo, primero [58-5,58-8]se calcula, seguido de lo [[5,8]#53,[5,8]#50]que resulta en [[7],[7]]o [7,7]después concat. El resultado coincide con el patrón x:mpara asegurarse de que la lista tenga al menos un elemento (de lo minimumcontrario, falla), luego se vuelve a ajustar la lista singleton de 1 más el mínimo del resultado. Sinera un cero menor o la llamada recursiva devolvió una lista vacía, estamos en una rama fallida de la búsqueda y se devuelve una lista vacía. Si n==0la rama tuvo éxito y [0]se devuelve.


Haskell , 101 bytes

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]

Pruébalo en línea! Un enfoque mucho más eficiente, verifica todos los casos de prueba en menos de un segundo.

Esta vez, la lista de dígitos de la entrada se calcula en orden descendente, lo que permite (#)intentar usar el dígito más grande con la mayor frecuencia posible, luego el segundo más grande, y hasta que se encuentre una solución. La primera solución encontrada de esta manera también es la más pequeña.

Laikoni
fuente