Xác định kích thước của hình chữ nhật xoay


14

Đây stack Snippet thu hút một aliased hình chữ nhật màu trắng trên nền đen thông số đưa ra cho kích thước của nó, vị trị, góc, và kích thước lưới:

<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>
( Phiên bản JSFiddle )

Biểu diễn văn bản có XXbất cứ nơi nào có pixel đen trong ảnh và ..bất cứ nơi nào có pixel trắng. (Nó trông bị vắt nếu họ X..)

Viết chương trình lấy biểu diễn văn bản của hình chữ nhật do Snippet tạo ra và đưa ra chiều rộng và chiều cao gần đúng của hình chữ nhật, cả hai đều nằm trong phạm vi ± 7% chiều rộng và chiều cao thực tế .

Chương trình của bạn phải hoạt động hiệu quả cho tất cả các hình chữ nhật có thể có thể được rút ra bởi đoạn mã, với các ràng buộc:

  • Chiều rộng và chiều cao hình chữ nhật tối thiểu là 24.
  • Chiều rộng và chiều cao lưới tối thiểu là 26.
  • Hình chữ nhật không bao giờ chạm và cũng không đi ra khỏi giới hạn lưới.

Vì vậy, hình chữ nhật đầu vào có thể có bất kỳ góc quay, vị trí và kích thước nào và lưới có thể có bất kỳ kích thước nào, miễn là đáp ứng ba ràng buộc ở trên. Lưu ý rằng ngoại trừ kích thước lưới, các tham số Snippet có thể được thả nổi.

Chi tiết

  • Lấy hình chữ nhật văn bản thô làm đầu vào hoặc lấy tên tệp của tệp chứa hình chữ nhật văn bản thô (thông qua stdin hoặc dòng lệnh). Bạn có thể giả sử hình chữ nhật có một dòng mới.
  • Bạn có thể giả sử hình chữ nhật văn bản được tạo từ bất kỳ hai ký tự ASCII có thể in riêng biệt nào khác X.nếu muốn. (Dòng mới phải ở dòng mới.)
  • Xuất ra chiều rộng và chiều cao đo được dưới dạng số nguyên hoặc số float cho thiết bị xuất chuẩn theo bất kỳ thứ tự nào (vì không có cách nào để xác định cái nào thực sự đi với tham số nào). Bất kỳ định dạng mà rõ ràng cho thấy hai kích thước là tốt, ví dụ như D1 D2, D1,D2, D1\nD2, (D1, D2)vv
  • Thay vì một chương trình, bạn có thể viết một hàm lấy hình chữ nhật văn bản thành một chuỗi hoặc tên tệp cho nó và in kết quả bình thường hoặc trả về dưới dạng một chuỗi hoặc liệt kê / tuple với hai phần tử.
  • Hãy nhớ rằng XXhoặc ..là một "pixel" của hình chữ nhật, không phải hai.

Ví dụ

Ví dụ. 1

Tham số: grid w:60 grid h:34 w:40 h:24 x:0 y:0 θ:12(Mặc định đoạn trích)

Đầu vào

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

Kết quả đầu ra

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

Ví dụ. 2

Thông số: grid w:55 grid h:40 w:24.5 h:24 x:-10.1 y:2 θ:38.5

Đầu vào

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

Kết quả đầu ra

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

Chấm điểm

Mã ngắn nhất tính bằng byte thắng. Tiebreaker là bài bình chọn cao nhất.


Không phải là một giải pháp đáp ứng các yêu cầu chính xác để được chấp nhận? Một trong những bạn đã chấp nhận là xa cho các giá trị đầu vào nhất định.
Reto Koradi

Câu trả lời:


6

Matlab, 226 byte

Ý tưởng rất đơn giản: Đầu tiên tôi cố gắng tìm hiểu xem hình chữ nhật được xoay bao nhiêu, sau đó xoay hình ảnh sao cho hình chữ nhật thẳng đứng. Sau đó, tôi chỉ cần tổng hợp tất cả các pixel trong các cột hàng một cách đều đặn và thử đếm xem có bao nhiêu tổng trên trung bình (ngưỡng đơn giản) để xác định chiều rộng và chiều cao. Phương pháp đơn giản này hoạt động đáng tin cậy đáng ngạc nhiên.

Làm thế nào tôi có thể phát hiện các góc?

Tôi chỉ cần thử từng bước (mỗi độ một độ) và tổng hợp dọc theo các cột và nhận được một vectơ tổng. Khi hình chữ nhật thẳng đứng, lý tưởng nhất là tôi chỉ nhận được hai thay đổi đột ngột trong vectơ tổng này. Nếu hình vuông nằm trên đỉnh, những thay đổi sẽ rất từ ​​từ. Vì vậy, tôi chỉ sử dụng đạo hàm đầu tiên và cố gắng giảm thiểu số lần 'nhảy'. Ở đây bạn có thể thấy một âm mưu của tiêu chí mà chúng tôi đang cố gắng giảm thiểu. Lưu ý rằng bạn có thể thấy bốn cực tiểu tương ứng với các hướng thẳng đứng có thể có.

tiêu chí tối thiểu hóa

Suy nghĩ thêm: Tôi không chắc có thể chơi golf được bao nhiêu vì việc tìm kiếm góc độ tốn rất nhiều ký tự và tôi nghi ngờ bạn có thể đạt được điều đó rất tốt với các phương pháp tối ưu hóa được xây dựng, bởi vì bạn có thể thấy có rất nhiều cực tiểu cục bộ mà chúng tôi không tìm kiếm. Bạn có thể dễ dàng cải thiện độ chính xác (đối với ảnh lớn) bằng cách chọn kích thước bước nhỏ hơn cho góc và chỉ tìm kiếm 90 ° thay vì 360 ° để bạn có thể thay thế 0:360bằng 0:.1:90hoặc thay đổi như thế. Nhưng dù sao, đối với tôi, thách thức là tìm ra một thuật toán mạnh mẽ hơn là chơi golf và tôi chắc chắn rằng các mục trong ngôn ngữ chơi gôn sẽ khiến bài nộp của tôi bị bỏ lại phía sau =)

Tái bút: Ai đó nên thực sự rút ra một ngôn ngữ chơi gôn từ Matlab / Octave.

Đầu ra

Ví dụ 1:

 25    39

Ví dụ 2:

 25    24

Chơi gôn

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))])

Ung dung:

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 byte

Điều này có thể được đánh gôn nhiều hơn một chút ..

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

Làm thế nào nó hoạt động

Logic khá đơn giản, nếu bạn nghĩ về nó.

Tất cả chúng ta cần từ các X.kết hợp đầu vào là 3 tọa độ của hai cạnh liền kề. Đây là cách chúng tôi có được chúng:

First

Trong bất kỳ hướng nào của hình chữ nhật, đầu tiên .trong toàn bộ đầu vào sẽ là một trong các góc. Ví dụ..

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

Ở đây, đầu tiên .là trong dòng thứ 2 , cột thứ 8 .

Nhưng đó không phải là nó, chúng ta phải thực hiện một số điều chỉnh và thêm độ rộng của đường .chạy trên đường thẳng đó vào tọa độ để có được tọa độ của đầu bên phải.

Second

Nếu chúng ta hoán chuyển hình chữ nhật ở trên (xoay vòng trên dòng mới), thì góc dưới bên trái sẽ chiếm vị trí của bước trên. Nhưng ở đây, chúng tôi không bù cho .chiều dài chạy vì chúng tôi muốn có được tọa độ dưới cùng bên trái của các cạnh dù sao (ở dạng chuyển tiếp vẫn sẽ là lần đầu tiên gặp phải .)

Rest two

Đối với hai tọa độ còn lại, chúng ta chỉ cần lật theo chiều ngang, hình chữ nhật và thực hiện hai bước trên. Một trong những góc ở đây sẽ là phổ biến từ hai đầu tiên.

Sau khi có được cả 4, chúng tôi chỉ cần làm một số phép toán đơn giản để có được khoảng cách.

Bây giờ đây không phải là phương pháp chính xác nhất, nhưng nó hoạt động tốt trong phạm vi lỗi và tốt cho tất cả các định hướng có thể có của hình chữ nhật.

Mở rộng mã (bit lỗi thời)

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

Dùng thử trực tuyến tại đây


Hãy thử kích thước lưới 50x50, kích thước hình chữ nhật 45x45 và góc -2. Lỗi khoảng 28%. Tôi đã thử một cách tiếp cận tương tự (đó là ý tưởng ban đầu của tôi, trước khi nhìn thấy bạn) và làm cho nó đủ chính xác hóa ra khó khăn hơn dự kiến, đặc biệt nếu các cạnh gần với ngang / dọc. Hoạt động tuyệt vời nếu chúng gần với đường chéo. Tôi nghĩ rằng điều này đòi hỏi logic hơn (ví dụ, cũng tìm kiếm các cực trị theo hướng chéo), hoặc một cách tiếp cận hoàn toàn khác.
Reto Koradi

@RetoKoradi ơi. Đó chỉ là vì tất cả các góc âm cần .điều chỉnh độ rộng trên tọa độ thứ hai, thay vì thứ nhất. Sẽ sửa chữa. Nên sửa ngắn.
Tối ưu hóa

1
@RetoKoradi nên được sửa ngay bây giờ.
Tối ưu hóa

Hãy thử hình chữ nhật 40x24 với góc 0.
Reto Koradi

@RetoKoradi Điểm tốt. Không được chấp nhận cho bây giờ.
Sở thích của Calvin

5

Python 3, 347 337 byte

Điều này hóa ra khó hơn tôi mong đợi. Công việc đang tiến triển ...

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])

Xác định hàm flấy chuỗi làm đối số và in kết quả sang STDOUT.

Pyth, 87 84 82 81 75 72 71 byte

(KHẢ NĂNG THAM GIA, ĐẦU TƯ KHI TÔI NHẬN NHÀ)

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

Con đường vẫn còn quá dài. Về cơ bản là một cổng của trước đó. Yêu .akhoảng cách Euclide của Pyth . Đưa đầu vào qua STDIN và cung cấp đầu ra qua STDOUT. Yêu cầu ký tự không phải hình chữ nhật là chữ thường x(tốt, mọi thứ có giá trị ASCII 98 trở lên).

Thuật toán

Cả hai đều sử dụng cùng một thuật toán. Về cơ bản, tôi bắt đầu với một mảng chứa tâm khối lượng của khu vực hình chữ nhật. Sau đó tôi thêm ba điểm vào mảng của tất cả các điểm trong hình chữ nhật, luôn chọn điểm có tổng khoảng cách tối đa với các điểm đã có trong mảng. Kết quả luôn là ba điểm ở các góc khác nhau của hình chữ nhật. Sau đó tôi chỉ cần tính tất cả ba khoảng cách giữa ba điểm đó và lấy hai điểm ngắn nhất.


Giải pháp Pyth hoàn toàn không hoạt động. Hai ví dụ từ OP đưa ra kết quả [33.0, 59.0]thay vì [40, 24][39.0, 54.0]thay vì [24.0, 24.5].
Jakube

@Jakube Lạ. Tôi sẽ điều tra một khi tôi về nhà. Thật không may, tôi đang trong một chuyến đi đến Lapland cho đến ngày 9 tháng 6.
PurkkaKoodari

Tôi sẽ không gọi một chuyến đi đến Lapland một cách đáng tiếc ;-)
Jakube

0

Python 2, 342 byte

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

Điều này lấy cảm hứng từ thuật toán của @ Pietu1998. Nó lấy ý tưởng xác định một góc là điểm xa nhất từ ​​trung tâm, nhưng khác ở đó:

  • Tôi xác định góc thứ hai là điểm có tích chéo lớn nhất với vectơ từ tâm đến góc thứ nhất. Điều này cho điểm với khoảng cách lớn nhất từ ​​đường thẳng từ trung tâm đến góc đầu tiên.
  • Không cần tìm kiếm góc thứ ba, vì đó chỉ là hình ảnh phản chiếu của góc thứ hai so với trung tâm.

Vì vậy, mã theo trình tự này:

  • Vòng lặp đầu tiên nằm trên các dòng trong đầu vào và xây dựng một danh sách rcác điểm hình chữ nhật.
  • Vòng lặp thứ hai tính trung bình của tất cả các điểm hình chữ nhật, cho tâm của hình chữ nhật.
  • Vòng lặp thứ ba tìm thấy điểm xa nhất từ ​​trung tâm. Đây là góc đầu tiên. Đồng thời, nó trừ trung tâm khỏi các điểm trong danh sách, sao cho tọa độ điểm có liên quan đến tâm cho phép tính còn lại.
  • Vòng lặp thứ tư tìm điểm có sản phẩm chéo lớn nhất có vectơ đến góc đầu tiên. Đây là góc thứ hai.
  • In ra khoảng cách giữa góc thứ nhất và góc thứ hai và khoảng cách giữa góc thứ nhất và hình ảnh phản chiếu của góc thứ hai.
  • 1.0được thêm vào khoảng cách vì các tính toán khoảng cách ban đầu sử dụng các chỉ số pixel. Ví dụ: nếu bạn có 5 pixel, sự khác biệt giữa chỉ số của pixel cuối cùng và pixel đầu tiên chỉ là 4, cần phải bù trong kết quả cuối cùng.

Độ chính xác khá tốt. Đối với hai ví dụ:

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

0

Python 2, 272 byte

Đăng bài này như một câu trả lời riêng vì đây là một thuật toán hoàn toàn khác với thuật toán trước của tôi:

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

Cách tiếp cận này không xác định góc nào cả. Nó dựa trên quan sát rằng kích thước (chiều rộng và chiều cao) của khung giới hạn và diện tích của hình chữ nhật xoay là đủ để xác định chiều rộng và chiều cao của hình chữ nhật.

Nếu bạn nhìn vào một bản phác thảo, khá dễ dàng để tính chiều rộng ( wb) và chiều cao ( hb) của khung giới hạn với w/ hkích thước của hình chữ nhật và pgóc xoay:

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

wbhbcó thể được trích xuất trực tiếp từ hình ảnh. Chúng ta cũng có thể nhanh chóng trích xuất tổng diện tích acủa hình chữ nhật bằng cách đếm số ..pixel. Vì chúng ta đang xử lý một hình chữ nhật, điều này cho chúng ta phương trình bổ sung:

a = w * h

Vì vậy, chúng ta có 3 phương trình với 3 ẩn số ( w, hp), đó là đủ để xác định các ẩn số. Bí quyết duy nhất là các phương trình chứa các hàm lượng giác, và ít nhất với sự kiên nhẫn và kỹ năng toán học của tôi, hệ thống không thể dễ dàng được giải quyết bằng phương pháp phân tích.

Những gì tôi thực hiện là một tìm kiếm vũ phu cho góc p. Khi pđược đưa ra, hai phương trình đầu tiên ở trên trở thành một hệ gồm hai phương trình tuyến tính, có thể được giải quyết cho wh:

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))

Với các giá trị này, sau đó chúng ta có thể so sánh w * hvới diện tích đo của hình chữ nhật. Hai giá trị lý tưởng sẽ bằng nhau tại một số điểm. Điều này tất nhiên sẽ không xảy ra trong toán học dấu phẩy động.

Giá trị w * hgiảm khi góc tăng. Vì vậy, chúng tôi bắt đầu ở góc 0,0, và sau đó tăng góc bằng các bước nhỏ cho đến lần đầu tiên w * hnhỏ hơn diện tích đo.

Mã chỉ có hai bước chính:

  1. Trích xuất kích thước của khung giới hạn và diện tích hình chữ nhật từ đầu vào.
  2. Lặp lại các góc ứng cử viên cho đến khi đạt được tiêu chí chấm dứt.

Độ chính xác của đầu ra là tốt cho hình chữ nhật trong đó chiều rộng và chiều cao khác nhau đáng kể. Nó có phần iffy với các hình chữ nhật gần như vuông và xoay gần 45 độ, chỉ vừa đủ để xóa rào cản lỗi 7% cho ví dụ thử nghiệm 2.

Bitmap cho ví dụ 2 thực sự trông hơi kỳ lạ. Góc bên trái trông buồn tẻ. Nếu tôi thêm một pixel ở góc bên trái, cả hai đều trông tốt hơn (với tôi) và mang lại độ chính xác cao hơn cho thuật toán này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.