Đường dẫn ngắn nhất trong đồ thị ước


15

Giới thiệu

Trong thử thách này, chúng ta sẽ xử lý một đồ thị vô hướng vô hạn nhất định, mà tôi gọi là đồ thị ước số cao . Các nút của nó là các số nguyên bắt đầu từ 2. Có một cạnh giữa hai nút <b nếu một phân chia bmột 2 ≥ b . Biểu đồ con được hình thành bởi phạm vi từ 2 đến 18 trông như thế này:

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

Có thể chỉ ra rằng đồ thị ước số cao vô hạn được kết nối, vì vậy chúng ta có thể hỏi về con đường ngắn nhất giữa hai nút.

Đầu vào và đầu ra

Đầu vào của bạn là hai số nguyên ab . Bạn có thể giả sử rằng 2 ≤ a ≤ b <1000 . Đầu ra của bạn là độ dài của đường đi ngắn nhất giữa ab trong biểu đồ ước số cao vô hạn. Điều này có nghĩa là số cạnh trong đường dẫn.

Bạn có thể thấy thực tế sau đây hữu ích: luôn tồn tại một đường dẫn tối ưu từ a đến b đầu tiên tăng rồi giảm và chỉ truy cập các nút có độ chính xác nhỏ hơn 2b 2 . Cụ thể, vì b <1000, bạn chỉ cần xem xét các nút nhỏ hơn 2 000 000.

Ví dụ

Hãy xem xét các đầu vào 332. Một đường dẫn có thể có giữa các nút 3 và 32 là

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

Đường dẫn này có bốn cạnh, và hóa ra không có đường dẫn ngắn hơn, vì vậy đầu ra chính xác là 4.

Một ví dụ khác, một đường dẫn tối ưu cho 225

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

vì vậy đầu ra đúng là 5. Trong trường hợp này, không có đường dẫn tối ưu nào chứa nút 50 = lcm(2, 25).

Quy tắc và tính điểm

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép. Không có giới hạn thời gian hoặc bộ nhớ, vì vậy buộc phải cho phép vũ phu.

Các trường hợp thử nghiệm

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

Tôi có một ý tưởng không phải là một lực lượng vũ phu như tôi giả định, nó đếm bội số nhỏ nhất của hai số, nhân dần với lũy thừa hai cho đến khi nó xuất hiện, sau đó chia dần cho sqrt cho đến khi số thứ hai xuất hiện, tôi không có thời gian để triển khai iy ngay bây giờ: /
Abr001am

Zgarb, Mathicala có FindShortestPath vi phạm các ràng buộc về sơ hở tiêu chuẩn không? Nếu có, chỉ cần cho tôi biết và tôi sẽ xóa bài đăng của mình.
DavidC

@DavidC Tôi không coi đó là một lỗ hổng. Các câu trả lời có liên quan thực sự có một số điểm là 0.
Zgarb

Câu trả lời:


4

Matlab, 218 190 175 byte

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

Cảm ơn @beaker về phím tắt trong bước kéo dài danh sách!

Đây là một triển khai dijkstra tương đối đơn giản:

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

hôm nay không có tổ hợp


2
Thay vì l=zeros(1,a*b);bạn có thể sử dụng l(a*b)=0;, điều này cũng tương tự
Luis Mendo

than ôi .... vẫn còn 10 byte phía sau bạn.
Abr001am

1

JavaScript (ES6), 186 byte

(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)))

Sử dụng hàm trợ giúp gđể tính toán tất cả các đường dẫn tăng dần từ mnlần lượt đến giới hạn được cung cấp, sau đó tính tổng các đường dẫn lại với nhau và trả về giá trị thấp nhất.


1

Toán học 98 byte

Tôi giả định rằng hàm tích hợp, FindShortestPathkhông vi phạm các ràng buộc về sơ hở tiêu chuẩn. Nếu có, chỉ cần cho tôi biết và tôi sẽ xóa bài đăng này.

Lực lượng vũ phu, do đó chậm với giá trị lớn của b. Tôi vẫn đang nghĩ cách để tăng tốc nó.

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

Điều này thiết lập một biểu đồ với các cạnh thích hợp giữa các nút từ ađến b^2. FindShortestPathtìm đường đi ngắn nhất trong đồ thị Lengthđếm các nút; Length -1là số cạnh.

Thread[# <-> Range[2, #] #] &tạo ra các cạnh của đồ thị đầy đủ. Ví dụ, Thread[# <-> Range[2, #] #]&[5]sẽ tạo ra các cạnh {5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}, nghĩa là , {5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}.


1

Matlab (195) (185) (181) (179)(173)

Lưu ý: Tôi là người dùng Agawa001 cá nhân tôi chứng thực rằng tôi đã thắng người dùng @flawr cách sử dụng sự trợ giúp của anh ta

 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
  • Hàm này khác với các hàm khác, nó tuân theo một loạt các phép tính và hệ số toán học thuần túy nhưng không liên quan gì đến các đường dẫn hoặc đồ thị.
  • Ví dụ về chức năng gọi:

     t(2,3,0)
    
     p =
    
     4
    

    Tất cả các trường hợp thử nghiệm đều hài lòng

  • Giải trình:

Trước khi bắt đầu với lời giải thích, hãy chứng minh một số bổ đề "không phải là màu xanh lá cây":

Bổ đề (1): Một đường dẫn tối ưu giữa hai số bất kỳ (a,b)tồn tại theo cách các nút đầu tiên tăng sau đó giảm dần.

Tại sao ? Điều này đơn giản được chứng minh bởi vì số lượng số nguyên tối đa mà phân chia bất kỳ số lượng alần lượt là lớn như số lượng abản thân, như vậy là một cách tiếp cận thông minh, chúng ta phải chọn nhâna càng nhiều càng tốt để làm cho nó đủ lớn hơn, sau đó chia cho các giá trị lớn hơn. Nếu chúng ta thực hiện theo cách vòng, số lượng aco lại, vì vậy chúng ta cần lặp lại nhiều hơn để nhân nó dần dần mà chúng ta được phân phối.

Bổ đề (2): Từ một số ađến b, nếu gcd(a,b)=1 ađược nhân với b, nếu blớn hơn anó sẽ được nhân với một số đã biết c, nếu gcd>1 aphải được nhân dần lên bởi ước số lớn nhất b/gcdđược đặt tên dđể xác minh điều kiện a >= dkhi tất cả dcụ thể là tối thiểu lớn hơn a, anhậna*c lại.

Giả định này rất đơn giản để chứng minh bất kỳ nút bắt đầu nào aphải được nhân cho đến khi nó đạt bội số nhỏ nhất abdo đó chúng ta nhân với tỷ lệ b*gcdbắt đầu bằng mức tối đa để xác minh điều kiện chính, đảm bảo luôn luôn là con đường ngắn nhất để smp trước khi quá trình phân chia bắt đầu, hoặc khi dkhông có sẵn, một số cđược nhân với ađể tạo điều kiện hợp lệ a>=dcho giai đoạn đầu tiên này.

Bổ đề (3): Từ bội graph-ultimum của ađể b, gcd của con số này và bbbản thân

Chà, đây chỉ là hậu quả của các thao tác trước đó và các bước cuối cùng còn lại cũng được thực hiện dần dần chia cho số chia lớn nhất không vượt quá căn bậc hai của nó.

Tiến thoái lưỡng nan: Con số tối ưu cđược nhân với số lần lặp asẽ dẫn thẳng đến điều kiện mở cho giai đoạn 1 sau đó là tối ưu là bao nhiêu?

Câu hỏi hay, đối với bất kỳ tình huống đơn giản nào cũng có một parry đơn giản, vì vậy giả sử một ví dụ về hai đầu được (a,b)=(4,26)nhân tố như thế này:

  2 | 2
  2 | 13

Ngoài gcd=2số nguyên nhỏ nhất phải được nhân với 2để đạt 13được 7, nhưng rõ ràng nó bị loại trừ, vì nó lớn hơn 2, vì vậy a là bình phương.

  2 | 2 
  5 | 13

Appearenlty trong ví dụ thứ hai (a,b)=(10,26)trên cđược đo như phần nguyên thấp nhất từ 1để 5mà vượt quá 13/5do đó nó đáp ứng các điều kiện của đồ thị mở rộng quy mô, đó là 3, vì vậy bước tiếp theo đây là nhân với3

  2 | 2 
  5 | 13
  3 |

Tại sao ? điều này là do, một khi chúng ta phải nhân 2*13/gcd=13với để khớp với mặt thứ hai của bảng, lượng rác chúng ta đã thêm trước đó là tối thiểu và di chuyển dọc theo biểu đồ được giảm thiểu, nếu chúng ta nhân với giá trị lớn hơn như 10cơ hội chia cho số lần giảm ít nhất và nó sẽ được tăng thêm 1 bước phân chia khác để đạt được mục tiêu của chúng tôi 2*13. được liệt kê vào: 13*2*5*10/2*5sau đó13*2*5/5 . Trong khi đó, rõ ràng ở đây con số được chia cho là5*3<13*2

và một điều nữa ........ MATIL HAIL ...


Đây là những kết quả so sánh của tôi với những kết quả của @flawr chỉ cần chú ý rằng tôi đã thực hiện một giới hạn trên cho việc thực hiện thuật toán của flawr theo thời gian, nó mất quá nhiều thời gian!

Bạn có thể chèn phạm vi quét bắt đầu và kết thúc dưới dạng các biến a và b trong tiêu đề của mã có thể biên dịch trực tuyến.


Wow, điều này thật đáng ngạc nhiên. Tôi không mong đợi rằng các đường dẫn tối ưu có thể được xây dựng theo cách đơn giản. Mong được giải thích ...
Zgarb

@Zgarb tôi đã đưa ra một lời giải thích tầm thường trong các bình luận chính của bài đăng, tôi sẽ moe công phu khi tôi hoàn thành việc chơi golf, btw, thật là một thử thách độc đáo!
Abr001am

@Zgarb bằng chứng là mới ra lò !!!!
Abr001am
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.