Визначте розміри обертового прямокутника


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та .за бажанням. (Нові лінії повинні залишатися новими.)
  • Виведіть виміряну ширину та висоту у вигляді цілих чи плаваючих чи викладених у будь-який порядок (оскільки немає способу визначити, який саме з цього параметра йшов). Будь-який формат , який чітко показує два вимірювання в порядку, наприклад D1 D2, D1,D2, D1\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%)

Оцінка балів

Виграє найкоротший код у байтах. Tierereaker - це найвище оцінений пост.


Чи не повинно рішення відповідати вимогам точності, які слід прийняти? Ви прийняли далеко не певні вхідні значення.
Рето Коради

Відповіді:


6

Матлаб, 226 байт

Ідея проста: спочатку я намагаюся з’ясувати, на скільки повернувся прямокутник, потім відповідно поверніть зображення таким чином, щоб прямокутник був вертикальним. Тоді я просто 'підсумовую' всі пікселі в стовпцях рядків спеціально і намагаюся підрахувати, скільки сум перевищує середнє (просте порогове значення) для визначення ширини та висоти. Цей простий метод працює напрочуд надійно.

Як я можу виявити кут?

Я просто намагаюся кожен крок (по одному градусу кожен) і підсумовую вздовж стовпців і отримую вектор сум. Коли прямокутник є вертикальним, в ідеалі я повинен отримати лише два раптових зміни цього вектора сум. Якщо квадрат знаходиться на кінчику, зміни дуже поступові. Тому я просто використовую першу похідну і намагаюся мінімізувати кількість "стрибків". Тут ви можете побачити сюжет критерію, який ми намагаємося мінімізувати. Зверніть увагу, що ви можете бачити чотири мінімуми, які відповідають четверенькам можливих вертикальних орієнтацій.

критерій мінімізації

Подальші думки: я не впевнений, наскільки це може бути поле для гольфу, оскільки вичерпний пошук під кутом займає багато персонажів, і я сумніваюся, що ви могли це досягти так добре за допомогою вбудованих методів оптимізації, тому що, як ви бачите, існує багато місцевих мінімумів що ми не шукаємо. Ви можете легко поліпшити точність (для великих зображень), вибираючи менший розмір кроку для кута і пошук тільки 90 ° замість 360 ° , щоб ви могли замінити 0:360з 0:.1:90або somehting подібними. Але в будь-якому випадку, для мене викликом було більше пошуку надійного алгоритму, а не гольфу, і я впевнений, що записи мов для гольфу залишать моє подання далеко позаду =)

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 та кут -2. Похибка становить близько 28%. Я спробував подібний підхід (це було моєю початковою ідеєю, перш ніж побачити вашу), і отримати його досить точно, виявляється складніше, ніж очікувалося, особливо якщо сторони близькі до горизонталі / вертикалі. Чудово працює, якщо вони ближче до діагоналі. Я думаю, для цього потрібна або більше логіки (наприклад, пошук крайностей у діагональному напрямку), або зовсім інший підхід.
Рето Коради

@RetoKoradi О. Це лише тому, що всі негативні кути потребують .регулювання ширини на другій координаті, а не на першому. Виправимо. Повинна бути коротка фіксація.
Оптимізатор

1
@RetoKoradi слід виправити зараз.
Оптимізатор

Спробуйте прямокутник 40x24 з кутом 0.
Ретро Кораді

@RetoKoradi Гарні моменти. Наразі неприйнято.
Захоплення Кальвіна

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.

Піта, 87 84 82 81 75 72 71 байт

(МОЖЛИВО НЕВАЛІДНИЙ, ДОСЛІДЖЕННЯ, КОЛИ Я ЗДОРОВИЙ ДОМА)

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

Шлях Ще занадто довгий. В основному порт попереднього. Любляча .aевклідова відстань Піта . Приймає вхід через STDIN і видає вихід через STDOUT. Очікує, що символ прямокутника буде малим x(ну, що завгодно зі значенням ASCII 98 або більше).

Алгоритм

Обидва вони використовують один і той же алгоритм. Я в основному починаю з масиву, що містить центр маси прямокутника. Потім я додаю три точки до масиву всіх точок прямокутника, завжди вибираючи той з максимальною сумою відстаней до точок, які вже є в масиві. Результат - це завжди три точки в різних кутах прямокутника. Потім я просто обчислюю всі три відстані між цими трьома точками і беру дві найкоротші.


Рішення Pyth взагалі не працює. Два приклади з ОП дають результати [33.0, 59.0]замість [40, 24]і [39.0, 54.0]замість [24.0, 24.5].
Якубе

@Jakube Дивно. Я розслідую, як тільки повернусь додому. На жаль, я перебуваю у класній поїздці до Лапландії до 9 червня.
PurkkaKoodari

На жаль, я б не назвав поїздку до Лапландії ;-)
Якубе

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) обмежувального поля з w/ hрозміром прямокутника та pкутом повороту:

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

wbі hbможе бути витягнутий безпосередньо із зображення. Також ми можемо швидко отримати загальну площу aпрямокутника, підрахувавши кількість ..пікселів. Оскільки ми маємо справу з прямокутником, це дає нам додаткове рівняння:

a = w * h

Таким чином , у нас є 3 рівнянь з 3 невідомими ( w, hі p), що досить для визначення невідомих. Єдиний обхід полягає в тому, що рівняння містять тригонометричні функції, і, принаймні, з моїм терпінням і математичними навичками система не може бути легко вирішена аналітично.

Те, що я реалізував, - це жорстокий пошук кута 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 градусів, лише ледь очищаючи 7% -не перешкоду помилки для тестового прикладу 2.

Біт-карта для прикладу 2 насправді виглядає трохи дивним. Лівий кут виглядає підозріло тьмяним. Якщо я додаю ще один піксель у лівому куті, він виглядає краще (для мене) і дає набагато кращу точність цього алгоритму.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.