完成网格填充曲折


18

网格填充曲折是一条封闭的路径,它至少访问一次N×N正方形网格的每个像元,从未与相邻像元之间的任何边缘交叉超过一次,也从未与自身相交。例如:

填充后,网格的每个单元格都可以由以下8个图块之一表示:

以这种方式编号,以上蜿蜒的图块可以通过以下矩阵表示:

5 6 5 6
4 8 3 2
5 7 6 2
4 3 4 3

给定一组不完整的图块,您的任务是完成网格填充曲折。例如,不完整的曲折:

...可以使用0s表示缺少的图块:

5 0 0 0 6
0 0 7 0 0
0 0 0 0 3
2 4 0 0 0
0 0 3 0 0

...可以这样完成:

...即:

5 6 5 1 6
4 8 7 6 2
5 7 7 7 3
2 4 8 8 6
4 1 3 4 3

技术指标

  • 输入将始终具有至少1且至多N2(非空)的瓷砖,其中2N7
  • 您可以使用任何一组值来表示图块,只要在答案中指定了该值即可。
  • 您的输入和输出可以采用任何格式和顺序,只要在答案中指定即可。
  • 对于所有输入,至少存在一个有效的解决方案(即,您不需要处理无效的输入)。
  • 适用标准I / O规则
  • 禁止出现标准漏洞
  • 鼓励甚至对“实用”语言进行解释。

测试用例

输入(Θ):

0 6
0 0

输出(Θ):

5 6
4 3

输入(Θ):

5 6 5 6
4 0 3 2
5 7 6 2
4 3 4 3

输出(Θ):

5 6 5 6
4 8 3 2
5 7 6 2
4 3 4 3

输入(Θ):

5 0 0 0 6
0 0 7 0 0
0 0 0 0 3
2 4 0 0 0
0 0 3 0 0

输出(Θ):

5 6 5 1 6
4 8 7 6 2
5 7 7 7 3
2 4 8 8 6
4 1 3 4 3


1
@Arnauld你是正确的;这是无效的。曲折是一条封闭的路径。
约旦

1
@Arnauld谢谢,我已经进行了更改。我没有意识到此站点上启用了MathJax!
约旦

Answers:


11

JavaScript(ES7), 236 ... 193185 字节

通过修改输入矩阵进行输出。

m=>(g=(d,x,y,v,r=m[y],h=_=>++r[x]<9?g(d,x,y,v)||h():r[x]=0)=>r&&1/(n=r[x])?x|y|!v?n?g(d='21100--13203-32-21030321'[n*28+d*3+7&31],x+--d%2,y+--d%2,v+=n<7||.5):h():!m[v**.5|0]:0)(0,0,0,0)

在线尝试!

(包括一些后处理代码,以矩阵形式和与OP提供的可视化工具兼容的平面列表形式打印结果)

结果

怎么样?

变数

gd(x,y)v

g

  • r

    r = m[y]
  • h18gg0

    h = _ => ++r[x] < 9 ? g(d, x, y, v) || h() : r[x] = 0

初步检查

n

r && 1 / (n = r[x]) ? ... ok ... : ... failed ...

(0,0)v>0

x | y | !v ? ... no ... : ... yes ...

现在,让我们假设我们还没有回到起点。

寻找道路

n0h

n0

ndd

d = '21100--13203-32-21030321'[n * 28 + d * 3 + 7 & 31]

最后8个条目无效并且被省略。其他4个无效条目用连字符明确标记。

作为参考,以下是挑战中提供的解码表,指南针和图块集:

   | 1 2 3 4 5 6 7 8
---+-----------------
 0 | 0 - - 1 3 - 3 1          1
 1 | - 1 - - 2 0 2 0        0 + 2
 2 | 2 - 1 - - 3 1 3          3
 3 | - 3 0 2 - - 0 2

g1/2v781

g(d, x + --d % 2, y + --d % 2, v += n < 7 || .5)

dxy

验证路径

(0,0)v>0

781/2v

v=N2v>N2v<N2kk=v

因此,JS代码:

!m[v ** .5 | 0]

格式化源

m => (
  g = (
    d,
    x, y,
    v,
    r = m[y],
    h = _ => ++r[x] < 9 ? g(d, x, y, v) || h() : r[x] = 0
  ) =>
    r && 1 / (n = r[x]) ?
      x | y | !v ?
        n ?
          g(
            d = '21100--13203-32-21030321'[n * 28 + d * 3 + 7 & 31],
            x + --d % 2,
            y + --d % 2,
            v += n < 7 || .5
          )
        :
          h()
      :
        !m[v ** .5 | 0]
    :
      0
)(0, 0, 0, 0)

辛苦了 我很想阅读代码的解释。
约旦

@Arna您是蛮力还是使用其他算法?
约拿

1
@Jonah我正在写一个解释。基本上,是的,这是一种蛮力的方法,但是一旦检测到一些不一致,算法就会回溯,而不是尝试每个可能的电路板。
Arnauld
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.