Tengo $ 15 en mi bolsillo. Del mismo modo, estoy en una tienda que no da cambio. Mientras navego, veo un artículo que cuesta $ 10 (impuestos incluidos). ¿Puedo comprar ese artículo sin perder dinero?
En este caso, la respuesta es sí. No importa cómo se dividan mis $ 15 (uno 10 y uno 5, o tres 5, u otra cosa), siempre tendré los $ 10 exactos necesarios.
Como segundo ejemplo, tengo $ 0.16 en mi bolsillo. ¿Qué otras cantidades de dinero debo poder pagar exactamente?
Possible Divisions:
0.01, 0.05, 0.10
0.01, 0.05 x 3
0.01 x 16
Guaranteed Exact Change:
0.01, 0.05, 0.06, 0.10, 0.11, 0.15, 0.16
¿Qué pasa si tengo $ 0.27 en mi bolsillo?
Possible Divisions:
0.01 x 2, 0.25
0.01 x 2, 0.05, 0.10 x 2
0.01 x 2, 0.05 x 3, 0.10
0.01 x 2, 0.05 x 5
0.01 x 27
Guaranteed Exact Change:
0.01, 0.02, 0.25, 0.26, 0.27
En el caso anterior, solo había unas pocas cantidades de dinero para las cuales siempre tendría un cambio perfecto.
Tu tarea
Escriba el programa más corto (o función con nombre) que toma A) una cantidad entera de dinero y B) una lista de posibles denominaciones como entrada, y genera una lista de las cantidades de dinero para las cuales debo tener un cambio perfecto. La entrada puede ser STDIN o argumentos para el programa o la función. No voy a ser muy estricto con el formato de entrada; puede coincidir con la forma en que su idioma formatea las matrices.
Quizás una explicación más detallada
Tengo una cierta cantidad de dinero en mi bolsillo, que se forma a partir de un conjunto de posibles demostraciones de moneda. Si tengo $ 8, y sé que las posibles denominaciones son $ 2 y $ 3, entonces solo hay muchas combinaciones diferentes de billetes que podrían estar en mi bolsillo. Estos son 2+2+2+2
y 3+3+2
. Para poder producir una cantidad exacta de dinero, tengo que poder producir esa cantidad usando solo los billetes que tengo en el bolsillo. Si tuviera cuatro 2s, podría producir 2, 4, 6, or 8
. Si tuviera dos 3 y un 2, podría producir 2, 3, 5, 6, or 8
Ya que no sé cuál de estas combinaciones tengo en mi bolsillo, mi respuesta final se reduce a 2, 6, 8
. Estos son los valores que sé que podría producir de mi bolsillo, dada la cantidad total y las posibles denominaciones.
Ejemplo de E / S calculado a mano
7 [3, 4]
3, 4, 7 //only one possible division into 3 + 4
7 [3, 2]
2, 3, 4, 5, 7 //the only division is 3 + 2 + 2
6 [2, 3, 4]
6 //divisions are 2+2+2, 3+3, 2+4
16 [1, 5, 10, 25] //this represents one of the examples above
1, 5, 6, 10, 11, 15, 16
27 [1, 5, 10, 25] //another example from above
1, 2, 25, 26, 27
1500 [1, 5, 10, 25, 100, 500, 1000, 2000]
500, 1000, 1500
600 [100, 500, 1000, 2000]
100, 500, 600
600 [200, 1, 5, 10, 25, 100, 500, 1000, 2000]
600
6 [2, 3, 4]
. ¿No2+2+2
puede hacer 3, y3+3
no hacer 2 y 4?Respuestas:
Python 2,
200197193140 bytes(Gracias a @Nabb por los consejos)
Aquí hay una solución mal desarrollada por ahora para comenzar las cosas. Llamar con
g(16, [1, 5, 10, 25])
: la salida es un conjunto con las denominaciones relevantes.El enfoque es sencillo y se divide en dos pasos:
f
analiza todas las formas de llegarn
con denominacionesD
(por ejemplo[1, 5, 10]
), y para cada una calcula todas las cantidades que se pueden hacer con estas denominaciones (por ejemploset([0, 1, 5, 6, 10, 11, 15, 16])
).g
calcula las intersecciones de los resultados def
, luego elimina 0 para la respuesta final.El programa resuelve bien los casos 1-5 y 7, el desbordamiento de la pila en 6 y dura 8 para siempre
Si no hay solución (p
g(7, [2, 4, 6])
. Ej. ), El programa devuelve un conjunto vacío. Si se permite lanzar un error para tal caso, entonces aquí hay un resumeng
:fuente
g=lambda L,c=0:L and g(L[1:],c)|g(L,c+L.pop(0))or{c}
es un poco más corto-{0}
a g y usar en[L]*-~n
lugar de[L][-n:]
JavaScript (ES6) 162
203 207Editar Cambió la forma de intersectar conjuntos de resultados en la matriz r. Un poco más rápido, pero el algoritmo todavía apesta.
Una explicación más detallada seguirá.En resumen: c es una función recursiva que enumera todas las subdivisiones posibles. k es una función recursiva que enumera todas las sumas posibles sin repeticiones. Cualquier nuevo conjunto de resultados encontrado con la función k se compara con el conjunto anterior encontrado, solo se mantienen los resultados comunes.
¿Por qué es tan lento? Tener que administrar un objetivo total de, digamos, 1500 y una sola pieza de valor 1, enumerar todas las sumas posibles no es una buena idea.
Sin golf
Prueba en la consola Firefox / FireBug
(tiempo 84 ms)
(tiempo 147252 ms, así que no tan rápido)
fuente
Wolfram Methematica, 104 bytes
Ungolfed (leído desde el final):
fuente