Bölen grafiğindeki en kısa yollar


15

Giriş

Bu meydan okumada, yüksek bölen grafik olarak adlandırdığım belirli bir sonsuz yönlendirilmemiş grafikle ilgileneceğiz . Bu düğümler iki düğüm arasındaki bir kenar vardır 2. başlayarak tamsayılardır <b ise bir bölme b ve bir 2 ≥ b . 2'den 18'e kadar olan aralığın oluşturduğu alt grafik şöyle görünür:

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

Sonsuz yüksek bölen grafiğinin bağlı olduğu gösterilebilir, böylece iki düğüm arasındaki en kısa yolu sorabiliriz.

Giriş ve çıkış

Girişleriniz a ve b olmak üzere iki tamsayıdır . 2 ≤ a ≤ b <1000 olduğunu varsayabilirsiniz . Çıktınız, sonsuz yüksek bölen grafiğindeki a ve b arasındaki en kısa yolun uzunluğudur . Bu, yoldaki kenar sayısı anlamına gelir.

Aşağıdaki gerçeği yararlı bulabilirsiniz: daima itibaren optimum yolu vardır bir etmek b ilk yükseldiği ve sonra düştüğü ve kesinlikle daha az olan sadece ziyaretler düğümler oluyor 2b 2 . Özellikle, b <1000 olduğu için sadece 2.000.000'dan küçük düğümleri göz önünde bulundurmanız gerekir.

Örnekler

Girişleri 3ve 32. 3 ve 32 düğümleri arasındaki olası bir yol

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

Bu yolun dört kenarı vardır ve daha kısa yollar olmadığı ortaya çıkar, bu nedenle doğru çıktı olur 4.

Başka bir örnek olarak, bir uygun yolu 2ve 25bir

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

böylece doğru çıktı 5. Bu durumda, hiçbir optimal yol düğümü içermez 50 = lcm(2, 25).

Kurallar ve puanlama

Tam bir program veya işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez. Zaman veya bellek sınırı yoktur, bu nedenle kaba zorlamaya izin verilir.

Test senaryoları

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

varsaydığım gibi kaba bir kuvvet olmayan bir fikrim var, iki sayının en küçük katını sayıyor, görünene kadar yavaş yavaş güç iki ile çarpıyor, sonra ikinci sayı görünene kadar yavaş yavaş sqrt tarafından bölünüyor, zamanım yok şimdi de iy uygulamak için: /
Abr001am

Zgarb, Mathematica'nın FindShortestPath standart boşluklar üzerindeki kısıtlamayı ihlal ediyor mu? Olursa, bana bildirin, gönderimi silerim.
DavidC

@DavidC Bir boşluk olduğunu düşünmüyorum. İlgili cevabı aslında 0. üzerinde bir puan almış
Zgarb

Yanıtlar:


4

Matlab, 218 190 175 bayt

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

Liste uzatma adımındaki kısayol için @ kabı teşekkürler!

Bu nispeten basit bir dijkstra uygulamasıdır:

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

bugün evrişim yok


2
Yerine l=zeros(1,a*b);kullanabileceğiniz l(a*b)=0;aynı işlevi gören
Luis Mendo

ne yazık ki .... hala 10 byte uzunluğunda arkanızda.
Abr001am

1

JavaScript (ES6), 186 bayt

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

Sağlanan sınıra ggelen mve nbu sınıra kadar yükselen tüm yolları hesaplamak için bir yardımcı işlevi kullanır , ardından yolları birlikte toplar ve en düşük değeri döndürür.


1

Mathematica 98 bayt

Yerleşik işlevin FindShortestPathstandart boşlukların kısıtlamasını ihlal etmediğini varsayıyorum . Varsa, bana bildirin, bu gönderimi sileceğim.

Kaba kuvvet, dolayısıyla büyük değerleri ile yavaş b. Hala hızlanmanın yollarını düşünüyorum.

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

Dan düğüm arasında uygun kenarlı bir grafik kadar bu kümeler aiçin b^2. FindShortestPathgrafikteki en kısa yolu bulur. Lengthdüğümleri sayar; Length -1kenar sayısıdır.

Thread[# <-> Range[2, #] #] &tam grafiğin kenarlarını oluşturur. Örneğin Thread[# <-> Range[2, #] #]&[5], kenarları {5 <-> 2*5, 5 <-> 3*5, 5 <-> 4*5, 5 <-> 5*5}, yani {5 <-> 10, 5 <-> 15, 5 <-> 20, 5 <-> 25}.


1

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

Not: Bana kullanıcı Agawa001 şahsen ben onun yardımı kullanarak @flawr üzerinden kazandığımı kanıtlamak

 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
  • Bu işlev diğerlerinden farklıdır, bir grup saf matematiksel hesaplamaları ve çarpanlara ayırır, ancak yollar veya grafikler ile ilgisi yoktur.
  • İşlev çağrısı örneği:

     t(2,3,0)
    
     p =
    
     4
    

    Tüm test senaryoları karşılandı

  • Açıklama:

Açıklamalara başlamadan önce bazı yeşil "değil yeşil" lemmaları kanıtlayalım:

Lemma (1):(a,b) Düğümler ilk önce artan, sonra azalan bir şekilde iki sayı arasında en uygun yol vardır.

Neden ? Bu basitçe kanıtlanmıştır, çünkü herhangi bir sayıyı bölen maksimum tamsayı miktarı asayının akendisi kadar büyüktür , bu yüzden akıllı bir yaklaşım aolarak, onu yeterince büyütmek ve daha büyük değerlere bölmek için mümkün olduğunca çoğaltmayı seçmeliyiz . Eğer herhangi bir şekilde yol yaparsak, sayı adaralır, bu yüzden ondan vazgeçtiğimiz yavaş yavaş çoğalmak için gereksiz yere daha fazla tekrarlamaya ihtiyacımız var.

Lemma (2): Bir numaradan aiçin beğer gcd(a,b)=1 açarpılır bise, bdaha büyük abir bilinen sayısının çarpımına olacak ceğer, gcd>1 aen büyük bölen tarafından kademeli olarak çarpmak gerekir b/gcdadında ddurum doğrular o a >= dda bütün zaman d'yani s minimum değeri daha büyüktür a, tekrar aalır a*c.

Bu varsayım, herhangi bir başlangıç ​​düğümünün aen küçük katına ulaşana kadar çoğaltılması gerektiğini kanıtlamak kolaydır ave bbu nedenle, ya b*gcdbölümleme işlemi başlamadan önce her zaman smp'ye giden en kısa yolu garanti eden, ana durumu doğrulayan maksimum ile başlangıç oranlarıyla çarpıyoruz, veya dmevcut olmadığında , bu ilk aşama için geçerli bir koşul oluşturmak üzere bir sayı cile çarpılır .aa>=d

Lemma (3): bir grafiktir-ultimum çoklu kaynaktan ait aiçin bbu sayının gcd ve bbir bkendini

Bu sadece önceki manipülasyonların bir sonucudur ve kalan son adımlar da kare kökünü aşmayan en büyük bölenle yavaş yavaş bölünerek yapılır.

İkilem: Aşama 1 ile açılış aşaması boyunca doğrudan en yüksek cseviyeye çıkacak yinelemeyle çarpılacak optimum sayı nedir a?

İyi bir soru, herhangi bir basit durum için basit bir çözüm var, bu yüzden böyle iki faktörlü bir örnek (a,b)=(4,26)varsayalım:

  2 | 2
  2 | 13

Bunun dışında gcd=2ile çarpmak gerekir wich en küçük tamsayı 2ulaşmak için 13ise 7, ancak 2 den büyük cuz bir karesi olduğunu bu yüzden açıkçası, ekarte edilir.

  2 | 2 
  5 | 13

İkinci örnekte Appearenlty (a,b)=(10,26)yukarıda carasında en düşük tamsayı olarak ölçülür 1için 5aşan 13/5bu nedenle tatmin olduğu grafik ölçekleme, durumu 3sonraki adım burada ile çarpılır, böylece3

  2 | 2 
  5 | 13
  3 |

Neden ? bunun nedeni, 2*13/gcd=13tablonun ikinci tarafına uymak için çarpmamız gerektiğinde, daha önce eklediğimiz önemsiz miktar en iyi şekilde en aza indirilir ve grafik boyunca hareket etme en aza indirilir, eğer 10bölme şansı gibi daha büyük bir değerle çarpılırsak en az zaman azalır ve hedefimize ulaşmak için bir bölme adımı daha artardı 2*13. bunlar numaralandırılır: 13*2*5*10/2*5o zaman 13*2*5/5. Açıkçası, burada bölünecek sayı5*3<13*2

ve bir şey daha ........ DEMİR MATS ...


Bunlar @flawr'ınkilerle karşılaştırmalı sonuçlarım sadece kusurların algoritmasını içeren zaman yürütme için bir üst sınır oluşturduğuna dikkat edin, çok fazla zaman alıyor!

Başlangıç ​​ve bitiş tarama aralıklarını çevrimiçi derlenebilir kodun başlığına a ve b değişkenleri olarak ekleyebilirsiniz.


Vay canına, bu şaşırtıcı. Optimal yolların basit bir şekilde inşa edilmesini beklemiyordum. Açıklamayı dört gözle bekliyorum ...
Zgarb

@Zgarb i ana yazı yorum içinde önemsiz bir açıklama yaptı, ben golf, btw, ne eşsiz güzel bir meydan okuma bitirmek zaman ayrıntılı moe olacak!
Abr001am

@Zgarb kanıtı fırından yeni çıkmış !!!!
Abr001am
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.