Encuentra el número de unidades para obtener un número usando + y *


28

Introducción

Su objetivo es encontrar la menor cantidad de unidades que necesita sumar o multiplicar para obtener el valor de entrada, esto es A005245 .

Entrada

Un número entero positivo N .

Salida

El número más pequeño de los que hay que sumar / multiplica para obtener N .

Entrada de muestra

7 7

Salida de muestra

6 6

Explicación

( 1+ 1+ 1) * ( 1+ 1) + 1= 7

Debido a que esto requiere 6unos, la salida es6

Casos de prueba

 1  1
 2  2
 3  3
 5  5
10  7
20  9
50 12

Como se trata de un desafío de , gana el menor número de bytes.



99
¡Bienvenido a Programming Puzzles y Code Golf! Como primer desafío, está bien, pero la próxima vez, utilice Sandbox antes de publicar desafíos para que pueda recibir comentarios.
betseg

44
Sugeriría modificar esto para indicar explícitamente que está buscando la cantidad mínima requerida. De lo contrario, simplemente generar el número original y afirmar que es el número de los que necesita sumar sería una solución válida.
Shaggy

2
¿Hay ejemplos donde f(x) != x.primeFactorisation().sum()excepto 1?
jrtapsell

1
@jrtapsell: sí. El ejemplo dado de $ f (7) = 6 $ es uno. Para cualquier primo $ p $ (lo suficientemente grande) puede factorizar $ p-1 $ y agregar uno. Es posible que pueda hacerlo mejor todavía.
Ross Millikan

Respuestas:


17

Python 2 , 74 70 bytes

f=lambda n:min([n]+[f(j)+min(n%j*n+f(n/j),f(n-j))for j in range(2,n)])

Pruébalo en línea!

Versión alternativa, 59 bytes (sin verificar)

f=lambda n:min([n]+[f(j)+f(n/j)+f(n%j)for j in range(2,n)])

Esto funciona al menos hasta n = 1,000,000 , pero todavía tengo que demostrar que funciona para todos los n positivos .

Pruébalo en línea!


Lo siento si me falta algo simple, pero no es obvio que esto intente con todos los árboles de expresión viables. En particular, tenemos una capa externa n=a*j+bcon b<j, pero ¿podríamos necesitar b>=j?
xnor

Hm, solo fallaría si ambos b>=jy b>=a. Pero tienes razón, no es obvio que esto no suceda.
Dennis

Interesante que no haya contraejemplos de hasta 1,000,000, me pregunto si realmente siempre funciona. Mi mejor pensamiento para un contraejemplo sería algo de forma a*b+c*dcon a,b,c,dtodas las expresiones de suma y son muy eficientes.
xnor

10

Jalea , 16 14 bytes

¡Gracias Dennis por guardar 2 bytes!

ÆḌḊ,Ṗ߀€+U$FṂo

Pruébalo en línea!


Explicación lógica

Dado un número n :

  • Si es así 1, la respuesta es 1. De otra manera:

La representación es a + bo a × b, where ay bson expresiones.

Considere todos los valores posibles de ay b:

  • Si la representación es a + b, entonces ay bestán dentro del rango [1 .. n-1].
  • Si la representación es a × b, ay bson divisores propios de nmayor que 1.

En ambos casos, [[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]se calcula la lista ( ÆḌḊ,Ṗ), asigna el enlace actual sobre cada número ߀€, agrega los pares correctos ( +U$) y obtén el valor mínimo ( FṂo).

Explicación del código

ÆḌḊ,Ṗ߀€+U$FṂo   Main link. Assume n = 10.
ÆḌ       Proper divisors. [1,2,5]equeue, remove the first element. [2,5]
   ,Ṗ    Pair with op. Auto convert n = 10 to range 
         [1,2,3,4,5,6,7,8,9,10] and remove the last element
         10, get [1,2,3,4,5,6,7,8,9].

߀€      Apply this link over each element.
   +U$   Add with the Upend of itself.

FṂ       Flatten and get the inimum element.
  o      Logical or with n.
         If the list is empty, minimum returns 0 (falsy), so logical or
         convert it to n.

5

JavaScript (ES6), 108 96 bytes

f=n=>n<6?n:Math.min(...[...Array(n-2)].map((_,i)=>Math.min(f(++i)+f(n-i),n%++i/0||f(i)+f(n/i))))

Muy ineficiente; Array(n>>1)lo acelera ligeramente a un costo de un byte. Explicación: n%++ino es cero si ino es un factor, también lo n%++i/0es Infinity(y, por lo tanto, es verdad, y definitivamente no es mínimo) si ino es un factor, pero NaN(y por lo tanto es falso) si ies un factor. Editar: guardado 12 bytes con inspiración de @ edc65.


Intenté ejecutar esto en segundo plano para ver si era capaz de calcular, f(50)pero desafortunadamente Windows Update reinició mi PC antes de que pudiera terminar.
Neil

¿Intentaste un solo paseo en una matriz?
edc65

@ edc65 Lo siento, pero no tengo claro qué sugiere y por qué.
Neil

Veo 2 mapas, cada uno escaneando la amatriz. ¿No puedes fusionar las evaluaciones en las 2 lambdas y tomar el min?
edc65

@ edc65 Ah sí, por alguna razón pensé que anidar el min no sería más barato, pero puedo reemplazarlo (i+=2)por otro, ++iasí que estoy ahorrando 12 bytes en total, ¡gracias!
Neil


4

Pari / GP , 213 bytes

Editar: He sido severamente golpeado .

f(n)={d;n<6&return(n);if(n<=#a,a[n]&return(a[n]),a=vector(n));for(i=1,n-1,a[i]||a[i]=f(i));a[n]=min(vecmin(vector(n\2,k,a[k]+a[n-k])),if(isprime(n),n,vecmin(vector((-1+#d=divisors(n))\2,i,a[d[i+1]]+a[d[#d-i]]))))}

Pruébalo en línea!




1

Perl 5 , -p 78 bytes

79 bytes en conteo de estilo antiguo ( +1para -p)

El hecho de que Perl deba usar un extra $para todo acceso escalar realmente perjudica la longitud de los campos de golf que hacen mucha aritmética ...

Este método es principalmente como los otros ya publicados (intente la multiplicación y la suma para construir un número objetivo, tome el más barato). Sin embargo, no se repite repetidamente, por lo que puede usarse para entradas relativamente grandes.

Tampoco trata de minimizar el costo de construir un número mediante la suma o la multiplicación porque perl 5 no tiene incorporado miny la ordenación numérica es muuuuuuy larga (como se ve en la ordenación aún en el código). En cambio, supongo que si un número es un factor del objetivo, usaré la multiplicación. Eso es seguro ya que si, por ejemplo, 3es un factor de 12(por lo tanto, suma el costo de 3y 12/3) más adelante en el ciclo, considerará 9=12-3cuál no será un factor, por lo que 9+3con el mismo costo que se 3+9probará de todos modos. Sin embargo, eso puede fallar para los objetivos <= 4(solo lo hace para 1y 2). Agregar $_a la lista para minimizar las correcciones que. Lo cual es lamentable ya que en realidad no lo necesito para los casos base porque ya lo inicializo@; con los valores iniciales adecuados, por lo que cuesta 3 bytes.

#!/usr/bin/perl -p
($_)=sort{$a-$b}$_,map{$;[$_]+$;[$'%$_?$'-$_:$'/$_]}//..$_ for@;=0..$_;$_=pop@

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.