길이 n의 뫼비우스 사다리에서 제한된 숲 수 계산


13

OEIS 시퀀스 A020872Möbius 래더 M n 의 제한된 포리스트 수를 계산합니다 .

도전

과제는 정수를 입력 으로 받아 Möbius 래더 M n 에 제한된 포리스트 수를 n > 1반환 하는 프로그램을 작성하는 것 입니다. 이것은 이므로 가장 짧은 코드가 승리합니다. (이러한 동기는 아마도이 시퀀스의 길이를 조금 연장하는 것입니다.)A020872(n)

정의

제한된 숲 각 부분은 (방향성이) 중 어느 하나가되도록 그래프의 파티션 경로 또는 격리 정점.

뫼비우스 사다리 M은 N 2n 개의 곤 대향 모든 정점 잇는 대각선으로 간주 될 수있는 그래프이다.

다음은 M 2 에 34 개의 제한된 숲입니다 (대각선이 그려진 사각형). 첫 번째 그래프는 4 개의 분리 된 정점으로 분할되고 두 번째 그래프는 1 개의 경로와 2 개의 분리 된 정점 등으로 분할됩니다. A020872 (2)


1
2에서 12까지의 테스트 사례 : 34, 241, 1582, 10204, 65197, 415076, 2638366, 16759249, 106427154, 675771276, 4290678337. 1output과 함께 input 이 왜 필요 하지 않은지 잘 모르겠습니다 2.
피터 테일러

@PeterTaylor, OEIS에 해당 용어를 추가해 주셔서 감사합니다! 1Wikipedia 기사에 M_1이 명확하게 정의되어 있지 않기 때문에 입력을 제외했습니다 . (특히, 가장자리가 여러 개이거나 입방 그래프가 아닙니다.)
Peter Kagey

1
이 사실에 대한 좋은 후보처럼 소리 fastest-code또는 fastest-algorithm도전.
mypetlion

1
추가 테스트 사례 ( 생성 코드 ) : 27242281044, 172964658642, 1098170541121, 6972388689086, 44268329738124
Peter Taylor

1
맞습니다, 당신의 욕구 동기가 만족 스럽습니다.
Peter Taylor

답변:


10

CJam ( 58 56 문자)

일부 문자는 인쇄 할 수 없으며 하나는 StackExchange 소프트웨어에 의해 엉망이되는 탭입니다.

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

온라인 데모 . 약 3 초 안에 n = 400 동안 온라인으로 실행됩니다.

에 의해 인코딩 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=

설명

Möbius 사다리는 기본적으로 두 개의 추가 모서리가있는 사다리입니다. 사다리에 제한된 숲이 있으면 Möbius 사다리에있는 1에서 4 개의 제한된 숲으로 들어 올릴 수 있습니다. 3 도의 정점 또는주기를 생성하지 않는 경우 모서리를 추가 할 수 있습니다. 네 모서리의 각도와 그 상호 연결은 사다리에 116 클래스의 제한된 숲을 형성하지만 그 중 일부는 사각형의 대칭으로 인해 동일합니다. 나는 길이가 n 인 사다리의 길이를 길이가 n + 1 인 확장으로 분석하는 프로그램을 작성한 다음 클래스를 26 개의 등가 클래스로 병합했습니다. 이것은 닫힌 형태를 제공합니다

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

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

[1244113222344]T[0001000000100020010000000001201101101111004003002000000000001021001000000000111001002001000012000010001201001000000000002002001000000000000010000000000102200230110210124]n2[1011201000121]

따라서 세 번의 선형 반복을 수행 한 다음 값을 추가하여 값을 빠르게 계산할 수 있지만 이것은 골프처럼 보이지 않습니다.

그러나 다양한 특성 다항식의 돌이킬 수없는 요소를 취하고 각 요소 중 하나를 곱하면 (다중성을 무시 함) 10 차 다항식을 얻게됩니다.

건설적인 접근 (58 자)

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

온라인 데모 . 그것은 n=2문제없이 그리고 n=3약간의 인내심을 가지고 온라인으로 실행될 것입니다. 들어 n=1그 충돌, 영업 이익이 요구 사항에서이 경우를 제외하기로 한 이후로는 근본적인 문제가되지 않습니다.

해부

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

보다 효율적인 버전은 98 바이트를 사용합니다.

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

온라인 데모

깊이 우선 검색을 통해 가능한 경로를 만든 다음 지정된 정점 세트에 대해 가능한 제한된 포리스트를 계산하는 메모 기능을 사용합니다. 이 함수는 비어 있지 않은 정점 집합에 대한 제한된 포리스트가 가장 작은 정점을 포함하는 경로와 해당 경로에없는 정점을 포함하는 제한된 포리스트로 구성되어 있다는 점을 기반으로 재귀 적으로 작동합니다.


그리드 그래프에서 이것은 선형 재귀로 설명 할 수 있으므로 이것이 훌륭하다는 것을 알게 된 것은 놀라운 일이 아닙니다.
Peter Kagey

6

자바 스크립트 (ES6)  160 158  146 바이트

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

온라인으로 사용해보십시오!

노트:

  • 이것은 매우 비효율적이며 동안 TIO에서 시간 초과됩니다 .n>4
  • a(5)=10204 가 내 노트북에서 3 분 미만 내에 ​​발견되었습니다.

댓글

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

젤리 , 61 58 바이트

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

온라인으로 사용해보십시오!

이것은 더 짧은 버전입니다. 짧은 길이 대 알고리즘 복잡성 및 속도에 최적화되어 있습니다.

젤리 , 85 바이트

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

온라인으로 사용해보십시오!

중복 경로 시도를 피하기 위해 추가 코드를 추가하는 더 긴 버전이 있습니다. 마지막에 n = 2에 대한 검사는 예제에서 빨강 / 청색 십자가처럼 보이고이 코드에 의해 생성되지 않는 n = 2에 대한 특정 사례를 처리하는 것입니다. 이 두 번째 버전은 TIO에서 13 초 이내에 n = 4를 완료했지만 더 높은 숫자는 시간 초과됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.