确定旋转矩形的尺寸


14

堆栈代码段在黑色背景上绘制了一个别名白色矩形,并为其尺寸,位置,角度和网格尺寸提供了参数:

<style>html *{font-family:Consolas,monospace}input{width:24pt;text-align:right;padding:1px}canvas{border:1px solid gray}</style><p>grid w:<input id='gw' type='text' value='60'> grid h:<input id='gh' type='text' value='34'> w:<input id='w' type='text' value='40'> h:<input id='h' type='text' value='24'> x:<input id='x' type='text' value='0'> y:<input id='y' type='text' value='0'> &theta;:<input id='t' type='text' value='12'>&deg; <button type='button' onclick='go()'>Go</button></p>Image<br><canvas id='c'>Canvas not supported</canvas><br>Text<br><textarea id='o' rows='36' cols='128'></textarea><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>function toCart(t,a,n,r){return{x:t-n/2,y:r/2-a}}function vtx(t,a,n){return{x:n.x+t*Math.cos(a),y:n.y+t*Math.sin(a)}}function sub(t,a){return{x:t.x-a.x,y:t.y-a.y}}function dot(t,a){return t.x*a.x+t.y*a.y}function inRect(t,a,n,r){var e=sub(a,t),o=sub(a,n),l=sub(a,r),i=dot(e,o),v=dot(e,l);return i>0&&i<dot(o,o)&&v>0&&v<dot(l,l)}function go(){var t=parseInt($("#gw").val()),a=parseInt($("#gh").val()),n=parseFloat($("#w").val()),r=parseFloat($("#h").val()),e={x:parseFloat($("#x").val()),y:parseFloat($("#y").val())},o=Math.PI*parseFloat($("#t").val())/180,l=Math.sqrt(n*n+r*r)/2,i=Math.atan2(r,n),v=vtx(l,o+i,e),h=vtx(l,o+Math.PI-i,e),u=vtx(l,o-i,e),x=$("#c");x.width(t).height(a).prop({width:t,height:a}),x=x[0].getContext("2d");for(var s="",c=0;a>c;c++){for(var f=0;t>f;f++)inRect(toCart(f+.5,c+.5,t,a),v,h,u)?(s+="..",x.fillStyle="white",x.fillRect(f,c,1,1)):(s+="XX",x.fillStyle="black",x.fillRect(f,c,1,1));a-1>c&&(s+="\n")}$("#o").val(s)}$(go)</script>
JSFiddle版本

文本表示形式XX在图像中的..任何地方都有黑色像素,而在白色的地方都有。(如果它们是X和,则看起来很混乱.。)

编写一个程序,该程序采用Snippet生成的矩形的文本表示形式,并输出该矩形的近似宽度和高度,两者均应在实际宽度和高度的±7%之内

您的程序应有效处理代码段可以绘制的所有可能的矩形,并具有以下约束:

  • 矩形的宽度和高度最小为24。
  • 网格宽度和高度最小为26。
  • 矩形永远不会触碰或超出网格边界。

因此,输入矩形可以具有任何旋转,位置和尺寸,并且网格可以具有任何尺寸,只要满足上述三个约束即可。请注意,除了网格尺寸外,Snippet参数可以是浮点型。

细节

  • 以原始文本矩形作为输入,或采用包含原始文本矩形的文件的文件名(通过stdin或命令行)。您可以假设文本矩形的末尾有换行符。
  • 你可以假设文本矩形从任意两个不同的制作可打印的ASCII比其他字符X.如果需要的话。(换行符必须保持换行符。)
  • 将测量的宽度和高度以整数或浮点数的形式输出到stdout(因为无法确定哪个参数实际与哪个参数一起使用)。任何格式,清楚地显示了两个维度是好的,例如D1 D2D1,D2D1\nD2(D1, D2),等。
  • 您可以编写一个函数来代替文本程序,该函数将文本矩形作为字符串或文件名,并正常打印结果,或者将其作为字符串或包含两个元素的列表/元组返回。
  • 请记住,XX或是..矩形的一个“像素”,而不是两个。

例子

例如 1个

参数:(grid w:60 grid h:34 w:40 h:24 x:0 y:0 θ:12代码段默认值)

输入值

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

输出示例

  • 40 24
  • 24 40
  • [40.0, 24.0]
  • 42.8, 25.68 (+ 7%)
  • 37.2, 22.32 (-7%)

例如 2

参数: grid w:55 grid h:40 w:24.5 h:24 x:-10.1 y:2 θ:38.5

输入值

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX..................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX................................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX..........XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

输出示例

  • 24.0 24.5
  • 25.68 26.215 (+ 7%)
  • 22.32 22.785 (-7%)

计分

以字节为单位的最短代码获胜。Tiebreaker是票数最高的职位。


解决方案不应该满足可接受的精度要求吗?对于某些输入值,您接受的值相差很远。
Reto Koradi 2015年

Answers:


6

Matlab,226个字节

这个想法很简单:首先,我尝试找出矩形被旋转了多少,然后相应地旋转图像,以使矩形直立。然后,我只是对行列中的所有像素进行“求和”,并尝试计算多少总和高于平均值(简单的阈值)来确定宽度和高度。这种简单的方法出奇地可靠地工作。

如何检测角度?

我只是尝试每个步骤(每个角度一个),然后沿列求和,得到和的向量。当矩形直立时,理想情况下,我应该只求和这个矢量的两个突然变化。如果正方形在尖端,则变化是非常缓慢的。因此,我只使用一阶导数,并尝试最小化“跳跃”的数量。在这里您可以看到我们试图最小化的标准图。请注意,您可以看到与四个可能的直立方向相对应的四个最小值。

最小化标准

进一步的想法:由于穷举角度搜索需要很多字符,因此我不确定可以打多少球,并且我怀疑您是否可以使用内置的优化方法来实现这一目标,因为您可以看到很多局部最小值我们不想要的。您可以通过选择较小的角度步长并仅搜索90°而不是360°来轻松提高精度(对于大图片),因此可以替换0:3600:.1:90类似的东西。但是无论如何,对我而言,挑战更多的是找到一种可靠的算法,而不是打高尔夫球,而且我确信打高尔夫球语言的输入将使我的论文远远落后于=)

PS:有人真的应该从Matlab / Octave中学到高尔夫语言。

产出

范例1:

 25    39

范例2:

 25    24

打高尔夫球:

s=input('');r=sum(s=='n');S=reshape(s',nnz(s)/r,r)';S=S(:,1:2:end-2)=='.';m=Inf;a=0;for d=0:360;v=sum(1-~diff(sum(imrotate(S,d))));if v<m;m=v;a=d;end;end;S=imrotate(S,a);x=sum(S);y=sum(S');disp([sum(x>mean(x)),sum(y>mean(y))])

取消高尔夫:

s=input('');
r=sum(s=='n');              
S=reshape(s',nnz(s)/r,r)'; 
S=S(:,1:2:end-2)=='.';    
m=Inf;a=0;
for d=0:360;                 
    v=sum(1-~diff(sum(imrotate(S,d))));
    if v<m;
        m=v;a=d;
    end;
end;
S=imrotate(S,a);
x=sum(S);y=sum(S');
disp([sum(x>mean(x)),sum(y>mean(y))])

7

CJam,68 65 64字节

可以打更多一点。

qN/2f%{{:QN*'.#Qz,)mdQ2$>2<".X"f#_~>@@0=?Qz}2*;@@-@@-mhSQWf%}2*;

怎么运行的

如果考虑的话,逻辑很简单。

我们需要的输入X.组合是两个相邻边的3个坐标。这是我们如何获取它们:

First

在矩形的任何方向上,.整个输入中的第一个将是角之一。例如..

XXXXXXXXXXXXXX
XXXXXXX...XXXX
XXXX.......XXX
X............X
XX.........XXX
XXXX...XXXXXXX
XXXXXXXXXXXXXX

在这里,第一个 .是在2 线,8 列中。

但是,不是那样,我们必须进行一些调整,并将该.行的走线宽度添加到坐标中,以获得右端的坐标。

Second

如果我们转置了上面的矩形(在换行符上旋转),则左下角将占据上述步骤的位置。但是在这里,我们不赔偿.游程长度,因为我们还是希望获得边缘的左下角坐标(以转置形式仍将是第一个遇到的坐标.

Rest two

对于其余两个坐标,我们只需水平翻转矩形,然后执行上述两个步骤。在前两个角落中,其中一个角落很常见。

全部取4后,我们只需做一些简单的数学运算即可得出距离。

现在,这不是最准确的方法,但是它在误差范围内以及矩形的所有可能方向上都可以很好地工作。

代码扩展(位已过时)

qN/2f%{{:QN*'.#Q0=,)md}:A~1$Q='.e=+QzA@@-@@-mhSQWf%}2*;
qN/2f%                               e# Read the input, split on newlines and squish it
      {   ...   }2*                  e# Run the code block two times, one for each side  
{:QN*'.#Q0=,)md}:A~                  e# Store the code block in variable A and execute it
 :QN*                                e# Store the rows in Q variable and join by newlines
     '.#                             e# Get the location of the first '.'
        Q0=,)                        e# Get length + 1 of the first row
             md                      e# Take in X and Y and leave out X/Y and X%Y on stack
1$Q=                                 e# Get the row in which the first '.' appeared
    '.e=+                            e# Get number of '.' in that row and add it to X%Y
         QzA                         e# Transpose the rows and apply function A to get
                                     e# the second coordinate
            @@-@@-                   e# Subtract resp. x and y coordinates of the two corners
                  mh                 e# Calculate (diff_x**2 + diff_y**2)**0.5 to get 1 side
                    SQWF%            e# Put a space on stack and put the horizontally flipped
                                     e# version of the rows/rectangle all ready for next two
                                     e# coordinates and thus, the second side

在这里在线尝试


尝试使用50x50的网格大小,45x45的矩形大小和angle -2。误差约为28%。我尝试了类似的方法(在看到您的想法之前,这是我的最初想法),并且要使其足够精确,这比预期的要棘手,尤其是当侧面接近水平/垂直时。如果它们更靠近对角线,则效果很好。我认为这要么需要更多的逻辑(例如,也要在对角线方向上寻找极限),要么需要完全不同的方法。
Reto Koradi 2015年

@RetoKoradi哦。那是因为所有负角都需要.在第二个坐标而不是第一个坐标上调整宽度。将修复。应该是短期解决方案。
Optimizer

1
@RetoKoradi应该现在固定。
Optimizer

尝试40x24矩形角0
雷托Koradi

@RetoKoradi好点。目前尚不接受。
加尔文的爱好2015年

5

Python 3中,347个 337字节

结果比我预期的要难。工作正在进行中...

def f(s):
 l=s.split('\n');r=range;v=sorted;w=len(l[0]);h=len(l);p=[[x,y]for x in r(w)for y in r(h)if'X'>l[y][x]];x,y=[sum(k)/w/h for k in zip(*p)];g=[[x/2,y]];d=lambda a:((a[0]/2-a[2]/2)**2+(a[1]-a[3])**2)**.5
 for i in r(3):g+=v(p,key=lambda c:~-(c in g)*sum(d(j+c)for j in g))[:1]
 print(v(map(d,[g[1]+g[2],g[2]+g[3],g[1]+g[3]]))[:2])

定义一个函数f,将字符串作为参数并将结果打印到STDOUT。

Pyth,87 84 82 81 75 72 71字节

(可能无效,回到家时要进行调查)

Km%2d.zJf<@@KeThTG*UhKUKPSm.adfqlT2ytu+G]ho*t}NGsm.a,kNGJ3]mccsklhKlKCJ

方式仍然太久。基本上是以前的端口。爱心Pyth的.a欧几里得距离。通过STDIN获取输入,通过STDOUT提供输出。期望非矩形字符为小写字母x(嗯,ASCII值等于或大于98的任何字符)。

算法

两者都使用相同的算法。我基本上从一个包含矩形区域质心的数组开始。然后,我将三个点添加到矩形中所有点的数组中,始终选择与数组中已存在点的最大距离之和的那个。结果始终是在矩形的不同角上的三个点。然后,我只计算这三个点之间的所有三个距离,并取两个最短的距离。


Pyth解决方案根本不起作用。OP中的两个示例给出了[33.0, 59.0]而不是 [40, 24][39.0, 54.0]而不是的结果[24.0, 24.5]
雅库布2015年

@Jakube怪异 我回到家后会进行调查。不幸的是,我要去拉普兰的一次课堂旅行,直到6月9日。
PurkkaKoodari

不幸的是,我不会叫您去拉普兰旅行;-)
雅库布2015年

0

Python 2,342字节

import sys
r=[]
h=.0
for l in sys.stdin:w=len(l);r+=[[x*.5,h]for x in range(0,w,2)if l[x:x+2]=='..'];h+=1
x,y=.0,.0
for p in r:x+=p[0];y+=p[1]
n=len(r)
x/=n
y/=n
m=.0
for p in r:
 p[0]-=x;p[1]-=y;d=p[0]**2+p[1]**2
 if d>m:m=d;u,v=p
m=.0
for p in r:
 d=p[0]*v-p[1]*u
 if d>m:m=d;s,t=p
print ((u-s)**2+(v-t)**2)**.5+1,((u+s)**2+(v+t)**2)**.5+1

这从@ Pietu1998的算法中获得了启发。它采用将一个角确定为距中心最远但与中心不同的点的想法:

  • 我将第二个角确定为交叉乘积最大的点,向量从中心到第一个角。这给出了从中心到第一个角的线的距离最大的点。
  • 无需搜索第三个角,因为它只是第二个角相对于中心的镜像。

因此代码遵循以下顺序:

  • 第一个循环在输入中的线上方,并建立一个r矩形点列表。
  • 第二个循环计算所有矩形点的平均值,给出矩形的中心。
  • 第三循环找到离中心最远的点。这是第一个角落。同时,它从列表中的点中减去中心,以便点坐标相对于剩余计算的中心。
  • 第四个循环找到向量与第一个角的叉积最大的点。这是第二个角落。
  • 打印出第一个角和第二个角之间的距离,以及第一个角和第二个角的镜像之间的距离。
  • 1.0之所以将距离添加到距离中,是因为原始距离计算使用像素索引。例如,如果您有5个像素,则最后一个像素与第一个像素的索引之间的差仅为4,这需要在最终结果中进行补偿。

精度相当不错。对于两个示例:

$ cat rect1.txt | python Golf.py 
24.5372045919 39.8329756779
$ cat rect2.txt | python Golf.py 
23.803508502 24.5095563412

0

Python 2,272字节

将其作为单独的答案发布,因为它与我之前的算法完全不同:

import sys,math
y,a,r=0,0,0
l,t=[1<<99]*2
for s in sys.stdin:
 c=s.count('..')
 if c:a+=c;x=s.find('.')/2;l=min(l,x);r=max(r,x+c);t=min(t,y);b=y+1
 y+=1
r-=l
b-=t
p=.0
w,h=r,b
while w*h>a:c=math.cos(p);s=math.sin(p);d=c*c-s*s;w=(r*c-b*s)/d;h=(b*c-r*s)/d;p+=.001
print w,h

这种方法根本无法确定角落。根据观察,边界框的大小(宽度和高度)和旋转后的矩形的面积足以确定矩形的宽度和高度。

如果您查看草图,则使用/ 矩形的大小和旋转角度来计算边界框的宽度(wb)和高度(hb)非常容易:whp

wb = w * cos(p) + h * sin(p)
hb = w * sin(p) + h * cos(p)

wbhb可以直接从图像中提取。我们还可以a通过计算..像素数来快速提取矩形的总面积。由于我们要处理的是矩形,所以这给了我们附加的等式:

a = w * h

因此,我们有3个方程具有3个未知数(whp),这足以决定未知数。唯一令人讨厌的是,这些方程式包含三角函数,至少以我的耐心和数学技巧,该系统无法轻松地通过解析来求解。

我实现的是用蛮力搜索角度p。一旦p给出,上面的前两个方程成为两个线性方程的系统,可以通过w和求解h

w = (wb * cos(p) - hb * sin(p)) / (cos(p) * cos(p) - sin(p) * sin(p))
h = (hb * cos(p) - wb * sin(p)) / (cos(p) * cos(p) - sin(p) * sin(p))

使用这些值,我们可以将其w * h与矩形的测量面积进行比较。理想情况下,这两个值在某些时候相等。当然,这在浮点数学中不会发生。

的值w * h随角度的增加而减小。因此,我们从角度0.0开始,然后以小步长增加角度,直到第一次w * h小于测量面积。

该代码只有两个主要步骤:

  1. 从输入中提取边界框和矩形区域的大小。
  2. 遍历候选角度,直到达到终止标准。

对于宽度和高度明显不同的矩形,输出的精度很好。对于几乎是正方形并旋转接近45度的矩形来说,它有些浮躁,仅能消除测试示例2的7%的误差。

示例2的位图实际上看起来有些奇怪。左角看起来可疑地暗淡。如果我在左上角再增加一个像素,对我来说,它们看起来都更好,并且为该算法提供了更高的精度。

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.