Introdução
Neste desafio, trataremos de um certo gráfico infinito e não direcionado, que chamo de gráfico de alto divisor . Seus nós são os números inteiros a partir de 2. Existe uma aresta entre dois nós a <b se a divide b e a 2 ≥ b . O subgráfico formado pelo intervalo de 2 a 18 tem a seguinte aparência:
16-8 12 18
\|/ |/|
4 6 9 10 15 14
| |/ |/ |
2 3 5 7 11 13 17
Pode-se mostrar que o gráfico do divisor alto infinito está conectado, para que possamos perguntar sobre o caminho mais curto entre dois nós.
Entrada e saída
Suas entradas são dois inteiros a e b . Você pode assumir que 2 ≤ a ≤ b <1000 . A sua saída é o comprimento do caminho mais curto entre um e b no gráfico alta divisor infinito. Isso significa o número de arestas no caminho.
Você pode achar útil o seguinte fato: sempre existe um caminho ideal de a para b que primeiro aumenta e depois diminui, e apenas visita nós que são estritamente menores que 2b 2 . Em particular, como b <1000, você precisa considerar apenas os nós inferiores a 2 000 000.
Exemplos
Considere as entradas 3
e 32
. Um caminho possível entre os nós 3 e 32 é
3 -- 6 -- 12 -- 96 -- 32
Esse caminho tem quatro arestas e, como não há caminhos mais curtos, a saída correta é 4
.
Como outro exemplo, um caminho ideal para 2
e 25
é
2 -- 4 -- 8 -- 40 -- 200 -- 25
então a saída correta é 5
. Nesse caso, nenhum caminho ideal contém o nó 50 = lcm(2, 25)
.
Regras e pontuação
Você pode escrever um programa completo ou uma função. A contagem de bytes mais baixa vence e as brechas padrão não são permitidas. Não há tempo ou limites de memória, portanto, a força bruta é permitida.
Casos de teste
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
viola a restrição sobre brechas comuns? Se isso acontecer, avise-me e excluirei meu envio.Respostas:
Matlab,
218190175 bytesObrigado @beaker pelo atalho na etapa de alongamento da lista!
Esta é uma implementação dijkstra relativamente direta:
nenhuma convolução hoje
fonte
l=zeros(1,a*b);
você pode usarl(a*b)=0;
, que faz o mesmoJavaScript (ES6), 186 bytes
Usa uma função auxiliar
g
para calcular todos os caminhos ascendentes a partir dem
en
até o limite fornecido, soma os caminhos juntos e retorna o valor mais baixo.fonte
Mathematica 98 bytes
Suponho que a função
FindShortestPath
interna não viole a restrição sobre brechas padrão. Se isso acontecer, avise-me e eu excluirei este envio.Força bruta, portanto lenta com grandes valores de
b
. Ainda estou pensando em maneiras de acelerar isso.Isso configura um gráfico com arestas apropriadas entre os nós de
a
ab^2
.FindShortestPath
localiza o caminho mais curto no gráfico.Length
conta os nós;Length -1
é o número de arestas.Thread[# <-> Range[2, #] #] &
produz as arestas do gráfico completo. Por exemplo,Thread[# <-> Range[2, #] #]&[5]
produziria as arestas{5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}
, ou seja{5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}
,.fonte
Matlab
(195) (185) (181) (179)(173)Exemplo de chamada de função:
Todos os casos de teste são satisfeitos
Explicação:
Antes de começar com explicações, vamos provar alguns lemas "não verdes":
Lema (1): Existe um caminho ideal entre dois números, de
(a,b)
maneira que os nós aumentam primeiro e depois diminuem.Por quê ? Isso é simplesmente provado porque a quantidade máxima máxima que divide qualquer número
a
é, respectivamente, grande como oa
próprio número ; portanto, como uma abordagem inteligente, devemos escolher multiplicara
o máximo possível para torná-lo suficientemente maior, depois dividindo-o por valores maiores. Se alguma vez fizermos o caminho inverso, o númeroa
diminuirá; portanto, precisamos desnecessariamente de mais iterações para multiplicá-lo gradualmente de que somos dispensados.Lema (2): de um número
a
parab
, segcd(a,b)=1
a
multiplicado porb
, seb
for maior doa
que será multiplicado por um número conhecidoc
, segcd>1
a
deve ser multiplicado gradualmente pelo maior divisor deb/gcd
nomeadod
que verifica a condiçãoa >= d
também quando todosd
são mínimo são maiores quea
,a
recebea*c
novamente.Essa suposição é simples para provar que qualquer nó inicial
a
deve ser multiplicado até atingir o menor múltiplo dea
e,b
portanto, multiplicamos por proporções deb*gcd
início pelo máximo que verifica a condição principal, que garante sempre o caminho mais curto para o smp antes do início do processo de divisão, ou quandod
não está disponível, um númeroc
é multiplicado pora
para criar uma condição válidaa>=d
para este primeiro estágio.Lema (3): De um múltiplo gráfico-ultimo de
a
atéb
, o MDC desse número eb
éb
ele próprioBem, isso é apenas uma consequência das manipulações anteriores, e os últimos passos restantes também são feitos gradualmente dividindo-se pelo maior divisor que não excede sua raiz quadrada.
Dilema: Qual é o número ideal
c
a ser multiplicado iterativamentea
que levaria diretamente à condição de abertura do estágio 1 e depois ao ultimo?Boa pergunta, para qualquer situação simples, há uma simples aparação, portanto, assumindo um exemplo de dois fins
(a,b)=(4,26)
fatorados como este:Além do
gcd=2
menor número inteiro que deve ser multiplicado2
para alcançar ,13
é7
, mas é obviamente descartado, porque é maior que 2, então a é ao quadrado.A aparência no segundo exemplo
(a,b)=(10,26)
acimac
é medida como o número inteiro mais baixo a partir1
do5
qual excede,13/5
portanto, satisfaz a condição de escala de gráfico, ou seja3
, portanto, a próxima etapa aqui é multiplicada por3
Por quê ? isso ocorre porque, uma vez que precisamos multiplicar
2*13/gcd=13
para corresponder ao segundo lado da tabela, a quantidade de lixo eletrônico que adicionamos antes é otimamente menor, e a movimentação ao longo do gráfico é minimizada, se é que multiplicamos por um valor maior, como10
a chance de dividir por o menor número de vezes reduzido e teria sido aumentado em mais 1 passo divisor para alcançar nossa meta2*13
. que são enumerados para:13*2*5*10/2*5
then13*2*5/5
. Embora, obviamente, aqui o número a ser dividido seja5*3<13*2
e mais uma coisa ........ MAIL MAHS ...
Estes são meus resultados comparativos com os do @flawr, apenas preste atenção que eu fiz um limite superior para a execução do tempo de acordo com o algoritmo do flawr, isso leva muito tempo!
Você pode inserir os intervalos de verificação inicial e final como variáveis aeb no cabeçalho do código compilável online.
fonte