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 3y 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 2y 25es
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

FindShortestPathla 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
gpara calcular todas las rutas ascendentes desdemynhasta 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
FindShortestPathno 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
aab^2.FindShortestPathencuentra la ruta más corta en el gráfico.Lengthcuenta los nodos;Length -1es 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
aes, respectivamente, grande como el número enasí mismo, por lo que, como un enfoque inteligente, debemos elegir multiplicaralo 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 seareduce, por lo que necesitamos innecesariamente más iteraciones para multiplicarlo gradualmente de lo que se nos prescinde.Lema (2): de un número
aab, sigcd(a,b)=1ase multiplica porb, sibes más grande dealo que se multiplicará por un número conocidoc, si segcd>1adebe multiplicar gradualmente por el mayor divisor deb/gcdnombredque verifica la condicióna >= dtambién cuando tododes mínimo son mayores quea,arecibe dea*cnuevo.Esta suposición es simple para demostrar que cualquier nodo de inicio
adebe multiplicarse hasta que alcance el múltiplo más pequeño deay,bpor lo tanto, multiplicamos por proporciones deb*gcdinicio 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 cuandodno está disponible,cse multiplica un número porapara hacer una condición válidaa>=dpara esta primera etapa.Lema (3): de un múltiplo gráfico-ultimum de
aab, el mcd de este número ybes enbsí 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
cque se multiplicará iterativamente poraeso 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=2número entero más pequeño por el que debe multiplicarse2para alcanzar13es7, pero obviamente se descarta, porque es mayor que 2, por lo que a es cuadrado.Appearenlty en el segundo ejemplo
(a,b)=(10,26)anteriorcse mide como el número entero más bajo de1a5que excede13/5por lo tanto satisface la condición del gráfico de desincrustación, que es3, por lo que el siguiente paso aquí está multiplicando por3Por qué ? Esto se debe a que, una vez que tenemos que multiplicar por
2*13/gcd=13para 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, como10la 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*5entonces13*2*5/5. Mientras que, obviamente, aquí el número que se dividirá es5*3<13*2y 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