Función para descomponer número en 3 factores

Hola expertos, esta es la problemática.
Tengo un número en la celda A1 y quiero poner en la celda B1, C1, D1 tres números que al mltiplicarlos me de la celda A1. Todos los números son enteros
Esto debe interpretarse como que lo que está en A1 es un valor de volumen y las restantes celdas son largo ancho y alto.
La particularidad es que necesito que los 3 números sean lo más cercanos posibles, o sea, que las dimensiones traten de asemejar un cubo.
Este es un ejemplo: el número 84 puede descomponerse de varias formas 1x1x84, 1x2x42 etc. De todas las descomposiciones la que necesito es 3x4x7 porque es la más cercana a un cubo.
Como dato matemático les digo que la raíz cúbica de 84 es 4 y fracción y si me ha ocurrido que con una función que me devuelva el divisor más cercano menor que un número dado podría resolver el problema.
Por ejemplo algo como esto mifunción(84, potencia(84,1/3) que me devuelva el valor 4 que para el ejemplo es el mayor divisor menor que la raíz cúbica.
Alguien conoce alguna manera de hacer lo que quiero, ¿o al menos de poder obtener esta función que busco?
Gracias de antemano

1 Respuesta

Respuesta
1
La función para encontrar el divisor mayor del número y que, además, sea menor que su raíz cúbica no parece demasiado complicada en VBA:
Public Function prueba(ByVal lNúm As Long) As Long
    Dim n As Long
    Dim lRaíz3 As Long
    Dim lMejor As Long
    lRaíz3 = Fix(lNúm ^ (1 / 3))
    For n = 2 To lNúm / 2
        If lNúm Mod n = 0 Then
            If n <= lRaíz3 Then
                prueba = n
            Else
                Exit Function
            End If
        End If
    Next n
End Function
La sintaxis desde la hoja de cálculo sería:
=prueba(Celda o Número a procesar)
A mí me gusta prescindir de VBA siempre que es posible y usar las funciones de Excel, y en este caso lo es, aunque la fórmula es matricial (hay que introducirla pulsando mayúsculas control entrada al mismo tiempo), y bastante larga y complicada:
=max((multiplo.inferior($a$1;fila(indirecto("1:"&entero($a$1/2))))=$a$1)*fila(indirecto("1:"&entero($a$1/2)))*((multiplo.inferior($a$1;fila(indirecto("1:"&entero($a$1/2))))=$a$1)*fila(indirecto("1:"&entero($a$1/2)))>0)*((multiplo.inferior($a$1;fila(indirecto("1:"&entero($a$1/2))))=$a$1)*fila(indirecto("1:"&entero($a$1/2)))<=$a$1^(1/3)))
(Suponiendo que el número estuviera en A1)
Encontrar los 3 divisores más cercanos supongo que se podría hacer echándole tiempo y ganas, pero habría que generar todas las combinaciones posibles de 3 elementos en el conjunto de los divisores y luego encontrar la forma de "decirle" a VBA que lo que se desea son los 3 más cercanos... muy complicado.
Hola experto. Muchas gracias por tu respuesta.
Pienso como tu con relación a utilizar código VBA. Es por eso que he probado la función que me expones en excel y no me funciona. Coloco el 84 en la celda A1, y pongo el código en B1 y me devuelve 0 cuando debería devolver 4, no se que pueda suceder.
Por otro lado tengo que agradecerte infinitamente pues me has dado una solución que me funcionará. Debo construir mis propias funciones pero al final tu idea me ha señalado un camino.
Para terminar, reiterarte que me gustaría ver funcionar la variante de las funciones propias de excel.
Pienso que el problema puede ser que no estás introduciendo la fórmula como matricial (pulsando mayúsculas control entrada al mismo tiempo).
He subido un ejemplo con la fórmula funcionando a http://www.jrgc.es/ejemplos/ejemplo_20091006a.xls
Una cosa sobre la función VBA que puse en mi primera respuesta: la instrucción
    Dim lMejor As Long
No hace falta y se puede quitar, es una variable que creé para hacer pruebas pero no es necesaria.
Hola experto. Antes de puntur tu pregunta me gustaría si no te es molestia me explicaras la idea para construir ese anidamiento de funciones en excel para obtener el primer factor.
Por otra parte ya resolví el problema utilizando VBA, pero tengo mucho interés en entender la otra solución. Para contribuir un poco aquí te mando la función que construí.
Public Function Desc_3Fact(ByVal lNum As Long, ByVal num_factor As Byte) As Long
    Dim n As Long
    Dim x As Long, y As Long, z As Long
    n = Fix(lNum ^ (1 / 3))
    Do While (n > 1) And (lNum Mod n <> 0)
      n = n - 1
    Loop
    x = n
    lNum = lNum / x
    n = Fix(lNum ^ (1 / 2))
    Do While (n > 1) And (lNum Mod n <> 0)
      n = n - 1
    Loop
    y = n
    z = lNum / y
    Select Case num_factor
        Case 1
          Desc_3Fact = x
        Case 2
          Desc_3Fact = y
        Case 3
          Desc_3Fact = z
        Case Else
          Desc_3Fact = 0
    End Select
End Function
Esta te devuelve el factor 1,2, o 3 como lo indiques en su llamado. Gracias por todo y espero tu respuesta.
Pues me temo que me resulta mucho más difícil explicar una fórmula matricial que escribirla.
Lo único que puedo decir sin entrar en detalles para los que no dispongo de tiempo es que la fórmula genera 2 matrices, la primera con los divisores de A1 y la segunda con VERDADERO para los divisores que son <= raíz cúbica de A1 y FALSO para los que son mayores, multiplica ambas matrices (con lo que los divisores > raíz cubica de A1 se convierten en ceros) y devuelve el valor mayor, que lógicamente será el primer divisor que esté por debajo de la raíz cúbica.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas