计算长度为n的莫比乌斯梯子上的受限森林数量


13

OEIS序列A020872Möbius梯 M n上的限制林进行计数。

挑战

面临的挑战是编写一个程序,该程序将整数作为输入n > 1并返回A020872(n)Möbius梯子M n上的受限林。这是,因此最短的代码获胜。(别有用心的是也许将此序列的长度延长一点。)

定义

受限森林是图的一个分区,使得每个部分可以是一个(无向)路径或分离的顶点。

所述莫比乌斯梯子中号Ñ是可以想到的2n边形与所有相对顶点之间画出的对角线的曲线图。

这是M 2(画有对角线的正方形)上的34个受限森林。请注意,第一个图被划分为四个孤立的顶点,第二个图被划分为一个路径和两个孤立的顶点,依此类推。 A020872(2)


1
测试用例从2到12: 34, 241, 1582, 10204, 65197, 415076, 2638366, 16759249, 106427154, 675771276, 4290678337。我不确定为什么1也不需要输入和输出2
彼得·泰勒

@PeterTaylor,感谢您将这些条款添加到OEIS!1由于Wikipedia文章中未明确定义M_1,因此我排除了输入。(特别是,它具有多个边或不是三次图。)
Peter Kagey

1
实际上,这听起来像是fastest-codefastest-algorithm挑战的理想人选。
mypetlion

1
进一步的测试案例(生成代码):13至17是27242281044, 172964658642, 1098170541121, 6972388689086, 44268329738124
Peter Taylor

1
是的,我认为您的别有用心远不止于此。
彼得·泰勒

Answers:


10

果酱(58 56个字符)

有些字符无法打印,其中一个是选项卡,它将由StackExchange软件破坏:

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

在线演示。这将在大约三秒钟内在线运行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=

说明

莫比乌斯梯子基本上是具有两个额外边缘的梯子。给定梯子上的限制林,可以将其提升到莫比乌斯梯子上的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它崩溃了,但是由于OP选择将这种情况排除在要求之外,所以这不是根本问题。

解剖

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

的JavaScript(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,但是对于更大的数字则超时。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.