反向工程师支架矩形


24

每个程序员都知道矩形真的很有趣。为了加剧这种乐趣,可以将这些可爱而模糊的图表转换为交织在一起的括号组。

这个挑战与我以前的挑战相反。

假设您有一组互锁的矩形,如下所示:

   +------------+
   |            |
+--+-+     +----+-+
|  | |     |    | |
|  | | +---+--+ | |
|  | | |   |  | | |
+--+-+ | +-+--+-+-+-+
   |   | | |  | | | |
   |   | | |  | | | |
   |   | | |  | | | |    +-+
   |   +-+-+--+ | | |    | |
   |     | |    | | |  +-+-+-+
   +-----+-+----+ | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

附加条款:

  • 不会有两个+相邻
  • 没有两个矩形共享边或角
  • 每列最多只能有一个垂直边缘

第一步是查看任何矩形的最左边。将其指定为四种括号类型之一({[<。我选择[

   +------------+
   |            |
[--+-]     +----+-+
[  | ]     |    | |
[  | ] +---+--+ | |
[  | ] |   |  | | |
[--+-] | +-+--+-+-+-+
   |   | | |  | | | |
   |   | | |  | | | |
   |   | | |  | | | |    +-+
   |   +-+-+--+ | | |    | |
   |     | |    | | |  +-+-+-+
   +-----+-+----+ | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

现在看第二个最左边的矩形。由于它与[矩形重叠,因此必须为其他类型。我选择(

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] +---+--+ ) |
[  ( ] |   |  | ) |
[--(-] | +-+--+-)-+-+
   (   | | |  | ) | |
   (   | | |  | ) | |
   (   | | |  | ) | |    +-+
   (   +-+-+--+ ) | |    | |
   (     | |    ) | |  +-+-+-+
   (-----+-+----) | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

下一个最左边的矩形不与任何前一个矩形相交,但嵌套在前一个矩形内。我选择(再次分配它。通常,如果可能的话,最好为矩形分配与其内部嵌套的矩形相同的类型,但是有时需要回溯。

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] (---+--) ) |
[  ( ] (   |  ) ) |
[--(-] ( +-+--)-)-+-+
   (   ( | |  ) ) | |
   (   ( | |  ) ) | |
   (   ( | |  ) ) | |    +-+
   (   (-+-+--) ) | |    | |
   (     | |    ) | |  +-+-+-+
   (-----+-+----) | |  | | | |
         | |      | |  | +-+ |
         | +------+ |  |     |
         |          |  |     |
         +----------+  +-----+

可以[再次分配下一个矩形。

   (------------)
   (            )
[--(-]     +----)-+
[  ( ]     |    ) |
[  ( ] (---+--) ) |
[  ( ] (   |  ) ) |
[--(-] ( [-+--)-)-+-]
   (   ( [ |  ) ) | ]
   (   ( [ |  ) ) | ]
   (   ( [ |  ) ) | ]    +-+
   (   (-[-+--) ) | ]    | |
   (     [ |    ) | ]  +-+-+-+
   (-----[-+----) | ]  | | | |
         [ |      | ]  | +-+ |
         [ +------+ ]  |     |
         [          ]  |     |
         [----------]  +-----+

下一个矩形有点有趣。它与a (和一个[矩形相交,所以我可以称其为{矩形(或者<没有人喜欢它们)。

   (------------)
   (            )
[--(-]     {----)-}
[  ( ]     {    ) }
[  ( ] (---{--) ) }
[  ( ] (   {  ) ) }
[--(-] ( [-{--)-)-}-]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]    +-+
   (   (-[-{--) ) } ]    | |
   (     [ {    ) } ]  +-+-+-+
   (-----[-{----) } ]  | | | |
         [ {      } ]  | +-+ |
         [ {------} ]  |     |
         [          ]  |     |
         [----------]  +-----+

最后两个矩形还不错。它们可以是任何两种不同的类型。

   (------------)
   (            )
[--(-]     {----)-}
[  ( ]     {    ) }
[  ( ] (---{--) ) }
[  ( ] (   {  ) ) }
[--(-] ( [-{--)-)-}-]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]
   (   ( [ {  ) ) } ]    {-}
   (   (-[-{--) ) } ]    { }
   (     [ {    ) } ]  <-{-}->
   (-----[-{----) } ]  < { } >
         [ {      } ]  < {-} >
         [ {------} ]  <     >
         [          ]  <     >
         [----------]  <----->

读完这些矩形,我得到了[(]([{))}]<{}> 这将是上述输入的一种可能的输出。以下列出了许多可能的选项,但并不详尽:

[(]([{))}]<{}>
<(>(<{))}>{()}
{<}[{(]>)}[<>]
any of the 4! permutations of ([{<, you get the idea...

输入项

ASCII矩形,前提是它们是明确的(请参见上面的注释),并且可以正确地转换为方括号。您可以假设没有尾随空格或使用可选的尾随换行符将其填充为矩形。不会有任何前导空格。

输出量

遵守矩形相交限制的任何有效括号字符串。除可选的尾随换行符外,除方括号外不应有其他字符。主要规则是,如果两个正方形相交,则应为其分配不同的括号类型。

目标

这是代码质量,(数量)超过质量。


3
仅供参考,“加剧”的意思是“使一件坏事变得更糟”。
Paul R

@PaulR我相信这就是重点

哦,好吧,很明显无论它指向哪一点!
Paul R

我们可以假设每个矩形都有一定的高度吗? +的左上角不能有一个,然后它的左下角(紧邻下面)+没有?
Tersosauros's

Answers:


2

Python 3,519字节

def c(i):
 a,b,c,d={},0,[],{}
 for e in map("".join,zip(*i.split("\n"))):
  if"+"in e:
   f=e.index("+"),e.rindex("+")
   if f in a:j=a.pop(f);d[j]=f+(d[j],len(c));c.append(j)
   else:a[f]=b;d[b]=len(c);c.append(b);b+=1
 g,h={},0
 while d:
  i={list(d)[0]};
  for j,(k,l,m,n)in d.items():
   for(o,p,q,r)in(d[v]for v in i):
    if not(m>r or n<q or k>p or l<o or(q<m<n<r and o<k>l<p)):break
   else:i.add(j)
  for j in i:del d[j];g[j]=h
  h+=1
 s,u=set(),""
 for t in c:u+="[{(<]})>"[g[t]+4*(t in s)];s.add(t)
 return u

这是解决方案的首次尝试。所使用的算法纯粹是看图中的角,滥用了事实,即一列中只能出现一条垂直线,因此,列中的第一个和最后一个+必须是矩形的角。然后,它收集所有矩形并对无冲突组进行幼稚(有些不确定)的搜索。我不确定这是否总能找到最佳解决方案,但它适用于我到目前为止尝试过的所有示例。另外,也可以用蛮力搜索来搜索最少的组。

输入:包含ascii art的字符串。没有尾随换行符,并且所有行都必须使用空格填充为相同的长度。如果您只看角落,也可以不放置任何|或-,这也是完全可以的。

由于打高尔夫球很简单(大多数情况下只是空白最小化和变量重命名),它可能会更短一些,但是由于没有其他答案,我现在将其保留。


您会得到赏金,因为在不到1天的时间内我没有其他任何答案。感谢您的回答,继续打高尔夫球!
Rɪᴋᴇʀ
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.