Introducción
En este desafío, trataremos con un cierto gráfico infinito no dirigido, que yo llamo el gráfico de alto divisor . Sus nodos son los enteros a partir de 2. Hay un borde entre dos nodos a <b si a divide b y a 2 ≥ b . El subgrafo formado por el rango de 2 a 18 se ve así:
16-8 12 18
\|/ |/|
4 6 9 10 15 14
| |/ |/ |
2 3 5 7 11 13 17
Se puede demostrar que el gráfico infinito de divisores altos está conectado, por lo que podemos preguntar sobre la ruta más corta entre dos nodos.
Entrada y salida
Sus entradas son dos enteros a y b . Puede suponer que 2 ≤ a ≤ b <1000 . Su salida es la longitud del camino más corto entre una y b en el gráfico de alta divisor infinito. Esto significa el número de bordes en la ruta.
Puede encontrar útil el siguiente hecho: siempre existe una ruta óptima desde a hasta b que primero aumenta y luego disminuye, y solo visita nodos que son estrictamente menores que 2b 2 . En particular, dado que b <1000 solo necesita considerar nodos inferiores a 2 000 000.
Ejemplos
Considere las entradas 3
y 32
. Una posible ruta entre los nodos 3 y 32 es
3 -- 6 -- 12 -- 96 -- 32
Esta ruta tiene cuatro bordes, y resulta que no hay rutas más cortas, por lo que la salida correcta es 4
.
Como otro ejemplo, una ruta óptima para 2
y 25
es
2 -- 4 -- 8 -- 40 -- 200 -- 25
entonces la salida correcta es 5
. En este caso, ninguna ruta óptima contiene el nodo 50 = lcm(2, 25)
.
Reglas y puntaje
Puede escribir un programa completo o una función. El conteo de bytes más bajo gana, y las lagunas estándar no se permiten. No hay límites de tiempo o memoria, por lo que se permite el forzamiento bruto.
Casos de prueba
2 2 -> 0
2 3 -> 4
2 4 -> 1
2 5 -> 5
3 5 -> 4
6 8 -> 2
8 16 -> 1
12 16 -> 2
16 16 -> 0
2 25 -> 5
3 32 -> 4
2 256 -> 3
60 77 -> 3
56 155 -> 3
339 540 -> 2
6 966 -> 4
7 966 -> 2
11 966 -> 4
2 997 -> 7
991 997 -> 4
FindShortestPath
la restricción sobre las lagunas estándar? Si es así, házmelo saber y eliminaré mi envío.Respuestas:
Matlab,
218190175 bytes¡Gracias @beaker por el acceso directo en el paso de alargamiento de la lista!
Esta es una implementación dijkstra relativamente sencilla:
sin convolución hoy
fuente
l=zeros(1,a*b);
que pueda usarl(a*b)=0;
, que hace lo mismoJavaScript (ES6), 186 bytes
Utiliza una función auxiliar
g
para calcular todas las rutas ascendentes desdem
yn
hasta el límite proporcionado, luego suma las rutas juntas y devuelve el valor más bajo.fuente
Mathematica 98 bytes
Supongo que la función incorporada
FindShortestPath
no viola la restricción sobre las lagunas estándar. Si es así, házmelo saber y eliminaré este envío.Fuerza bruta, por lo tanto lenta con grandes valores de
b
. Todavía estoy pensando en formas de acelerarlo.Esto configura un gráfico con bordes apropiados entre los nodos de
a
ab^2
.FindShortestPath
encuentra la ruta más corta en el gráfico.Length
cuenta los nodos;Length -1
es el número de aristasThread[# <-> Range[2, #] #] &
produce los bordes del gráfico completo. Por ejemplo,Thread[# <-> Range[2, #] #]&[5]
produciría los bordes{5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}
, es decir,{5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}
.fuente
Matlab
(195) (185) (181) (179)(173)Ejemplo de llamada de función:
Todos los casos de prueba están satisfechos
Explicación:
Antes de comenzar con explicaciones, demostremos algunos lemas "no verdes":
Lema (1):
(a,b)
existe una ruta óptima entre dos números cualquiera de manera que los nodos aumenten primero y luego disminuyan.Por qué ? Esto se demuestra simplemente porque la cantidad entera máxima que divide cualquier número
a
es, respectivamente, grande como el número ena
sí mismo, por lo que, como un enfoque inteligente, debemos elegir multiplicara
lo más posible para hacerlo lo suficientemente grande, y luego dividirlo por valores más grandes. Si alguna vez hacemos la vuelta, el número sea
reduce, por lo que necesitamos innecesariamente más iteraciones para multiplicarlo gradualmente de lo que se nos prescinde.Lema (2): de un número
a
ab
, sigcd(a,b)=1
a
se multiplica porb
, sib
es más grande dea
lo que se multiplicará por un número conocidoc
, si segcd>1
a
debe multiplicar gradualmente por el mayor divisor deb/gcd
nombred
que verifica la condicióna >= d
también cuando todod
es mínimo son mayores quea
,a
recibe dea*c
nuevo.Esta suposición es simple para demostrar que cualquier nodo de inicio
a
debe multiplicarse hasta que alcance el múltiplo más pequeño dea
y,b
por lo tanto, multiplicamos por proporciones deb*gcd
inicio por el máximo que verifica la condición principal, que garantiza siempre el camino más corto a smp antes de que comience el proceso de división, o cuandod
no está disponible,c
se multiplica un número pora
para hacer una condición válidaa>=d
para esta primera etapa.Lema (3): de un múltiplo gráfico-ultimum de
a
ab
, el mcd de este número yb
es enb
sí mismoBueno, esto es solo una consecuencia de las manipulaciones anteriores, y los últimos pasos restantes también se realizan dividiendo gradualmente entre el divisor más grande que no excede su raíz cuadrada.
Dilema: ¿Cuál es el número óptimo
c
que se multiplicará iterativamente pora
eso que conduciría directamente a la condición de apertura para la etapa 1 y luego el ultimum?Buena pregunta, para cualquier situación simple hay una parada simple, por lo que suponiendo un ejemplo de dos fines
(a,b)=(4,26)
factorizados así:Aparte del
gcd=2
número entero más pequeño por el que debe multiplicarse2
para alcanzar13
es7
, pero obviamente se descarta, porque es mayor que 2, por lo que a es cuadrado.Appearenlty en el segundo ejemplo
(a,b)=(10,26)
anteriorc
se mide como el número entero más bajo de1
a5
que excede13/5
por lo tanto satisface la condición del gráfico de desincrustación, que es3
, por lo que el siguiente paso aquí está multiplicando por3
Por qué ? Esto se debe a que, una vez que tenemos que multiplicar por
2*13/gcd=13
para que coincida con el segundo lado de la tabla, la cantidad de basura que agregamos antes es óptimamente menor, y el movimiento a lo largo del gráfico se minimiza, si alguna vez multiplicamos por un valor mayor, como10
la posibilidad de dividir por el menor tiempo se reduce, y se habría incrementado en 1 otro paso divisorio para alcanzar nuestra meta2*13
. que se enumeran a:13*2*5*10/2*5
entonces13*2*5/5
. Mientras que, obviamente, aquí el número que se dividirá es5*3<13*2
y una cosa más ........ HAIL MATHS ...
Estos son mis resultados comparativos con los de @flawr. Solo preste atención a que hice un límite superior para el algoritmo de flawr de conserjería de ejecución de tiempo, ¡lleva demasiado tiempo!
Puede insertar los rangos de exploración inicial y final como variables ayb en el encabezado del código compilable en línea.
fuente