行军广场查询


9

Marching Squares是计算机图形学中的一种算法,用于从样本网格中恢复2D等值线(有关3D设置,另请参见其兄长Marching Cubes)。想法是独立处理网格的每个像元,并根据其角处的值确定通过该像元的轮廓。

此过程的第一步是根据拐角是在轮廓值上方还是下方,确定轮廓连接哪些边缘。为简单起见,我们只考虑沿value的轮廓0,这样我们对拐角是正还是负感兴趣。有一些情况可以区分:24 = 16

在此处输入图片说明
图片来源:Wikipedia

白色和黑色的识别在这里并不重要,但是为了明确起见,请说白色为正,黑色为负。我们将忽略其中一个角正好是1的情况0

鞍点(案例5和案例10)提供了一些额外的困难:仅通过查看拐角并不清楚应该使用哪些对角线。这可以通过找到四个角的平均值(即中心值的近似值)并选择对角线以使轮廓将中心与带有相反符号的角分开来解决。如果平均值恰好是0,则可以选择任何一种情况。

通常,这16种情况仅存储在查找表中。这对于提高效率非常有用,但是当然,我们希望此处的代码简短。因此,您的任务是执行此查找步骤,并以尽可能少的代码打印出外壳的ASCII表示形式。

挑战

您将以选择的固定顺序获得四个角(非零整数)的值。然后,您应该生成轮廓的正确布局,以正确解决鞍点情况。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行自变量或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

输入可以采用任何方便的字符串或列表格式。

这16种情况将使用以下5x5块之一以ASCII艺术形式表示:

o---o  o---o  o---o
|   |  |   |  | | |
|   |  |---|  | | |
|   |  |   |  | | |
o---o  o---o  o---o

o---o  o---o  o---o  o---o
|/  |  |  \|  |   |  |   |
|   |  |   |  |   |  |   |
|   |  |   |  |\  |  |  /|
o---o  o---o  o---o  o---o

o---o  o---o
|/  |  |  \|
|   |  |   |
|  /|  |\  |
o---o  o---o

您不得打印任何开头或结尾的空格,但可以打印单个可选的换行符。

这是代码高尔夫球,因此最短的答案(以字节为单位)获胜。

测试用例

测试用例假定输入是按top-lefttop-rightbottom-leftbottom-right的顺序给出的。测试用例分为9组,一组对应于上面给出的9种表示形式(以相同的顺序,从空单元格开始,以两个鞍点结束)。

[1, 2, 1, 3]
[-9, -2, -2, -7]

[4, 5, -1, -2]
[-1, -2, 3, 4]

[7, -7, 7, -7]
[-5, 5, -5, 5]

[1, -6, -4, -1]
[-2, 3, 3, 4]

[-1, 6, -4, -1]
[2, -3, 3, 4]   

[-1, -6, 4, -1]
[2, 3, -3, 4]

[-1, -6, -4, 1]
[2, 3, 3, -4]

[3, -8, -9, 2]
[-3, 8, 9, -2]

[8, -3, -2, 9]
[-8, 3, 2, -9]

此外,以下测试用例可能会返回两个鞍点(您的选择):

[1, -4, -2, 5]
[-1, 4, 2, -5]

Answers:


4

红宝石,201 180 176

这是一个匿名lambda函数,将以非高尔夫示例中显示的方式调用。

这不包含任何变量s。在非高尔夫版本中,s为清晰起见,在使用之前会为其分配一个复杂的表达式。插入版本,高尔夫球版本将保存4个字节。版本之间的唯一其他区别是空格和注释。

如果可以接受以五个字符的五个字符串组成的数组形式返回输出,而不是将其打印到stdout,则可以再节省一个字节。

->a{p=t=0
4.times{|i|t+=a[i]*=a[3];p+=a[i]>>9&1<<i}
q=p==6&&t>0?19:'@AC@P*10'[p].ord
puts c='o---o',(0..2).map{|i|b=p*i==3?'|---|':'|   |';b[q%4]='|/|\|/'[q%4+(i&2)];q/=4;b},c}

我对数组的解析感到满意,但我认为可能会有更短的方法来形成输出。

输入数组的所有四个元素都与最后一个元素相乘。这样可以保证最后一个元素为正,并将案例数从16减少到8。将元素右移9位,以便所有正数变为0而所有负数变为-1(至少在输入范围内)然后1<<array index对它们进行“与”运算以给出表示该模式的3位二进制数(实际上是4位,但是由于最后一个元素始终为正,因此第4位始终为零。)

然后将从0..7开始的该数字输入到(叹气)查找表中,以确定每行的哪些字符为非空白字符。正是在这个阶段,处理了两个不同的鞍形显示,如果总和为正,则使用查找表中的数字替代(该问题表示要考虑“平均值”,但仅对标志感兴趣,我们是否考虑总数并不重要。)

希望通过代码中的注释可以清楚地显示输出的工作方式。

在测试程序中取消

f=->a{p=t=0
  4.times{|i|                      #for each number in the input
    t+=a[i]*=a[3];                   #multiply each number by a[3]; totalize the sum in t
    p+=a[i]>>9&1<<i                  #shift right to find if negative; AND with 1<<i to build index number for pattern 
  }                                #q is a 3-digit base 4 number indicating which character of each line is non-whitespace (if any). 
  q=p==6&&t>0?19:'@AC@P*10'[p].ord #It's encoded in the magic string, except for the case of saddles with a positive total, which is encoded by the number 19.
  s=(0..2).map{|i|                 #build an array of 3 strings, indexes 0..2
    b=p*i==3?'|---|':'|   |';        #IF p is 3 and we are on row 1, the string is |---| for the horizontal line case. ELSE it is |   |.
    b[q%4]='|/|\|/'[q%4+(i&2)];      #The numbers in q indicate which character is to be modified. The characters in the string indicate the character to replace with.
    q/=4;                            #If q%4=0, the initial | is replaced by | (no change.) i&2 shifts the string index appropriately for the last row.
    b                                #divide q by 4, and terminate the loop with the expression b so that this is the object loaded into array s.  
  }
puts c='o---o',s,c}                #print the array s, capped with "o---o" above and below.


[[1, 2, 1, 3],
[-9, -2, -2, -7],

[4, 5, -1, -2],
[-1, -2, 3, 4],

[7, -7, 7, -7],
[-5, 5, -5, 5],

[1, -6, -4, -1],
[-2, 3, 3, 4],

[-1, 6, -4, -1],
[2, -3, 3, 4],

[-1, -6, 4, -1],
[2, 3, -3, 4],

[-1, -6, -4, 1],
[2, 3, 3, -4],

[3, -8, -9, 2],
[-3, 8, 9, -2],

[8, -3, -2, 9],
[-8, 3, 2, -9],

[1, -4, -2, 5],
[-1, 4, 2, -5]].each{|k|f.call(k)}
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.