El reto
El número plástico es un número relacionado con la proporción áurea, con muchas propiedades matemáticas interesantes. Como tal, hay muchos enfoques que se pueden usar para calcular el número.
Para especificar con precisión el número para los propósitos de este desafío, usaremos la siguiente definición (aunque hay muchas definiciones equivalentes, y puede usar cualquier definición que desee siempre que se trate del mismo número):
El número plástico es un número real ρ tal que ρ ³ = ρ +1.
Su desafío es escribir un programa o función que tome un entero x como entrada (con x > 1), y produzca una aproximación a ρ como salida, de modo que cuanto mayor sea el valor de x , más se acerca la salida a ρ ( con a lo sumo muchas excepciones; permanecer en el mismo valor cuenta como "más cercano" para este propósito), y para cualquier número positivo δ , hay alguna entrada x en su programa que produce una salida que está dentro de δ de ρ .
Aclaraciones
- Si está emitiendo a través de un método que inherentemente genera cadenas (por ejemplo, la secuencia de salida estándar), puede formatear la salida en decimal (por ejemplo
1.3247179572
) o como una relación de dos enteros con un/
carácter entre ellos. - Si está generando un valor dentro de su lenguaje de programación (por ejemplo, regresando de una función), debe ser de tipo fijo, punto flotante o racional. (En particular, no puede usar tipos de datos que almacenen números simbólicamente, a menos que se usen solo para mantener la relación de dos enteros. Por lo tanto, si está usando Mathematica o un lenguaje similar, deberá incluir el extra código para generar realmente los dígitos de la salida).
- Su respuesta debe funcionar en una variante hipotética de su idioma en la que los enteros pueden ser arbitrariamente grandes, y la memoria (incluida la pila) es ilimitada. Es posible que no asuma que aritmética de punto flotante en su idioma es arbitraria precisa, sino que debe utilizar su exactitud real (lo que significa que la salida de un número de coma flotante sólo va a ser posible en los idiomas en que la exactitud de los números de coma flotante puede ser controlado en tiempo de ejecución).
- x puede tener el significado que desee (siempre que al aumentarlo se obtengan resultados más precisos). Me imagino que la mayoría de las presentaciones harán que controle el número de dígitos de salida para producir, o el número de iteraciones del algoritmo utilizado por su programa para converger en el número plástico, pero otros significados son aceptables.
Caso de prueba
Aquí están los primeros dígitos del número plástico:
1.32471795724474602596090885
Hay más dígitos disponibles en OEIS .
Condición de victoria
Como es habitual para el código de golf , más corto es mejor, medido en bytes. Sin embargo, siéntase libre de publicar respuestas incluso si no ganan, siempre que agreguen algo (por ejemplo, un idioma diferente o un algoritmo diferente) a las respuestas existentes.
Respuestas:
Python 2 , 49 bytes
Pruébalo en línea!
La idea es expresar el
ρ
conρ³=ρ+1
como una fracciónn/x
cuyo denominadorx
es el parámetro de precisión de entrada. Tomamos(n/x)³=n/x+1
y despejamos denominadores para obtenern³=x²(x+n)
.Como el LHS aumenta
n
más rápido que el RHS, podemos aproximar el punto de igualdadn
como el más pequeño conn³≥x²(x+n)
. El código cuentan
hasta que este sea el caso, comenzando en elx
cual es más pequeño.Un pequeño byte guardado es dividir ambos lados entre
x²
escribirn³/x²≥x+n
(negado en lawhile
condición). Esta es la división de piso en el código, pero la parte fraccional perdida es insignificante.Una alternativa de la misma longitud en su lugar pone
x
como numerador:Python 2 , 49 bytes
Pruébalo en línea!
fuente
2**input()
lugar de simplementeinput()
; entonces, cada aproximación será tan precisa como la anterior.Mathematica, 20 bytes
La
Root
función incorporada de Mathematica da las soluciones a una ecuación polinómicaf[x] == 0
.Explicación
Muestra de E / S
fuente
Root[x^3-x-1,1]~N~#&
funciona bien (a pesar de no decir quex
es una variable) para el mismo recuento de bytes.Mathematica, 27 bytes
-1 byte de Martin
-2 bytes de ovs
entrada
salida
fuente
Solve[x^3==x+1>2,x]~N~#&
para 24 bytes{{x -> 1.32...}}
sin embargo. Es posible que desee verificar con ais si ese es un formato de salida válido.{1.32...}
realidad, pero ese formato es probablemente menos polémico.sed ,
6760 (59 + 1) bytesPruébalo en línea!
+1 para la
-E
bandera (ERE en lugar de BRE). La entrada y la salida son ambas unarias: la entrada 11111 para x = 5, por ejemplo, la salida es una fracción de dos números unarios: la entrada 11111 mencionada anteriormente produce la salida 11111/1111 (5/4 en decimal).Aproxima el número plástico como una fracción entre elementos consecutivos de la secuencia de Padovan .
fuente
b
comando, pero puede acortarlo aún más utilizando la etiqueta vacía (:
yb
sin argumento). tio.run/#%23K05N@f@/…t
lugar deb
, así que es un buen guardado. Gracias :)Mathematica, 27 bytes
Utiliza una aproximación truncada de la forma radical cúbica anidada ³√ (1 + ³√ (1 + ³√ (1 + ...))) . Si bien la salida siempre tendrá decimales x-1 , el resultado es en realidad menos preciso que eso, porque la expresión converge más lentamente que un dígito por iteración ( x también se usa como el número de radicales anidados que se calculan). Por ejemplo x = 100 da
donde la parte sobrepuesta es correcta.
fuente
dc
, pero me bloqueé porque resulta que no tiene una operación de raíz cúbica, y elevar un número a la potencia ⅓ tampoco funciona :-( Al menos siempre puedes contar con Mathematica tendrá construcciones apropiadas ...CubeRoot
pero nadie tiene bytes para eso.Octava , 50 bytes
Pruébalo en línea!
Define una función anónima, con
n
el número deseado de dígitos de salida.Esta respuesta abusa de que
digits
devuelve la configuración actual para el número de dígitos en aritmética de precisión variable. Esto significa que podemos usarlo en una función anónima sin errores sobre 'Demasiados argumentos de salida'.Aparte de eso, es realmente sencillo:
vpasolve
es la abreviatura de resolución aritmética de precisión variable, con la precisión establecida por la última llamada dedigits
. Dado quevpa
es un tipo de datos simbólico en Octave, que está prohibido según la especificación, simplemente envolvemos toda la funciónchar(...)
para obtener una salida de cadena. Tenga en cuenta que ensolve
yvpasolve
, elf==0
está implícito, por lo quer^3==r+1
ha sido reemplazado porr^3-r-1 (==0)
fuente
MATL (
2728 bytes)Mi primera solución (27 bytes)
Pruébalo en línea!
Ciertamente no es óptimo, todavía me estoy acostumbrando a MATL.
Explicación:
Creo una secuencia de Padovan hasta la entrada + 3 y luego encuentro la relación de los dos últimos números.
Salida de fracción adecuada
(35 bytes)(28 bytes, @Sanchises):Sin embargo, la primera solución no satisface la necesidad de precisión arbitraria siendo el límite de coma flotante de la configuración MATL predeterminada. Entonces, en lugar de agregar varios bytes para extender esta precisión, es más simple tomar la ruta de fracción adecuada y escribir una fracción de los dos enteros finales en los elementos (N-1) th y N th de la secuencia de Padovan truncada.
por ejemplo, "114/86"
7BG: "t @) y @ 1 +) + h] tG3 +) V '/' YcyG2 +) VYcCortesía del usuario @Sanchises. :)
Pruébalo en línea!
Evaluación no iterativa:
Notablemente, mi código más corto para la versión 'exacta' es (23 bytes):
Pruébalo en línea!
... pero no da precisión arbitraria. Me pregunto si alguien puede ajustar esto para cumplir con las reglas (usar la entrada, etc.) y aun así agregar menos de 5 bytes. :PAGS
fuente
1+
puede acortarse aQ
.Con eso en mente, puede reemplazar@)y@1+)+
con solo@tQh)s
. Además, puede usarJ
para indicar el final de una matriz; y finalmente, MATL no distingue entre matrices normales y matrices de caracteres, por lo que puede reemplazarYc
porh
(no necesita la funcionalidad adicional deYc
). Esto proporciona solo 28 bytes:7BG:"t@tQh)sh]tJ)V47hyJq)Vh&
(observe el&
para evitar la salida superflua y el reemplazo'/'
por 47).7B
lllv
J
contiene de forma predeterminada1j
, sino que el portapapelesL
también contiene muchas funciones útiles de indexación (tenga en cuenta que1j
es igualend
en MATL).M ,
1514 bytesPruébalo en línea!
Algoritmo
Esto usa racionales y el método de Newton. Específicamente, para la entrada x , se aplican las primeras iteraciones x con el valor inicial x .
Estamos tratando de encontrar una raíz específica del polinomio p (t) = t³ - t - 1 . El método de Newton logra esto tomando un valor inicial t 0 - suficientemente cerca de ρ - y definiendo recursivamente una secuencia por
t n + 1 = t n - p (t n ) / p '(t n ) .
Como p '(t) = 3t² -1 , obtenemos
t n + 1 = t n - (t n ³ - t n - 1) / (3t n ² - 1) = (3t n ³ - t n - t n ³ + t n + 1) / (3t n ² - 1) = (2t n ³ + 1) / (3t n ² - 1) .
Tenga en cuenta que la aproximación inicial x empeora progresivamente a medida que x aumenta. Si bien la salida para x = 3 es ligeramente menos precisa que la salida para x = 2 , dado que el método de Newton converge cuadráticamente a ρ , esto no debería ser un problema para valores grandes de x .
Cómo funciona
fuente
µ¡
...Julia 0.5 ,
4440 bytesUtiliza racionales y el método de Newton.
Pruébalo en línea!
fuente
05AB1E , 23 bytes
Pruébalo en línea!
Puerto directo de /codegolf//a/126822/59376 por xnor.
fuente
Carbón , 28 bytes
Pruébalo en línea! Enlace al modo detallado. También aparentemente me equivoqué
Divide
yIntDivide
: |Utiliza el mismo método que las respuestas de Python y JavaScript.
fuente
NewStack , 14 bytes
Descompostura:
Cómo funciona:
La fórmula (2x 3 +1) / (3x 2 -1) proviene de la simplificación del método de Newton para la ecuación x 3 = x + 1. Lo puedes encontrar aquí . Repitiendo este proceso una infinidad de veces converge al número plástico. Su tasa de convergencia es bastante rápida, alrededor de 2.6 decimales por iteración.
Alternativa de secuencia de Padua,
272517 bytesDescompostura:
-2 bytes eligiendo una mejor estrategia de impresión
-8 bytes eligiendo la mejor manera de indexar la pila
Cómo funciona:
A medida que continúa la secuencia de Padovan , la relación de los dos últimos elementos converge al número plástico.
fuente
Clojure, 46 bytes
Utiliza la fórmula iterada de la raíz cúbica. Esto es un poco más interesante pero más largo:
fuente
Javascript, 36 bytes
Funciona igual que la respuesta superior de Python. No
console.log
se incluyó porque si ejecutaf(x)
en la consola, se registrará automáticamente.fuente
> <> , 38 + 3 = 41 bytes
Espera que la entrada esté presente en la pila al inicio del programa, por lo que +3 bytes para el
-v
indicador.Pruébalo en línea!
Efectivamente realiza una búsqueda binaria para reducir el valor de salida. Aumentar
x
aumenta el número de iteraciones a realizar.Editar: cálculo refactorizado ligeramente para guardar 1 byte, versión anterior:
fuente
k, 27 bytes
Pruébalo en línea! Esto supone enteros infinitos (que, por desgracia, no es cierto). Utiliza la secuencia de Padovan .
fuente
TI-BASIC, 21 bytes
Utiliza esta fórmula recursiva .
Curiosamente, codificar el número y redondearlo da el mismo número de bytes:
TI-BASIC, 21 bytes
Utiliza esta fórmula trigonométrica .
fuente
Your answer must work in a hypothetical variant of your language in which integers can be arbitrarily large, and memory (including stack) is unlimited. You may not assume that floating-point arithmetic in your language is arbitrarily accurate, but must instead use its actual accuracy (meaning that outputting a floating-point number is only going to be possible in languages where the accuracy of floating-point numbers can be controlled at runtime).
C # , 317 bytes
Devuelve el resultado como una fracción.
Explicación
Utiliza el método de Newton con iteraciones x para encontrar la raíz del polinomio p ^ 3-p-1 = 0. La fórmula es x_n = 1- (f (x_ (n-1))) / (f '(x_ (n-1))), y x_0 es un punto de partida.
La derivada de polinomios es 3p ^ 2-1, y digamos x_ (n-1) = b / c. Luego, usando la fórmula anterior, obtenemos que x_n = (2 b ^ 3 + c ^ 3) / (3 b ^ 2 cc ^ 3). Digamos también que comenzamos desde 1, esto sucederá cuando x = 2, porque x> 1, y es un número entero. Código ideado y comentado:
fuente
PHP, 86 bytes
PHP Sandbox en línea
Crea la espiral de Padovan e imprime la razón de los dos últimos números.
fuente
Axioma, 96 bytes
resultados
cómo puede ver h (2) debe ser 1.32 y no 1.33, por lo que hay algún error en los últimos dígitos
Entonces habría uno de 110 bytes
Utiliza la fórmula para resolver la ecuación de grado III de tipo x ^ 3-3 * p * x-2 * q = 0 en el caso q ^ 2-p ^ 3> = 0 que es m = sqrt (q ^ 2- p ^ 3) yx = (q + m) ^ (1/3) + (qm) ^ (1/3)
En nuestro caso, r ^ 3-r-1 = 0, esto puede escribirse como r ^ 3-3 * (1/3) r-2 * (1/2) = 0, entonces p = 1/3 q = 1/2 m = 1 / 4-1 / 27 = 23/108 x = (0.5 + m) ^ (1/3) + (0.5-m) ^ (1/3)
este que usa la iteración de Newton con el punto de inicio r = 1
cambia en la función, valor de dígitos para obtener un obj de n + 1 dígitos después del punto flotante. Al final, el valor de los dígitos () se asigna nuevamente al valor de referencia.
fuente
Ruby , 35 bytes
Pruébalo en línea!
fuente