N uzunluğundaki Möbius merdiveni üzerindeki sınırlı orman sayısını saymak


13

OEIS dizisi A020872 , Möbius merdiveni M n üzerindeki kısıtlanmış orman sayısını sayar .

Meydan okuma

Zorluk, bir tamsayı girdi olarak alan ve Möbius merdiveni M n üzerindeki kısıtlı ormanların sayısını n > 1döndüren bir program yazmaktır . Bu , bu yüzden en kısa kod kazanır. (Bir ön neden belki de bu dizinin uzunluğunu biraz uzatmaktır.)A020872(n)

Tanımlar

Bir sınırlı orman her bölüm bir (yönlendirilmeyen) ya olduğu şekilde grafik bir bölümü olan bir yol ya da izole edilmiş bir tepe noktası.

Möbiüs merdiven M n 2n-gon tüm karşıt uçları arasında çizilmiş çapraz olan düşünülebilir bir grafiktir.

Misal

Burada M 34 kısıtlı ormanlar 2 (çizilmiş çapraz olan bir kare). İlk grafiğin dört izole köşeye bölündüğüne, ikincisinin bir yola ve iki izole köşeye, vb. Ayrıldığına dikkat edin. A020872 (2)


1
2 ile 12 test durumları: 34, 241, 1582, 10204, 65197, 415076, 2638366, 16759249, 106427154, 675771276, 4290678337. 1Çıktı ile neden girişin gerekli olmadığından emin değilim 2.
Peter Taylor

@PeterTaylor, OEIS'e bu şartları eklediğiniz için teşekkür ederiz! 1M_1 Wikipedia makalesinde açıkça tanımlanmadığı için girişi hariç tuttum . (Özellikle, birden fazla kenarı vardır veya kübik bir grafik değildir.)
Peter Kagey

1
Bu aslında bir fastest-codeya da fastest-algorithmmeydan okuma için iyi bir aday gibi geliyor .
mypetlion

1
Diğer test senaryoları ( üretim kodu ): 13 ila 1727242281044, 172964658642, 1098170541121, 6972388689086, 44268329738124
Peter Taylor

1
Doğru, sanırım ön nedeniniz tatmin edici değil.
Peter Taylor

Yanıtlar:


10

CJam ( 58 56 karakter)

Bazı karakterler yazdırılamaz ve biri StackExchange yazılımı tarafından yönetilecek bir sekmedir:

"¶3¬î¿Á·    7ÛÈmÈÚÚ¡"256b454b212f-{__W%.*A<1b+}qi*-4=

Çevrimiçi demo . Bu, yaklaşık üç saniye içinde n = 400 için çevrimiçi olarak çalışacaktır.

Kodlayan xxd:

0000000: 22b6 0233 93ac eebf c1b7 0609 3794 dbc8  "..3........7...
0000010: 6dc8 1015 dada a122 3235 3662 3435 3462  m......"256b454b
0000020: 3231 3266 2d7b 5f5f 5725 2e2a 413c 3162  212f-{__W%.*A<1b
0000030: 2b7d 7169 2a2d 343d                      +}qi*-4=

açıklama

Möbius merdiveni temel olarak iki ekstra kenarı olan bir merdivendir. Merdiven üzerindeki sınırlı bir orman göz önüne alındığında, Möbius merdivenindeki 1 ile 4 arası sınırlı ormana kaldırılabilir. Kenarlar, derece 3 tepe noktası veya döngü oluşturmadığı sürece eklenebilir. Dört köşenin dereceleri ve ara bağlantıları merdiven üzerinde 116 sınıf sınırlı orman oluşturur, ancak bazıları dikdörtgenin simetrileri nedeniyle eşdeğerdir. N uzunluğundaki bir merdivenin n + 1 uzunluğundaki uzantılarını analiz etmek için bir program yazdım ve daha sonra sınıfları 26 denklik sınıfıyla birleştirdim. Bu kapalı bir form verir

[1111]T[1220121123410010]n2[0100]+

[221111122]T[211111111101001010002010000001010000000100001110000011001000011322112142000100002]n2[002200000]+

[1244113222344]T[0001000000100020010000000001201101101111004003002000000000001021001000000000111001002001000012000010001201001000000000002002001000000000000010000000000102200230110210124]n2[1011201000121]

bu nedenle değerler üç doğrusal yineleme alarak ve sonra bunları ekleyerek hızlı bir şekilde hesaplanabilir, ancak bu çok golf gibi görünmüyor.

Bununla birlikte, çeşitli karakteristik polinomların indirgenemez faktörlerini alır ve her birinden birini çoğaltırsak (çokluğu görmezden gelirsek), çalışan bir lineer nüks veren 10 derecelik bir polinom elde ederiz.

Yapıcı yaklaşım (58 karakter)

qi:Q2*,Wa*e!{Wa/{_W%e<}%$}%_&{{,1>},2few:~{:-z(Q(%}%0-!},,

Çevrimiçi demo . Sorunsuz bir şekilde n=2ve n=3biraz sabırla çevrimiçi olarak çalışacaktır . İçin n=1bunun çöküyor, ama OP gereklerinden çantayı dışlamak seçmiştir çünkü temel bir sorun değil.

teşrih

qi:Q          e# Take input from stdin, parse to int, store in Q
2*,Wa*e!      e# Take all permutations of (0, -1, 1, -1, 2, -1, ..., -1, 2*Q-1)
{             e# Map to canonical form...
  Wa/         e#   Split around the -1s
  {_W%e<}%    e#   Reverse paths where necessary to get a canonical form
  $           e#   Sort paths
}%
_&            e# Filter to distinct path sets
{             e# Filter to path sets with valid paths:
  {,1>},      e#   Ignore paths with fewer than two elements (can't be invalid; break 2ew)
  2few:~      e#   Break paths into their edges
  {:-z(Q(%}%  e#   The difference between the endpoints of an edge should be +/-1 or Q (mod 2Q)
              e#   So their absolute values should be 1, Q, 2Q-1.
              e#   d => (abs(d)-1) % (Q-1) maps those differences, and no other possible ones, to 0
              e#   NB {:-zQ(%}% to map them all to 1 would save a byte, but wouldn't work for Q=2
  0-!         e#   Test that all values obtained are 0
},
,             e# Count the filtered distinct path sets

Daha verimli bir sürüm 98 bayt alır:

qi2*:Q{a{__0=[1Q2/Q(]f+Qf%_&1$-\f{+E}~}:E~}/]{_W%>!},:MW=0{_{M\f{__3$_@&@:e<@|^{=}{^j}?}1b}{,)}?}j

Çevrimiçi demo

Bu, önce derinlik aramasıyla olası yolları oluşturur, daha sonra belirli bir köşe kümesi için olası kısıtlı ormanları sayan not edilmiş bir işlev kullanır. İşlev, belirli bir boş olmayan köşe kümesi için herhangi bir sınırlı ormanın en küçük tepe noktasını içeren bir yoldan ve o yolda olmayan köşe noktalarını kapsayan sınırlı bir ormandan oluşması temelinde yinelemeli olarak çalışır.


Izgara grafiğinde, bu doğrusal bir özyineleme ile tanımlanabilir, bu yüzden bunun güzel olduğunu bulmak beni şaşırtmaz.
Peter Kagey

6

JavaScript (ES6),  160 158  146 bayt

n=>(g=(e,v,p)=>[...Array(N=2*n),N-1,1,n].reduce((s,x,i)=>(m=1<<(x=i<N?i:(p+x)%N))&v?s:s+g((i>=N)/p?[...e,1<<p|m]:e,v|m,x),g[e.sort()]^(g[e]=1)))``

Çevrimiçi deneyin!

Notlar:

  • Bu oldukça verimsizdir ve için TIO'da zaman aşımı olacaktır .n>4
  • a(5)=10204 , dizüstü bilgisayarımda 3 dakikadan az bir süre içinde bulundu.

Yorumlananlar

n => (                        // n = input
  g = (                       // g = recursive function taking:
    e,                        //   e[] = array holding visited edges
    v,                        //   v   = bitmask holding visited vertices
    p                         //   p   = previous vertex
  ) =>                        // we iterate over an array of N + 3 entries, where N = 2n:
    [ ...Array(N = 2 * n),    //   - 0...N-1: each vertex of the N-gon (starting points)
      N - 1,                  //   - N      : previous vertex \
      1,                      //   - N+1    : next vertex      }-- connected to p
      n                       //   - N+2    : opposite vertex /
    ].reduce((s, x, i) =>     // reduce() loop with s = accumulator, x = vertex, i = index:
      ( m = 1 << (            //   m is a bitmask where only the x-th bit is set
          x = i < N           //   and x is either:
              ? i             //   - i if i < N
              : (p + x) % N   //   - or (p + x) mod N otherwise
      )) & v ?                //   if this vertex was already visited:
        s                     //     leave s unchanged
      :                       //   else:
        s +                   //     add to s
        g(                    //     the result of a recursive call:
          (i >= N) / p ?      //       if p and x are connected (i >= N and p is defined):
            [ ...e,           //         append to e[]:
              1 << p | m      //           the edge formed by p and x
            ]                 //           and uniquely identified by 1 << p | 1 << x
          :                   //       else:
            e,                //         leave e[] unchanged
          v | m,              //       mark the vertex x as visited
          x                   //       previous vertex = x
        ),                    //     end of recursive call
      g[e.sort()] ^           //   sort the edges and yield 1 if this list of edges has not
      (g[e] = 1)              //   already been encountered; either way, save it in g
    )                         // end of reduce()
)``                           // initial call to g with e = ['']

2

Jöle , 61 58 bayt

®R,³;Ø+
Ḥ©Ḷµ1ị+¢%®ḟ€;€€1¦-Ẏ;€)Ẏ$ƬẎṣ€-Ẉ’ẠƊƇU¹Ø.ị>/Ɗ?€€Ṣ€QL‘

Çevrimiçi deneyin!

Bu daha kısa versiyon; algoritmik karmaşıklık ve hıza karşı daha kısa uzunluk için optimize edilmiştir.

Jöle , 85 bayt

%®ḟ
1ị+³;Ø+¤ç,1ị+®_3¤R‘¤Ʋç;€-Ʋ“”2ị>-Ʋ?Ẏ;€
Ḥ©Ḷ;€-Ç€Ẏ$ƬẎṣ€-Ẉ=1ẸƊÐḟU¹1ị>0ị$Ʋ?€€Ṣ€QL‘+=2$

Çevrimiçi deneyin!

Gereksiz yolları denemek için ekstra kod ekleyen daha uzun bir sürüm. Sonunda n = 2 denetimi, örnekte kırmızı / mavi haç gibi görünen ve bu kod tarafından oluşturulmayan n = 2 için özel durumla başa çıkmaktır. Bu ikinci sürüm n = 4'ü TIO'da 13 saniyeden daha kısa sürede tamamladı, ancak daha yüksek sayılar için zaman aşımına uğradı.

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.