Bir grafik oluşturma


15

Bu zorlukta, göreviniz bir dizi yönergeden yönlendirilmemiş bir grafik oluşturmaktır. Her negatif olmayan tam sayı için bir yönerge vardır ve her biri belirli bir grafiği yeni bir grafiğe dönüştürür.

  • Yönerge 0: Bağlantısı kesilmiş yeni bir düğüm ekleyin.
  • Yönerge 1: Yeni bir düğüm ekleyin ve mevcut tüm düğümlere bağlayın.
  • Yönerge m > 1: Derecesi (komşu sayısı) ile bölünebilen tüm düğümleri kaldırın m. 0Herkes tarafından bölünebileceğini unutmayın m, bu nedenle bağlantısı kesilen düğümler her zaman kaldırılır.

Yönergeler, boş grafikle başlayarak soldan sağa doğru tek tek uygulanır. Örneğin, dizi [0,1,0,1,0,1,3]harika ASCII sanatı kullanılarak açıklandığı gibi işlenir. Boş grafikle başlıyoruz ve şu şekilde belirtildiği gibi tek bir köşe ekliyoruz 0:

a

Ardından, başka bir tepe noktası ekleyin ve şu şekilde gösterildiği gibi ilkine bağlayın 1:

a--b

Yönettiği gibi, daha sonra başka bir bağlantısız köşe ve bağlı tek ekleyebilir 0ve 1:

a--b   c
 \  \ /
  `--d

Yönettiği ülke olarak buna bir kez daha tekrarlamak 0ve 1:

  ,--f--e
 /  /|\
a--b | c
 \  \|/
  `--d

Son olarak, derece-3 köşelerini kaldırıyoruz ave bşu şekilde 3:

f--e
|\
| c
|/
d

Bu, dizi tarafından tanımlanan grafiktir [0,1,0,1,0,1,3].

Giriş

Bir dizi yönergeyi temsil eden negatif olmayan tam sayıların bir listesi.

Çıktı

Grafikteki dizi tarafından tanımlanan düğüm sayısı.

Test senaryoları

[] -> 0
[5] -> 0
[0,0,0,11] -> 0
[0,1,0,1,0,1,3] -> 4
[0,0,0,1,1,1] -> 6
[0,0,1,1,0,0,1,1,2,5,7,0,1] -> 6
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2] -> 6
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1] -> 8
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8] -> 14

Ayrıntılı kurallar

Bir işlev veya tam bir program yazabilirsiniz. En kısa bayt sayısı kazanır. Standart boşluklara izin verilmez. Lütfen cevabınızda algoritmanızı açıklayınız.


Bir hafta oldu, bu yüzden en kısa cevabı kabul ettim. Daha kısa bir süre sonra gelirse, seçimimi güncelleyeceğim. Şerefli bir söz Peter Taylor'ın kazanan da dahil olmak üzere başkalarının dayandığı cevabına gidiyor .


5
Soruyu okurken, aslında grafiği çizmeniz gerektiğini düşünüyoruz - Bu çok zor , aşağı
Optimizer

@Optimizer Evet, soruyu grafiğin gerçek temsili önemli değil ve asıl zorluk direktiflerin uygulanmasında yatmaktadır. Düğüm sayısı, doğruluğu kontrol etmenin kolay bir yoludur.
Zgarb

1
Bu meydan okumayı gerçekten çok seviyorum! Bir veri yapısı tasarlamak gibi. Giriş ve çıkış biçimleri ona bağlı olmadığından grafiğin nasıl temsil edileceğini bulmalısınız.
xnor

Yanıtlar:


4

Pyth , 37 31

lu?+GH<H2m@Gdf%+*@GTtTs>GTHUGQY

Bu çözüm, bir uliste oluşturmak için bir azaltma işlevi ( ) kullanır ; burada her giriş, listede kalan bir düğüme karşılık gelir ve düğümün başlangıçta 0 veya 1 yönergesi altında eklenip eklenmediğine karşılık gelen girdinin değeri.

G, azaltma işlevindeki akümülatör değişkenidir ve yukarıda belirtilen listeyi tutar. Boş listeye ilklendirilir Y,.

HQgirdinin her bir üyesinin değerini tek tek alır. İfadenin sonucu Gher seferinde atandı ve ifadesinin bir sonraki girdisi Qatandı Hve ifade yeniden çalıştırıldı.

GDüzgün güncellemek için, biri 0 veya 1 yönergesi ve diğeri diğer yönerge için olmak üzere iki olasılık vardır. Bu dava üçlü ile ayırt edilir? ... <H2 ...

Eğer H0 veya 1, daha sonra hepimiz ekleme yapmanın gerek Hiçin G. +GHbunu başarır.

Aksi takdirde, ihtiyaç duyulan ilk şey, grafikteki her düğüm için kaç komşusuna sahip olduğunu belirlemektir. Bu iki adımda gerçekleştirilir:

İlk olarak, s>GTgiriş düğümünde veya sonrasındaki 1s olan düğüm sayısını sayar. Bunların hepsi giriş düğümüne bağlanır, ancak giriş düğümü 1 ise 1'den fazla saymamız gerekir.

İkincisi, kendisine bağlanan giriş düğümünden daha önce düğüm sayısına ihtiyacımız var. Giriş düğümü 0 ise 0, giriş düğümü 1 ise giriş düğümünün dizini 0'dır T. Bu değer tarafından verilir *@GTT. Bununla birlikte, hala düzeltilmesi gereken ilk bölümden fazla sayma vardır. Böylece, *@GTtTgiriş düğümü 1 ise 1'in daha az olduğunu hesaplıyoruz . Bu değerler, giriş düğümüne bağlı düğümlerin sayısını vermek için toplanır.

% ... H0 verecekse sayı bölünebilir Hve dolayısıyla kaldırılmalıdır, aksi takdirde 0 vermeyecektir.

f ... UGböylece fbir filtre olduğu ve 0'ın yanlış olduğu için kaldırılmaması gereken girdinin indekslerini verecektir .

m@Gd bu indeksleri ilgili düğümlerin 0'larına ve 1'lerine dönüştürür.

Son olarak, sonuçta 0 ve 1 etiketli düğümlerin listesi bulunduğunda, uzunluğu hesaplanır ( l) ve yazdırılır (örtük).

@PeterTaylor sayesinde geniş fikir.


12

GolfScript (53 bayt)

])~{:^1>{.-1:H)-,:T;{..H):H*T@-:T+^%!{;}*}%}{^+}if}/,

Çevrimiçi demo

Henüz bunu golf yapmadım, ancak Hve Tdeğişkenleri ortadan kaldırmanın çok kolay olmadığını keşfettim, bu yüzden bu yerel bir minimum olabilir.

Stdin biçiminde girdi alır [0 1 2 3]. Stdout çıktı bırakır.

Ungolfed:

])~{
  :^1>{
    # array of 0s and 1s
    # Each 0 has degree equal to the number of 1s after it
    # Each 1 has degree equal to the number of values before it plus the number of 1s after it
    .-1:H)-,:T;
    {
      # Stack: x
      # T' = T - x is the number of 1s after it
      # H' = H + 1 is the number of values before it
      # Degree is therefore H' * x + T' = H * x + T - x = (H-1)*x + T
      # Keep x unless degree % ^ == 0
      ..H):H*T@-:T+^%!{;}*
    }%
  }{^+}if
}/,

4

CJam, 129 75 73 68 61 46 42 bayt

Peter algoritmasına dayanan çözüm:

Lq~{I+I1>{0:U(<:L{LU<,*LU):U>1b+I%},}*}fI,

Takip edilecek kod genişletme.


Önceki çözüm (61 bayt):

Lq~{:N2<{U):UaN{f+U1$0f=+}*a+}{{:X,(N%_!{X0=L+:L;}*},Lf-}?}/,

STDIN'den aşağıdaki gibi girdi alır:

[0 0 1 1 0 0 1 1 5 2 3 0 0 1 1 0 0 1 1 3 4 0 0 1 1 2 1 1]

Çıktı STDOUT üzerindeki sayıdır:

8

Algoritma :

  • UEklenecek düğümün kimliğini depolayan bir artan değişkeni koruyun .
  • Her listenin, listenin ilk öğesi tarafından oluşturulan benzersiz bir kimliğe ve kalan öğelerin bağlı düğümlerin kimlikleri olduğu bir düğüm olduğu bir liste listesi bulundurun.
  • Her yinelemede (giriş yönergelerini okurken),
    • Yönerge ise 0, [U]bir listeye ekleyin
    • Yönerge ise 1, Uliste listesindeki her listeye ekleyin ve her liste listesinin ilk öğesinden oluşan başka bir liste ekleyin veU
    • Yönetmeliğin kaldırılması için, length - 1bölünebilir tüm listeleri filtreleyerek mve bu listelerin ilk öğesini not almaya devam ediyorum . Filtrelemeden sonra, kaldırılan tüm kimliği kalan kimlik listesinden kaldırırım.

Kod genişletme :

Lq~{:N2<{U):UaN{f+U1$0f=+}*a+}{{:X,(N%_!{X0=L+:L;}*},Lf-}?}/,
L                                            "Put an empty array on stack";
 q~                                          "Evaluate the input";
   {                                }/       "For each directive";
    :N                                       "Store the directive in N";
      2<{     ...    }{    ...    }?         "If directive is 0 or 1, run the first";
                                             "block, else second";
{U):UaN{f+U1$0f=+}*a+}
 U):U                                        "Increment and update U (initially 0)";
     a                                       "Wrap it in an array";
      N{         }*                          "Run this block if directive is 1";
        f+                                   "Add U to each list in list of list";
          U1$                                "Put U and list of lists on stack";
             0f=                             "Get first element of each list";
                +                            "Prepend U to the above array";
                   a+                        "Wrap in array and append to list of list";
{{:X,(N%_!{X0=L+:L;}*},Lf-}
 {                   },                      "Filter the list of list on this block";
  :X,(                                       "Get number of connections of this node";
      N%_                                    "mod with directive and copy the result";
         !{        }*                        "If the mod is 0, run this block";
           X0=                               "Get the id of this node";
              L+:L;                          "Add to variable L and update L";
                       Lf-                   "Remove all the filtered out ids from the";
                                             "remaining nodes";
,                                            "After the whole process is completed for"
                                             "all directives, take length of remaining ";
                                             "nodes in the list of list";

Burada deneyin


3

Pyth, 88 80 75 karakter

JYFHQI!H~Y]]lY)IqH1=Y+m+dlYY]UhlY)VYI&Hq%l@YNH1~J]N))=Ymf!}TJ@YkUlYY;-lYl{J

Bitirdim. Belki başka birinin golf ipuçları var.

Ygrafiğin bitişik listesidir. Golf nedenleriyle, düğüm silindikten sonra bile bu listede bir düğüm tutuyorum (Aksi takdirde tüm indeksleri güncellemem gerekir). Her düğümün komşu olarak kendisi vardır. Liste J, silinen düğümlerin kaydını tutar.

Örnek girişte bitişiklik listesindeki değişiklikleri gösteririm [0,1,0,1,0,1,3]:

giriş 0: Y = [[0]] J = []
giriş 1: Y = [[0,1], [0,1]] 0 J = []
girdi 0: Y = [[0,1], [0,1], [2]] J = []
girdi 1: Y = [[0,1,3], [0,1,3], [2,3], [0,1,2,3]] J = []
girdi 0: Y = [[0,1,3], [0,1,3], [2,3], [0,1,2,3], [4]] J = []
girdi 1: Y = [[0,1,3,5], [0,1,3,5], [2,3,5], [0,1,2,3,5], [4,5 ], [0,1,2,3,4,5]] J = []
girdi 3: Y = [[3,5], [3,5], [2,3,5], [2,3,5], [4,5], [2,3,4,5]] J = [0,1]

Bu durumda algoritma oldukça basittir: input == 0 ise, tüm girdilerin üzerinde yineleme: komşu olarak kendisiyle yeni bir düğüm ekleyin, input == 1 ise: tüm düğümlerin komşu (ayrıca silinenler) olduğu yeni bir düğüm ekleyin ve ekleyin giriş> 1 ise, bu düğüm tüm düğümlerin bitişiklik listesine: # neighbor-1% input == 0 olan düğümleri belirleyin ve bunları Jher durumda kullanarak her düğümün komşularına güncelleyin J. Sonunda Yeksi uzunluğu (set) uzunluğunu yazdırın J.

JYFHQI!H~Y]]lY)IqH1=Y+m+dlYY]UhlY)VYI&Hq%l@YNH1~J]N))=Ymf!}TJ@YkUlYY;-lYl{J
JY                      set J=[]
  FHQ                   for H in: input()
I!H      )                if H==0:
   ~Y]]lY                   Y.append([len(Y)])
IqH1              )       if H==1:
    =Y+                     Y=                 +
       m+dlYY                 old nodes updated
             ]UhlY                              new node with all neighbors
VY                )       for N in range(len(Q)):
  I&Hq%l@YNH1    )          if H>0 and len(Y[N])%H==1:
             ~J]N             J.append(N) //this node gets deleted
=Ym           Y           Y=[           for k in Y]
   f!}TJ@YkUlY               k-filtered  //all items of J are removed
;                       end input for loop
-lYl{J                  print len(Y) - len(set(J))

kullanım

Sadece komut dosyasını arayın ve girdi [0,1,0,1,0,1,3]veya başka bir test durumu olarak verin.


3

2

Python 2, 296

s=input();e=[];n=[];c=0
for t in s:
    if t<2:e=e+[[]]if t==0 else [x+[c]for x in e]+[n[:]];n+=[c];c+=1
    else:
        M=zip(*[(i,n[i])for i,x in enumerate(e)if not len(x)%t])
        if M:e=[list(set(z)-set(M[1]))for j,z in enumerate(e)if j not in M[0]];n=list(set(n)-set(M[1]))
print len(n)

Her düğüme benzersiz bir kimlik verilir ve her düğümün komşu kimlikleri kaydedilir. Yönerge 0 olduğunda, yeni düğüm için boş bir komşu listesi eklenir. Yönerge 1 olduğunda, mevcut tüm düğümlerin kimlikleri yeni düğümün komşu listesi haline gelir ve diğer tüm komşu listeleri yeni düğüm kimliğini içerecek şekilde güncellenir. M> 1 için, m'nin katları olan komşu listelere sahip düğümler düğüm listesinden ve tüm komşu listelerinden kaldırılır. Önceki bir sürümde bir hata yakalamak için @Optimizer'a teşekkürler.


2

NetLogo, 160

to f[t]foreach t[if ? = 0[crt 1]if ? = 1[crt 1[create-links-with other turtles]]if ? > 1[ask turtles with[count my-links mod ? = 0][die]]]show count turtles
end

Uygulama basittir, her sembolü okur ve uygun eylemi gerçekleştirir.

to f[t]
  foreach t [
    if ? = 0 [
      crt 1
    ]
    if ? = 1 [
      crt 1 [create-links-with other turtles]
    ]
    if ? > 1 [
      ask turtles with [count my-links mod ? = 0] [die]
    ]
  ]
  show count turtles
end

Komut satırından olarak çalıştırabilirsiniz f[0 0 1 1 0 0 1 1 2 5 7 0 1].


2

Ruby 159157 ( demo )

N=Struct.new:l
G=->c{n=[]
c.map{|m|m<1?n<<N.new([]):m<2?(w=N.new([])
n.map{|x|x.l<<w;w.l<<x}
n<<w):(n-=r=n.select{|x|x.l.size%m<1}
n.map{|x|x.l-=r})}
n.size}

Bu, Gstabby-lambda sözdizimi kullanılarak adlandırılan bir işlevi tanımlar . Kullanım G[[0, 1]]komutlarla aramak0Ve1 .

Uygulama oldukça basittir: özellik aracılığıyla tüm bağlantılı düğümlere referansları tutan bir Nodeyapı ( Nyukarıda adı geçen) vardır l. Ggerektiğinde düğümler oluşturur ve bağlantılarını değiştirir. Bir okunabilir sürümü mevcut burada .


1

CJam, 99 97 bayt

Lal~{I2<{_0={{If+z}2*));0+a+}{;Iaa}?}{_0=!!{{{_:+I%+}%z}2*));1+a+{{W=},z}2*);z_{);}{a}?}*}?}fI0=,

Bu konuda hala golf oynayacak çok şey var. Algoritma, bitişiklik matrisini takip etmeye dayanır, ancak boş matrisi özel olarak tedavi etmek zorunda kalmadan temsil etmek bana baş ağrısı verir.

Burada test edin.

Giriş, CJam tarzı bir dizidir:

[0 0 1 1 0 0 1 1 2 5 7 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 8]

Bu test kayışını tüm testleri çalıştırmak için kullanabilirsiniz:

"[]
[5]
[0,0,0,11]
[0,1,0,1,0,1,3]
[0,0,0,1,1,1]
[0,0,1,1,0,0,1,1,2,5,7,0,1]
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2]
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1]
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8]"

","SerN/{
La\~{I2<{_0={{If+z}2*));0+a+}{;Iaa}?}{_0=!!{{{_:+I%+}%z}2*));1+a+{{W=},z}2*);z_{);}{a}?}*}?}fI0=,
N}/

1

Python 2, 174

l=input()
g={}
n=0
for x in l:
 n+=1;g[n]=set()
 if x>1:h={i for i in g if len(g[i])%x};g={i:g[i]&h for i in set(g)&h}
 if x==1:
  for i in g:g[i]^={n};g[n]^={i}
print len(g)

Bu muhtemelen hala çok golf olabilir.

Sözlük kullandım gGrafiği temsil . Düğümler sayılarla etiketlenir ve bitişik düğüm kümesiyle eşlenirler. Bu, bir kenarın her güncellemesinin her iki uç noktasında yürütülmesi gerektiği anlamına gelir.

Yeni düğüm indeksleri sayılarak oluşturulur n. Her seferinde yeni bir boş düğüm oluşturuyorum n. Komuta 0için kalır. Komut için 1, birbirine düğüm yoluyla bağlanır g[i]^={n};g[n]^={i}; xor kullanarak düğümün kendisine bağlı olmaması gerekir. > 1 komutları için hemen silinir.

Derecesi bir kat olan düğümlerin filtrelenmesi önce kalan ( h) düğümleri bularak, düğümlerin andlistesi ve her düğümün komşuları ile yapılır.

Son olarak, grafik sözlüğündeki girişlerin sayısı cevaptır.


0

Mathematica, 223 bayt

Vay canına, bu beklediğimden daha uzun oldu.

f=(g={};t=Append;l=Length;m=ListQ;h=Flatten;k=Position;o=If;(d=#;o[d==0,g=g~t~{},o[d==1,g=o[m@#,t[#,l@g+1],#]&/@g;g=t[g,h@k[g,_?m,1]],g=o[l@#~Mod~d==0,0,#]&/@g;p=h@k[g,0];(c=#;g=#~DeleteCases~c&/@g)&/@p]])&/@#;g~Count~_?m)&

Kullanımı:

f@{0, 1, 0, 1, 0, 1, 3}

İşte test senaryolarının sonuçları:

f /@ {
  {},
  {5},
  {0, 0, 0, 11},
  {0, 1, 0, 1, 0, 1, 3},
  {0, 0, 0, 1, 1, 1},
  {0, 0, 1, 1, 0, 0, 1, 1, 2, 5, 7, 0, 1},
  {0, 0, 1, 1, 1, 1, 5, 1, 4, 3, 1, 0, 0, 0, 1, 2},
  {0, 0, 1, 1, 0, 0, 1, 1, 5, 2, 3, 0, 0, 1, 1, 0, 0, 1, 1, 3, 4, 0, 0, 1, 1, 2, 1, 1},
  {0, 0, 1, 1, 0, 0, 1, 1, 2, 5, 7, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 8}
}

Out: {0, 0, 0, 4, 6, 6, 6, 8, 14}

Daha az golf:

f = (
   a = #;
   g = {};
   Table[
    If[a[[n]] == 0,
     AppendTo[g, {}],
     If[a[[n]] == 1,
      g = If[ListQ@#, Append[#, Length@g + 1], #] & /@ g; 
      g = Append[g, Flatten@Position[g, _?ListQ, 1]],
      If[a[[n]] > 1,
       g = If[Mod[Length@#, a[[n]]] == 0, 0, #] & /@ g;
       p = Flatten@Position[g, 0];
       (c = #; g = DeleteCases[#, c] & /@ g) & /@ p
       ]
      ]
     ],
    {n, Length@a}];
   Count[g, _?ListQ]
   ) &

Bunun çalışma şekli grafiği "komşuların listesi" listesi olarak göstermektir.
İçin 0 direktifi, sadece boş bir liste ekleyin.
İçin 1 direktifi, tüm önceki düğümler bir listesini ekler ve önceki tüm düğümlere yeni bir düğüm ekleyin. > 1
yönergesi için belirtilen düğümleri kaldırdım ve gerisini güncelledim.

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.