Negatif Uzay Grafikleri


13

Görev

Size pozitif bir tamsayı verilecek ve bu düğümlerle bir " kendini tamamlayıcı grafik " vermelisiniz . Kendini tamamlayan bir grafiğin ne olduğunu bilmiyorsanız, wikipedia makalesi size çok yardımcı olmayacaktır.Aşağıda iki açıklama vardır, teknik ve teknik olmayan.

Teknik Olmayan

Grafik, çizgilerle birbirine bağlanan bir düğüm kümesidir. Her bir nokta çifti bir çizgi veya hiçbiri ile birleştirilemez. Bir grafiğin "tamamlayıcısı", bir grafik almanın ve bağlı olmayan tüm düğümlerin bağlanmasının ve tüm düğümlerin bağlantısının kesilmesinin sonucudur.

Kendini tamamlayan bir grafik, tamamlayıcısı orijinalin şekline yeniden düzenlenebilen bir grafiktir. Aşağıda kendi kendini tamamlayan bir grafik ve bunun nasıl yapılacağına dair bir örnek verilmiştir.

İşte 5 düğümlü bir grafik:

5 Düğümlü Grafik

Bağlantıların kırmızı noktalı çizgilerle gidebileceği tüm yerleri vurgulayacağız:

Vurgulanan Grafik

Şimdi kırmızı ve siyah kenarları değiştirerek grafiğin tamamlayıcısını bulacağız:

Tamamlayıcı

Bu orijinal grafiğe benzemez, ancak düğümleri bu şekilde hareket ettirirsek (her adım iki düğümü değiştirir):

İzomorfizma

Orijinal grafiği aldık! Grafik ve tamamlayıcısı aynı grafiktir

Teknik

Kendini tamamlayan bir grafik, tamamlayıcısına izomorfik bir grafiktir.

Özellikler

Size en uygun yöntemle pozitif bir tam sayı alırsınız. Ve uygun gördüğünüz herhangi bir yöntemde bir grafik çıktısı alacaksınız, ancak bunlarla sınırlı olmamak üzere Bitişiklik Matris Formu , Bitişiklik Listesi Formu ve elbette resimler! Çıkarılan grafik kendi tamamlayıcısı olmalı ve tamsayı girişi kadar sayıda düğüme sahip olmalıdır. Böyle bir grafik yoksa, bir falsy değeri çıkarmalısınız.

Bu ve bayt sayınızı en aza indirmeyi amaçlamalısınız.

Test Durumları

Aşağıda birkaç n için olası çıkışların resimleri bulunmaktadır

4

5

9


Kendini tamamlayan bir grafik yalnızca tüm grafiğin eşit sayıda kenarı olduğunda kullanılabilir. Bunun garantisi var mı?
xnor

@xnor Bunu eklemeyi unuttum. Şimdi düzeltildi.
Ad Hoc Garf Hunter

Negatif girdileri ele almamız gerekiyor mu?
xnor

@xnor Hayır ben uyumlu olmasını soru çözecektir
Ad Hoc GARF Hunter

3
Herkes bir cevabı temel alma fikrini elde etmeden önce , Wolfram'ın veritabanından GraphData@{"SelfComplementary",{#,1}}&düşük için bazı örnekler yüklediğine inanıyorum n, bu yüzden bu keyfi olarak büyük girdiler için işe yaramayacak.
Martin Ender

Yanıtlar:


9

Haskell , 77 bayt

f n=[(a,b)|b<-[1..n],a<-[1..b-1],mod n 4<2,mod(a+(last$b:[a|odd n,n==b]))4<2]

Çevrimiçi deneyin!

Bu, bir kenarın (a,b)grafikte olup olmadığına karar vermek için hesaplaması kolay açık bir ölçüt kullanır . Modulo 4 değerleri arasında permütasyon çevrimi ile bu algoritmayı başlatır.

4*m -> 4*m+1 -> 4*m+2 -> 4*m+3 -> 4*m

İki uç nokta köşesi 0 veya 1 modulo 4'e eklenen kenarları ekliyoruz. Bu permütasyona göre bisiklet köşelerinin her biri için köşe toplamına 2 modulo 4 eklediğini ve böylece kenarları ve kenarları değiştirmediğini unutmayın. Bu, kenarları tamamlayan köşelerin permütasyonunu verir.

Grafiğin 4 katının ötesinde fazladan bir düğümü varsa, tek başına bir döngüye konur. O zaman diğer köşe eşit olduğunda kenarları dahil ederiz. Köşelere izin vermek, pariteyi tersine çevirir ve böylece grafik kendini tamamlayıcı olarak kalır.

Köşelerin sayısı 0 veya 1 modulo 4 değilse, tüm grafikte tek sayıda kenar olduğu için kendiliğinden tamamlayıcı grafik mümkün değildir

Genel olarak, koşullar şunlardır:

  • N girişi 0 veya 1 modulo 4 değilse, boş bir liste çıkar
  • N çift Aksi takdirde, tüm kenarları dahil (a,b)olan a<bve a+b, 0 ya da 1 modülo 4'e eşittir.
  • Aksi takdirde, n tuhafsa, aynısını yapın, ancak bunun yerine (a,n)a çift olduğunda formun kenarlarını ekleyin .

Kod, koşulu hem ve mod(a+b)4<2ile değiştirerek ikinci ve üçüncü durumları birleştirir .mod(a+a)4<2odd nb==n


5

Brachylog 2 , 24 bayt

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧

Çevrimiçi deneyin!

Bu, iki bitişiklik listesinden oluşan bir çifti döndüren bir işlevdir : biri grafik için, diğeri de tamamlayıcı grafik için. (TIO'daki Brachylog yorumlayıcısında, Zkomut satırı argümanı olarak vererek, tam bir program yerine bir işlevi değerlendirmesini isteyebilirsiniz .) Örneğin, girdi çıktısı 5:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

Bir görüntü olarak neye benzediğini görebilirsiniz (iki grafiği gösterir):

bir grafik ve 5 element üzerindeki aynı tamamlayıcısı

Prolog tabanlı dillerde yaygın olduğu gibi, işlev birden fazla çağrı modelini destekler. Özellikle, bir jeneratör olarak kullanmayı denerseniz, olası tüm tamamlayıcı grafikleri verilen sayıda köşe noktasıyla çıkarır (ancak bu durumu kullanılabilir hale getirmek için herhangi bir çaba sarf etmemiştim ve özellikle her birinin çıktısını alacaktır) grafikler her biri birçok kez).

açıklama

Bu temel olarak sorunun sadece bir tanımıdır ve Prolog uygulamasını en iyi çözme yöntemini bulmaya bırakır. (Bununla birlikte, bu özel durumda kaba kuvvetten daha iyi bir algoritma kullanacağından şüpheliyim, bu yüzden muhtemelen oldukça verimsizdir ve test, performansın grafik ne kadar büyük hale geldiğini çok daha kötüleştirdiğini göstererek bunu teyit ediyor gibi görünüyor.)

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧
 ⟦₁                       The range [1, 2, …, ?], where ? is the input
   ⊇                      A subset of that range…
    Ċ                     …which has exactly two elements
{    }ᶠ                   A list of everything that fits the above description
{⟦₁⊇Ċ}ᶠ                   All edges that could exist in a ?-element graph
       p                  Find a permutation of these…
        ḍ                 …so that splitting it into two equal parts…
          (       ∨   )   …either:
               dl?          produces ? distinct elements
           \                after transposing it
            \ᵐ              and transposing its elements
              c             and flattening one level;
                          or:
                   ?<2      ? was less than 2
         .             ∧  Once you've found it, . specifies what to output

Bu arada, (∨?<2)0 ve 1 özel vakaları ele almak için 6 baytlık (programın ¼ karakterleri ) harcamak zorunda kaldım . Sinir bozucu, ama bu özel vakaların doğası.

\\ᵐcdl?Bölüm işte bir çalışılmış örnek, anlamak biraz zordur. Amacı, bir şeyin bir grafik ve onun tamamlayıcısı olup olmadığını, grafikteki ve tamamlayıcının listeler içinde aynı sırada olduğunu kontrol etmektir. Grafik / tamamlayıcı çifti programın nihai çıktısı olur. Örnek bir örnek:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

Bunu değiştirmek, grafik ve tamamlayıcı arasındaki karşılık gelen kenar çiftlerinin bir listesini verir:

[[[1,2],[2,5]],[[1,3],[2,3]],[[1,5],[2,4]],[[3,5],[3,4]],[[4,5],[1,4]]

Sonra, liste öğelerinin içine aktarıyoruz ve bir seviye düzleştiriyoruz; bize grafik ve tamamlayıcı arasındaki karşılık gelen öğelerin çiftlerinin bir listesini verir:

[[1,2],[2,5],[1,2],[3,3],[1,2],[5,4],[3,3],[5,4],[4,1],[5,4]]

Açıkçası, burada istediğimiz şey, her bir elemandan başlayarak en fazla 1 çift olmamasıdır (böylece grafiğin ve tamamlayıcının elemanlarının 1'e 1 yazışmada olduğunu kanıtlar). Sadece listenin tam olarak ?farklı elemanlara (yani köşe sayısına eşit bir dizi farklı eleman) sahip olduğunu belirterek neredeyse doğrulayabiliriz . Bu durumda, test başarılı olur; farklı unsurlar:

[[1,2],[2,5],[3,3],[5,4],[4,1]]

Ancak, bu potansiyel bir soruna yer açar; bir tepe noktasının orijinal grafikte tamamen bağlantısı kesilirse, yazışmalarından bahsedilmeyecek ve başka bir tepe noktasından yinelenen yazışmalara yer bırakmayacaktır. Bu durumda, tamamlayıcı grafiği hep tepe arasında bir kenar olmalıdır (genelliği kaybetmeden en çok diyelim 1) ve diğer her köşe ve yazışmalar listesi içerecektir yüzden [1,2], [1,3], ..., [1, ?]. Ne zaman ?büyük başka türlü olurdu daha bu yüzden herhangi bir problem yoktur, daha çok yazışmalar toplam yol açacaktır. Tek sorun ?3 veya daha düşük olduğunda olur , bu durumda yalnızca bir ek yazışma ekleriz (1girişte görünmüyor); bununla birlikte, bu pratikte bir problem değildir, çünkü 3 elemanlı bir grafikte 3 olası kenar vardır, bu tek bir sayıdır (aynı şekilde 2 elemanlı bir grafikte 1 olası kenar da tek bir sayıdır) ve dolayısıyla test \adımda başarısız olur (düzensiz bir listeyi, yani öğeleri farklı uzunluklara sahip olanları aktaramazsınız).


Arasındaki fark zve \olduğunu z, yani siklik zip [[1,2,3],["a"]]sona erecek [[1,"a"],[2,"a"],[3,"a"]]ile zbu başarısız olur ise, \. \şu anda sadece kare matrisler üzerinde çalışıyor; gelecekteki uygulama, zdöngüsel olarak değil, aynı şekilde çalışmasını sağlayacaktır .
17'de

Aslında farkı kendim çözmüştüm, ama sadece açıklamayı yazdıktan sonra. Bu özel çözüm `` sadece dikdörtgenler üzerinde çalışıyor (ancak bu adımdan yararlanamazsanız sadece 2 bayt daha alır).

2

BBC BASIC, 161 bayt

Tokenlenmiş dosya boyutu 140 bayt

Yorumlayıcıyı http://www.bbcbasic.co.uk/bbcwin/bbcwin.html adresinden indirin

I.m:IF2ANDm ORm<4P.0:END
r=400n=-2A.m:t=2*PI/n:F.i=1TOn*n:a=i DIVn:b=i MODn:c=b:IFa+b A.2a*=t:b*=t:L.r+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1A.m A.c DRAWr*3,0
N.

Kod çözülmemiş kod

  INPUTm                           :REM get input
  IF2ANDm ORm<4PRINT0:END          :REM if m=4x+2 or 4x+3 or less than 4, print 0 and exit
  r=400                            :REM radius of diagram
  n=-2ANDm                         :REM n = m truncated to an even number
  t=2*PI/n                         :REM t = 1/n turns
  FORi=1TOn*n                      :REM for each combination of vertices
    a=i DIVn                       :REM extract a and b
    b=i MODn                       :REM make a copy of c
    c=b                            :REM if a+b MOD 4 = 2 or 3, convert a and b to angles and draw edge.
    IFa+b AND2 a*=t:b*=t:LINEr+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1ANDm ANDc DRAWr*3,0
  NEXT                             :REM if m is odd and c is odd, draw a line to the additional vertex for m=4x+1 input.

açıklama

Bu, Xnor ile aynı algoritmayı kullanır, ancak diyagramatik bir çıktı üretir.

Burada nform olan 4x+2ya da 4x+3kenarların sayısı tek olduğu gibi herhangi bir çözüm yoktur.

n4x formunun olduğu yerde , tüm köşeleri bir daire içinde düzenleriz ve bu kenarları (a+b) mod 42 veya 3 olan yerleri çizeriz (golf için nedenlerden dolayı Xnor'ın durumunda 0 veya 1 değil. Bu nedenle Xnor tarafından verilen çözümün tamamlayıcısıdır).

Bunu daha resimli bir şekilde görmek için, her ikinci köşeyi alıp kenarları saat yönünün tersine 1 ve 2 köşelere çekiyoruz. Bu n, toplamın yarısı olan paralel yönleri tanımlar . Sonra bunlara paralel olarak diğer tüm kenarları ekliyoruz.

Tamamlayıcı, her kenar spesifikasyonunda a ve b'ye 1 eklenerek veya diyagramın bir 1/ndönüşle döndürülmesiyle bulunabilir.

n4x + 1 formunun olduğu yerde , 4x grafiğinin her ikinci köşesine bağlı başka bir tepe noktası ekliyoruz. Merkeze yerleştirilirse, diyagramın simetrisi korunurdu, ancak netlik için ana nokta çemberinin dışına koymayı seçtim.

Çıktı

4x + 1 için ilk birkaç durum aşağıdadır. 4x kasaları sağ alt köşedeki tepe noktası ve ilişkili kenarları silerek görülebilir.

resim açıklamasını buraya girin


1

JavaScript (ES6), 191 bayt

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a

Bu işlev bir bitişiklik listesi döndürür. Bu dönerek boş tamamlayıcı grafikler ve non-çıkışları arasında iki algoritma, ve ayırt kullanır 0yerine []yok var olduğunda. İlk algoritma, BIT yüklemi kullanılarak oluşturulan Rado Grafiklerine dayanır ve geçerli 0-, 1-, 4- ve 5 dereceli tamamlayıcı grafikler oluşturur. Matematikte arkadaşlarımız tarafından bulunan diğer algoritma, geçerli bir V tepe tamamlayıcı grafiğine 4 yollu bir ekleme uygulayarak geçerli bir V + 4 tepe tamamlayıcı grafiği oluşturur.

Geçerli bir tamamlayıcı grafiğin (kullanarak n*~-n/4%1) varlığını doğrulamak için girişi doğrulayarak başlar ve başarısız olursa döndürür 0. Daha sonra geçerli bir düşük dereceli çözüm n>5oluşturmak için n-4duruma geri dönüp dönmediğini kontrol eder ve 4 eklemeyi özyineleme zincirini yedekleme yolunda döndürülen bitişiklik listesine uygular. Son olarak, n>5doğru değildir, bu kadar yineleme 0için n-1için xve yeğer ve kontroller (y>>x)&1doğrudur. Öyleyse, bu düğümler eşleştirilir.

Üçlü işleçler if-else deyimlerine genişletildiğinde ve eval()satır içine alındığında işlevin daha okunabilir bir biçimi aşağıda verilmiştir :

// precalculate amount of required vertices in v
f = (n, a = [], v = n*~-n / 4) => {
  // if amount is non-integer
  if (v % 1) {
    // no valid complementary graph
    return 0;
  } else {
    if (n > 5) {
      // generate valid (n-4)-order complementary graph
      f(n -= 4, a);
      // apply 4-path addition
      for (i = 0; i < n;)
        a.push([i, n+1],[i++, n+2]);
      a.push([n, ++n], [n, ++n], [n, ++n]);
    } else {
      // construct Rado graph using BIT predicate
      for(l = x = 0; x < n; x++)
        for(y = x; y < n; y++)
          // if amount of pairs is less than required and xth bit of y is high
          if (l < v && (y>>x & 1))
            // vertices x and y should be paired
            a.push([x,y]);
    }
    return a;
  }
};

gösteri

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a
<input type="number" onchange="o.textContent=JSON.stringify(f(this.value))"><pre id="o"></pre>

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.