Đếm số lượng rừng bị hạn chế trên thang Mobius có chiều dài n


13

Trình tự OEIS A020872 đếm số lượng rừng bị hạn chế trên thang Möbius M n .

Các thách thức

Thách thức là viết một chương trình lấy một số nguyên làm đầu vào n > 1và trả về A020872(n), số lượng rừng bị hạn chế trên thang Möbius M n . Đây là , vì vậy mã ngắn nhất sẽ thắng. (Một động cơ thầm kín là có thể kéo dài độ dài của chuỗi này thêm một chút.)

Các định nghĩa

Một khu rừng bị hạn chế là một phân vùng của biểu đồ sao cho mỗi phần là một đường dẫn (không bị chặn) hoặc một đỉnh bị cô lập.

Các bậc thang Mobius M n là một đồ thị có thể được nghĩ đến 2n-gon với đường chéo rút ra giữa tất cả các đỉnh đối diện.

Thí dụ

Dưới đây là 34 khu rừng bị hạn chế trên M 2 (một hình vuông có đường chéo được vẽ). Lưu ý rằng đồ thị đầu tiên được phân vùng thành bốn đỉnh bị cô lập, thứ hai được phân vùng thành một đường dẫn và hai đỉnh bị cô lập, v.v. A020872 (2)


1
Các trường hợp thử nghiệm từ 2 đến 12 : 34, 241, 1582, 10204, 65197, 415076, 2638366, 16759249, 106427154, 675771276, 4290678337. Tôi không chắc tại sao đầu vào 1cũng không bắt buộc, với đầu ra 2.
Peter Taylor

@PeterTaylor, Cảm ơn bạn đã thêm các điều khoản đó vào OEIS! Tôi đã loại trừ đầu vào 1vì M_1 không được xác định rõ ràng trong bài viết Wikipedia. (Trong đó, một trong hai nó có nhiều cạnh hoặc nó không phải là một đồ thị khối.)
Peter Kagey

1
Điều này thực sự có vẻ như một ứng cử viên tốt cho một fastest-codehoặc fastest-algorithmthách thức.
mypetlion

1
Các trường hợp thử nghiệm khác ( mã thế hệ ): 13 đến 17 là27242281044, 172964658642, 1098170541121, 6972388689086, 44268329738124
Peter Taylor

1
Phải, tôi nghĩ động cơ thầm kín của bạn là nhiều hơn thỏa mãn.
Peter Taylor

Câu trả lời:


10

Camam 58 56 ký tự)

Một số ký tự không thể in được và một là một tab sẽ được xử lý bằng phần mềm StackExchange:

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

Bản demo trực tuyến . Điều này sẽ chạy trực tuyến với n = 400 trong khoảng ba giây.

Được mã hóa bởi 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=

Giải trình

Một thang Möbius về cơ bản là một cái thang có hai cạnh phụ. Với một khu rừng bị hạn chế trên một cái thang, nó có thể được nâng lên từ 1 đến 4 khu rừng bị hạn chế trên thang Mobius. Các cạnh có thể được thêm vào miễn là không tạo đỉnh 3 hoặc chu kỳ. Độ của bốn góc và các mối liên kết của chúng tạo thành 116 lớp rừng bị hạn chế trên thang, mặc dù một số trong số chúng là tương đương do tính đối xứng của hình chữ nhật. Tôi đã viết một chương trình để phân tích các phần mở rộng của một bậc thang có độ dài n đến một chiều dài n + 1, và sau đó hợp nhất các lớp thành 26 lớp tương đương. Điều này cho một hình thức đóng

[1111]T[1220121123410010]n-2[0100]+

[221111122]T[211111111101001010002010000001010000000100001110000011001000011322112142000100002]n-2[002200000]+

[1244113222344]T[0001000000100020010000000001201101101111004003002000000000001021001000000000111001002001000012000010001201001000000000002002001000000000000010000000000102200230110210124]n-2[1011201000121]

vì vậy các giá trị có thể được tính toán nhanh bằng cách thực hiện ba lần lặp lại tuyến tính và sau đó thêm chúng, nhưng điều này có vẻ không được hay lắm.

Tuy nhiên, nếu chúng ta lấy các yếu tố không thể thay đổi của các đa thức đặc trưng khác nhau và nhân với nhau một (bỏ qua bội số), chúng ta sẽ có một đa thức bậc 10 mang lại sự tái phát tuyến tính đơn lẻ.

Phương pháp xây dựng (58 ký tự)

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

Bản demo trực tuyến . Nó sẽ chạy trực tuyến n=2mà không có vấn đề và n=3với một chút kiên nhẫn. Đối với n=1nó gặp sự cố, nhưng vì OP đã chọn loại trừ trường hợp đó khỏi các yêu cầu nên nó không phải là vấn đề cơ bản.

Mổ xẻ

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

Một phiên bản hiệu quả hơn mất 98 byte:

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

Bản demo trực tuyến

Điều này xây dựng các đường dẫn có thể bằng cách tìm kiếm theo chiều sâu, sau đó sử dụng hàm ghi nhớ để đếm các khu rừng bị hạn chế có thể cho một tập hợp các đỉnh nhất định. Hàm này hoạt động đệ quy trên cơ sở rằng bất kỳ khu rừng bị hạn chế nào cho một tập hợp các đỉnh không trống nhất định bao gồm một đường dẫn chứa đỉnh nhỏ nhất và một khu rừng bị hạn chế bao phủ các đỉnh không nằm trong đường dẫn đó.


Trên biểu đồ lưới, điều này có thể được mô tả bằng đệ quy tuyến tính, vì vậy tôi sẽ không ngạc nhiên khi biết rằng điều này là tốt.
Peter Kagey

6

JavaScript (ES6),  160 158  146 byte

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

Hãy thử trực tuyến!

Ghi chú:

  • Điều này khá không hiệu quả và sẽ hết thời gian trên TIO cho n>4.
  • một(5)= =10204 đã được tìm thấy trong ít hơn 3 phút trên máy tính xách tay của tôi.

Đã bình luận

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

Thạch , 61 58 byte

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

Hãy thử trực tuyến!

Đây là phiên bản ngắn hơn; nó được tối ưu hóa cho chiều dài ngắn hơn so với độ phức tạp và tốc độ thuật toán.

Thạch , 85 byte

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

Hãy thử trực tuyến!

Đây là phiên bản dài hơn có thêm mã bổ sung để tránh thử các đường dẫn dư thừa. Việc kiểm tra n = 2 ở cuối là để đối phó với trường hợp cụ thể cho n = 2 trông giống như một chữ thập đỏ / xanh trong ví dụ và không được tạo bởi mã này. Phiên bản thứ hai này đã hoàn thành n = 4 trong chưa đầy 13 giây trên TIO, nhưng hết thời gian cho số lượng cao hơn.

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.