제수 그래프의 최단 경로


15

소개

이 도전에서, 우리는 무한한 무 방향 그래프를 다룰 것인데, 이것을 높은 제수 그래프 라고 부릅니다 . 그 노드는 두 개의 노드 사이에 에지가 2부터 시작되는 정수 은 <B 의 경우 분할 된 B2 ≥ B는 . 2에서 18까지의 범위로 형성된 하위 그래프는 다음과 같습니다.

16-8 12 18
  \|/ |/|
   4  6 9 10 15 14
   |  |/   |/   |
   2  3    5    7  11 13 17

무한 높은 제수 그래프가 연결되어 있음을 알 수 있으므로 두 노드 사이의 최단 경로를 물어볼 수 있습니다.

입력과 출력

입력 값은 두 개의 정수 ab 입니다. 2 ≤ a ≤ b <1000 이라고 가정 할 수 있습니다 . 출력은 무한 높은 제수 그래프에서 ab 사이의 최단 경로 길이입니다 . 이것은 경로의 가장자리 수를 의미합니다.

다음 사실이 유용하다는 것을 알 수 있습니다. 항상 a 에서 b 까지의 최적 경로가 항상 증가하고 감소하며 2b 2 미만인 노드 만 방문 합니다. 특히, b <1000 이므로 2 000 000 미만의 노드 만 고려하면됩니다.

입력 3과를 고려하십시오 32. 노드 3과 32 사이의 가능한 경로는

3 -- 6 -- 12 -- 96 -- 32

이 경로에는 네 개의 모서리가 있으며 짧은 경로가 없으므로 올바른 출력은 4입니다.

다른 예로서, 2and에 대한 최적의 경로 25

2 -- 4 -- 8 -- 40 -- 200 -- 25

올바른 출력은 5입니다. 이 경우 최적 경로에 노드가 포함되지 않습니다 50 = lcm(2, 25).

규칙과 득점

전체 프로그램 또는 함수를 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다. 시간이나 메모리 제한이 없으므로 무차별 강제 실행이 허용됩니다.

테스트 사례

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

내가 생각한 것처럼 무차별 한 힘이 아닌 아이디어가 있습니다. 두 숫자 중 가장 작은 배수를 세고, 나타날 때까지 2를 거듭 제곱 한 다음 두 번째 숫자가 나타날 때까지 sqrt로 점차 나눕니다. 시간이 없습니다. iy 지금 eventhough를 구현하는 : /
Abr001am

Zgarb, Mathematica FindShortestPath 는 표준 허점에 대한 제약 조건을 위반 합니까 ? 그렇다면 알려 주시면 제출물을 삭제하겠습니다.
DavidC

@DavidC 나는 허점으로 생각하지 않습니다. 관련 대답은 실제로 0의 점수가
Zgarb

답변:


4

MATLAB, 218 (190) 175 바이트

function f(a,b);q=a;l(b)=0;l(a)=1;while~l(b);x=q(1);q=q(2:end);l(end+1:x^2)=0;g=x+1:x^2;s=2:x-1;u=[g(~mod(g,x)),s(~mod(x,s)&s.^2>=x)];u=u(~l(u));q=[q,u];l(u)=l(x)+1;end;l(b)-1

목록 확장 단계의 바로 가기에 대해 @beaker에게 감사드립니다!

이것은 비교적 간단한 dijkstra 구현입니다.

q=a;                  %queue
l(b)=0;       %list of path lengths
l(a)=1;
while~l(b);         %if there is no predecessor to b
    x=q(1);         %get first queue element
    q=q(2:end);
    %add edges 
    l(end+1:x^2)=0;% lengthen predecessor list if too short
    g=x+1:x^2;      % g=greater neighbours
    s=2:x-1;        % s=smaller neighbours %keep only valid/unvisited neighbours 
    u=[g(~mod(g,x)),s(~mod(x,s)&s.^2>=x)]; %-1byte
    u=u(~l(u));
    q=[q,u];      %add only hte valid nodes edges to queue
    l(u)=l(x)+1;       %mark x as predecessor  
end;
l(b)-1 %output length to the end of the path

오늘 컨볼 루션 없음


2
대신 동일한 작업을 수행 l=zeros(1,a*b);할 수 있습니다l(a*b)=0;
Luis Mendo

아아 .... 여전히 10 바이트 뒤에 있습니다.
Abr001am

1

자바 스크립트 (ES6), 186 바이트

(m,n)=>(g=i=>{for(q=[i],r=[],r[i]=j=0;i=q[j++];)for(k=i+i;k<=i*i&(k<m*m*2|k<n*n*2);k+=i)r[k]-r[i]<2?0:r[q.push(k),k]=r[i]+1},g(m),s=r,g(n),Math.min(...r.map((i,j)=>i+s[j]).filter(i=>i)))

도우미 함수를 사용 g에서 모두에게 상승 경로를 계산 m하고 n제공된 한계까지 차례로, 다음 함께 경로를 반환 가장 낮은 값을 요약한다.


1

Mathematica 98 바이트

내장 함수 FindShortestPath가 표준 허점에 대한 제약 조건을 위반하지 않는다고 가정합니다 . 그렇다면 알려 주시면이 제출물을 삭제하겠습니다.

무차별 대입 값이 크면 느려집니다 b. 나는 여전히 속도를 높이는 방법을 생각하고 있습니다.

h@{a_,b_}:=Length@FindShortestPath[Graph[Apply[Join,Thread[#<->Range[2,#] #]&/@Range[b^2]]],a,b]-1

노드 사이의 적절한 가장자리 그래프 업이 세트 ab^2. FindShortestPath그래프에서 최단 경로를 찾습니다. Length노드를 계산합니다. Length -1가장자리 수입니다.

Thread[# <-> Range[2, #] #] &전체 그래프의 가장자리를 생성합니다. 예를 들어, Thread[# <-> Range[2, #] #]&[5]가장자리를 생산하는 것 {5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}입니다, {5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}.


1

MATLAB (195) (185) (181) (179)(173)

참고 : 나 사용자 Agawa001 개인적으로 나는 그의 도움을 사용하여 @flawr 사용자를 이겼 음을 증명한다.

 function t(a,b,p),for r=0:1,d=(b*~r+r*a)/gcd(a,b);while(d>1)p=p+1;e=find(~rem(d,1:d));f=max(e(a^(1-r/2)>=e));a=a*min([find(1:a*a>=b) a])^~(f-1);d=d/f;a=a*f^(1-2*r);end,end,p
  • 이 함수는 다른 함수와 다르며, 순수한 수학 계산 및 인수 분해를 따르지만 경로 또는 그래프와는 아무런 관련이 없습니다.
  • 함수 호출의 예 :

     t(2,3,0)
    
     p =
    
     4
    

    모든 테스트 사례가 충족됩니다

  • 설명:

설명을 시작하기 전에 "녹색이 아닌"일부 보조 정리를 증명할 수 있습니다.

렘마 (1) : 두 숫자 사이의 최적 경로 (a,b)는 노드가 먼저 증가하고 감소하는 방식으로 존재합니다.

왜 ? 이것은 임의의 숫자를 나누는 최대 정수량 a이 각각 숫자 a자체보다 크므로 영리한 접근 방식 a으로 최대한 크게 곱한 다음 더 큰 값으로 나누도록 선택해야 하기 때문에 간단하게 증명 됩니다. 우리가 그 길 a을 가면 숫자가 줄어들 기 때문에 우리가 분배 된 점진적으로 곱하기 위해 더 많은 반복이 필요합니다.

보조 정리 (2) : 숫자에서 ab경우 gcd(a,b)=1 a를 곱 b하면, b보다 더 큰 a이 알려진 수를 곱한 될 c경우 gcd>1 a의 가장 큰 제수로 점진적으로 곱해야한다 b/gcd라는 이름의 d상태를 검증하는 것이 a >= d아니라 모두가 때 d', 즉이야 최소보다 더 큰 a, a수신 a*c다시.

이 가정은 어떤 시작 노드가 증명 간단 a는 가장 작은 여러 도달 할 때까지 곱해야 a하고 b그래서 하나 우리 곱셈의 비율로 b*gcd분할 프로세스가 시작되기 전에 보장 항상 최단 경로가 SMP 것을 주요 조건을 확인 최대에 의해 시작, 또는 d사용할 수없는 경우이 첫 번째 단계에 유효한 조건을 만들기 위해 숫자 c를 곱합니다 .aa>=d

보조 정리 (3) : 그래프-ultimum에서의 배수 ab해당 숫자의 GCD하고 b있다 b자체

이것은 이전 조작의 결과 일 뿐이며 마지막 남은 단계는 제곱근을 초과하지 않는 최대 제수로 점차적으로 나뉩니다.

딜레마 :c 반복적으로 곱할 최적의 숫자는 a1 단계의 열림 조건과 궁극의 열림 조건으로 이어집니다.

좋은 질문은 간단한 상황에 대해 간단한 패리가 있으므로 두 끝의 예를 (a,b)=(4,26)다음과 같이 인수 분해 한다고 가정합니다 .

  2 | 2
  2 | 13

외에도에서 gcd=2곱해야 느릅 나무 작은 정수 2범위가 13있다 7,하지만 2보다 큰 사촌 제곱되도록이 분명히 배제된다.

  2 | 2 
  5 | 13

두 번째 예에서 Appearenlty은 (a,b)=(10,26)상기 c에서 최저 정수 측정 15초과 13/5따라서이를 만족 그래프이다 스케일링의 조건 3다음 단계 여기서 곱한되도록,3

  2 | 2 
  5 | 13
  3 |

왜 ? 이는 2*13/gcd=13테이블의 두 번째면과 일치시키기 위해 곱한 후에 이전에 추가 한 정크 양이 최적으로 가장 작고 그래프를 따라 이동하는 것이 최소화 될 수 10있기 때문입니다. 가장 적은 시간이 줄어들었고, 우리의 목표에 도달하기 위해 또 하나의 분할 단계가 증가했을 것 2*13입니다. 13*2*5*10/2*5다음에 열거됩니다 13*2*5/5. 분명히 여기에서 나눌 수는5*3<13*2

그리고 한가지 더 ........ HAIL MATHS ...


이것들은 @flawr과 비교 결과입니다 .flawr의 알고리즘을 고려한 시간 실행에 대한 상한선을 만들었습니다. 시간이 너무 많이 걸립니다!

온라인 컴파일 가능 코드의 헤더에 시작 및 종료 스캔 범위를 변수 a 및 b로 삽입 할 수 있습니다.


와우, 이건 놀랍습니다. 최적의 경로를 간단하게 구성 할 수있을 것으로 기대하지 않았습니다. 설명을 기대하고 ...
Zgarb

@ Zgarb 나는 주요 게시물 댓글 내에서 사소한 설명을 만들었습니다. 골프를 마치면 정교하게 설명 할 것입니다.
Abr001am

@ Zgarb 증거는 오븐 밖으로 신선합니다 !!!!
Abr001am
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.