Döndürülmüş Dikdörtgenin Boyutlarını Belirleme


14

Bu yığın Pasaj bir çekilişi yumuşatılmış boyutları, konum, açı ve ızgara boyutları için siyah bir zemin üzerinde verilen parametreleri beyaz bir dikdörtgen:

<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 Sürümü )

Metin gösterimi, XXgörüntüde siyah bir pikselin olduğu ..her yerde ve beyaz bir pikselin olduğu her yerde bulunur. (Eğer olsaydı ezilmiş görünüyor Xve ..)

Snippet tarafından üretilen bir dikdörtgenin metin temsilini alan ve dikdörtgenin yaklaşık genişliğini ve yüksekliğini, her ikisi de gerçek genişlik ve yüksekliğin ±% 7'si dahilinde çıktısı alan bir program yazın .

Programınız, snippet tarafından çizilebilecek tüm olası dikdörtgenler için etkili bir şekilde çalışmalıdır;

  • Dikdörtgen genişliği ve yüksekliği minimum 24'tür.
  • Izgara genişliği ve yüksekliği minimum 26'dır.
  • Dikdörtgen asla dokunmaz ve ızgara sınırlarının dışına taşmaz.

Dolayısıyla, giriş dikdörtgeni herhangi bir döndürme, konum ve boyuta sahip olabilir ve yukarıdaki üç kısıtlama karşılandığı sürece ızgara herhangi bir boyuta sahip olabilir. Izgara boyutları dışında Snippet parametrelerinin yüzer olabileceğini unutmayın.

ayrıntılar

  • Ham metin dikdörtgenini girdi olarak alın veya ham metin dikdörtgenini içeren bir dosyanın dosya adını alın (stdin veya komut satırı üzerinden). Metin dikdörtgenin sonunda bir satırsonu olduğunu varsayabilirsiniz.
  • Metin dikdörtgeninin istenirse ve istenirse yazdırılabilir iki farklı ASCII karakterinden yapıldığını varsayabilirsiniz . (Yeni satırlar yeni satır olarak kalmalıdır.)X.
  • Ölçülen genişlik ve yüksekliği herhangi bir sırayla stdout'a tamsayı veya yüzer olarak çıktılayın (hangisinin gerçekte hangi parametreyle gittiğini belirlemenin bir yolu olmadığından). Açık bir şekilde iki boyutu gösterir herhangi bir biçimi ince, örneğin bir D1 D2, D1,D2, D1\nD2, (D1, D2), vs.
  • Program yerine, metin dikdörtgeni bir dize veya dosya adı olarak alan ve sonucu normal olarak yazdıran veya iki öğe içeren bir dize veya liste / tuple olarak döndüren bir işlev yazabilirsiniz.
  • Bunun XXveya ..dikdörtgenin bir 'pikseli' olduğunu unutmayın, iki değil.

Örnekler

Ör. 1

Parametreler: grid w:60 grid h:34 w:40 h:24 x:0 y:0 θ:12(Snippet varsayılanları)

Giriş

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

Örnek Çıktılar

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

Ör. 2

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

Giriş

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

Örnek Çıktılar

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

puanlama

Bayt cinsinden en kısa kod kazanır. Tiebreaker en yüksek oy alan yazı.


Bir çözüm, kabul edilecek hassasiyet gereksinimlerini karşılamamalı mı? Kabul ettiğiniz belirli giriş değerleri için çok uzak.
Reto Koradi

Yanıtlar:


6

Matlab, 226 bayt

Fikir basit: Önce dikdörtgenin ne kadar döndüğünü bulmaya çalışıyorum, sonra dikdörtgeni dik olacak şekilde görüntüyü döndürün. Sonra sadece satır sütunlarındaki tüm pikselleri toparlıyorum ve genişlik ve yüksekliği belirlemek için toplamların kaçının ortalamanın (basit eşik) üstünde olduğunu saymaya çalışıyorum. Bu basit yöntem şaşırtıcı derecede güvenilir bir şekilde çalışır.

Açıyı nasıl tespit edebilirim?

Sadece her adımı (her biri bir derece) deneyin ve sütunlar boyunca toplamı ve toplamları bir vektör olsun. Dikdörtgen dik olduğunda, ideal olarak bu toplamlar vektöründe sadece iki ani değişiklik elde etmeliyim. Kare ucundaysa, değişiklikler çok aşamalıdır. Bu yüzden sadece ilk türevi kullanıyorum ve 'sıçrama' sayısını en aza indirmeye çalışıyorum. Burada en aza indirmeye çalıştığımız kriterin bir grafiğini görebilirsiniz. Dört olası olası dik yönelime karşılık gelen dört minima görebilirsiniz dikkat edin.

minimizasyon kriteri

Diğer düşünceler: Kapsamlı açı araması çok fazla karakter aldığından ne kadar golf oynayabileceğinden emin değilim ve yerleşik optimizasyon yöntemleriyle bu kadar iyi başarabileceğinizden şüpheliyim, çünkü görebileceğiniz gibi çok sayıda yerel minima var aramıyoruz. Açı için daha küçük bir adım boyutu seçerek doğruluğu (büyük resimler için) kolayca iyileştirebilir ve 360 ​​° yerine yalnızca 90 ° arayabilir, böylece 0:360bununla 0:.1:90veya böyle bir şeyle değiştirebilirsiniz . Ama neyse, benim için zorluk golf yerine daha sağlam bir algoritma bulmaktı ve golf dillerinin girişlerinin gönderimi çok geride bırakacağından eminim =)

Not: Birisi gerçekten Matlab / Octave'den bir golf dili türetmelidir.

çıktılar

Örnek 1:

 25    39

Örnek 2:

 25    24

kod

golfed:

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

Ungolfed:

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 bayt

Bu biraz daha golf yapılabilir ..

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

Nasıl çalışır

Eğer düşünürseniz, mantık oldukça basittir.

Giriş X.kombinasyonlarından tek ihtiyacımız olan iki bitişik kenarın 3 koordinatı. Onları şu şekilde elde ederiz:

First

Dikdörtgenin herhangi bir yönünde ., girdinin tamamındaki ilk köşelerden biri olacaktır. Örneğin..

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

Burada, ilk .2 yılında olduğu nd 8, hat inci sütunu.

Ama bu değil, bazı ayarlamalar yapmalı .ve sağ tarafın koordinatını elde etmek için o satırdaki çalışmanın genişliğini koordinatlara eklemeliyiz .

Second

Yukarıdaki dikdörtgeni (yeni satırlara döndürülmüş) devredersek, sol alt köşe yukarıdaki adımın yerini alır. Ancak burada, .kenarın sol alt koordinatını yine de almak istediğimiz için çalışma uzunluğunu telafi etmiyoruz (transpozisyonda hala karşılaşılan ilk form olacak .)

Rest two

Diğer iki koordinat için, dikdörtgeni yatay olarak çeviririz ve yukarıdaki iki adımı uygularız. Buradaki köşelerden biri ilk ikisinden yaygın olacak.

Tüm 4'ü aldıktan sonra, mesafeleri almak için basit bir matematik yapıyoruz.

Şimdi bu en doğru yöntem değil, ancak hata payı içinde ve dikdörtgenin tüm olası yönleri için iyi çalışıyor.

Kod genişletme (bit modası geçmiş)

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

Buradan çevrimiçi deneyin


Izgara boyutunu 50x50, dikdörtgen boyutunu 45x45 ve açı olarak deneyin -2. Hata yaklaşık% 28'dir. Benzer bir yaklaşım denedim (sizinkini görmeden önce ilk fikrimdi) ve özellikle kenarlar yatay / dikey yakınsa, beklenenden daha zor olduğu ortaya çıktı. Köşeye yakınsa harika çalışıyor. Bence bu daha fazla mantık (örneğin çapraz yönde aşırı uçları aramak) ya da tamamen farklı bir yaklaşım gerektirir.
Reto Koradi

@RetoKoradi Oh. Bunun nedeni, tüm negatif açıların .birinci yerine ikinci koordinatta genişlik ayarlamasına ihtiyaç duymasıdır . Düzeltecek. Kısa düzeltme olmalıdır.
Optimize Edici

1
@RetoKoradi şimdi düzeltilmelidir.
Doktor

40x24 dikdörtgeni 0 açısıyla deneyin.
Reto Koradi

@RetoKoradi İyi puan. Şimdilik kabul edilmedi.
Calvin'in Hobileri

5

Python 3, 347337 bayt

Bu beklediğimden daha zor çıktı. Yapılmakta olan çalışmalar ...

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

Dizeyi fbağımsız değişken olarak alan ve sonucu STDOUT'a yazdıran bir işlevi tanımlar .

Pyth, 87 84 82 81 75 72 71 bayt

(EVİM ALDIĞIMDA ARAŞTIRMAK GEREKEN GEÇERSİZ)

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

yol Hala çok uzun. Temelde bir önceki liman. Sevgi dolu Pyth'in .aÖklid mesafesi. STDIN üzerinden girdi alır ve STDOUT üzerinden çıktı verir. Dikdörtgen olmayan karakterin küçük harf olmasını bekler x(ASCII değeri 98 veya daha fazla olan herhangi bir şey).

Algoritma

Her ikisi de aynı algoritmayı kullanır. Temelde dikdörtgen alanın kütle merkezini içeren bir dizi ile başlar. Daha sonra dikdörtgen içindeki tüm noktaların dizisine üç nokta eklerim, her zaman dizideki noktalara maksimum uzaklık toplamı olanı seçerim. Sonuç, dikdörtgenin farklı köşelerinde her zaman üç noktadır. Daha sonra bu üç nokta arasındaki üç mesafeyi de hesaplayıp en kısa iki mesafeyi alıyorum.


Pyth çözümü hiç çalışmıyor. OP'den iki örnek, [33.0, 59.0]yerine [40, 24]ve [39.0, 54.0]yerine sonuçları vermektedir [24.0, 24.5].
Jakube

@Jakube Weird. Eve döndüğümde araştıracağım. Ne yazık ki 9 Haziran'a kadar Lapland'a bir sınıf gezisinde bulunuyorum.
PurkkaKoodari

Ne yazık ki; Lapland bir gezi çağırmak olmaz ;-)
Jakube

0

Python 2, 342 bayt

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

Bu @ Pietu1998'in algoritmasından ilham aldı. Bir köşeyi merkezden en uzak nokta olarak belirleme fikrini alır, ancak oradan farklıdır:

  • İkinci köşeyi, vektörü merkezden ilk köşeye kadar olan en büyük çapraz ürüne sahip nokta olarak belirlerim. Bu, merkezden ilk köşeye doğru en büyük mesafeye sahip noktayı verir.
  • Üçüncü bir köşe aramaya gerek yoktur, çünkü merkeze göre sadece ikinci köşenin ayna görüntüsüdür.

Kod şu sırayı izler:

  • İlk döngü girişteki satırların üzerindedir ve rdikdörtgen noktaların bir listesini oluşturur .
  • İkinci döngü, dikdörtgenin merkezini vererek tüm dikdörtgen noktalarının ortalamasını hesaplar.
  • Üçüncü döngü merkezden en uzak noktayı bulur. Bu ilk köşe. Aynı zamanda, merkezi listedeki noktalardan çıkarır, böylece nokta koordinatları kalan hesaplama için merkeze göreli olur.
  • Dördüncü döngü, vektörü ilk köşeye kadar olan en büyük çapraz ürüne sahip noktayı bulur. Bu ikinci köşe.
  • İlk köşe ile ikinci köşe arasındaki mesafeyi ve ikinci köşe ile ikinci köşenin ayna görüntüsü arasındaki mesafeyi yazdırır.
  • 1.0mesafelere eklenir çünkü orijinal mesafe hesaplamaları piksel indeksleri kullanır. Örneğin, 5 pikseliniz varsa, son ve ilk pikselin dizini arasındaki fark yalnızca 4'tür ve bu da nihai sonuçta telafi gerektirir.

Hassasiyet oldukça iyidir. İki örnek için:

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

0

Python 2, 272 bayt

Bir öncekinden tamamen farklı bir algoritma olduğu için bunu ayrı bir cevap olarak göndermek:

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

Bu yaklaşım köşeleri hiç tanımlamaz. Sınırlama kutusunun boyutunun (genişlik ve yükseklik) ve döndürülmüş dikdörtgenin alanının, dikdörtgenin genişliğini ve yüksekliğini belirlemek için yeterli olduğu gözlemine dayanır.

Bir çizime bakarsanız , sınırlama kutusunun genişliğini ( wb) ve yüksekliğini ( hb) w/ hdikdörtgenin boyutu ve pdönüş açısı ile hesaplamak oldukça kolaydır :

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

wbve hbdoğrudan görüntüden çıkarılabilir. Ayrıca piksel asayısını sayarak dikdörtgenin toplam alanını hızlı bir şekilde çıkarabiliriz ... Bir dikdörtgenle uğraştığımız için, bu bize ek denklemi verir:

a = w * h

Biz 3 bilinmeyenli (3 denklemler var Yani w, hve pbilinmeyenleri belirlemek için yeterlidir). Tek serseri, denklemlerin trigonometrik fonksiyonlar içermesidir ve en azından sabrım ve matematik becerilerimle sistem analitik olarak kolayca çözülemez.

Uyguladığım açı için kaba bir kuvvet arayışı p. Bir kez pilk iki denklem için yukarıda çözülebilir iki lineer denklem, bir sistem haline verilir, wve 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))

Bu değerlerle, w * hdikdörtgenin ölçülen alanıyla karşılaştırabiliriz . İki değer ideal olarak bir noktada eşit olacaktır. Bu tabii ki kayan nokta matematiğinde gerçekleşmeyecek.

w * hAçı arttıkça değeri azalır. Bu nedenle 0.0 açısıyla başlıyoruz ve ardından ilk kez w * hölçülen alandan daha az olana kadar açıyı küçük adımlarla artırıyoruz .

Kodun yalnızca iki ana adımı vardır:

  1. Sınırlama kutusunun ve dikdörtgen alanının boyutunu girişten çıkarın.
  2. Fesih kriterine ulaşılana kadar aday açıları üzerinde döngü yapın.

Çıktının hassasiyeti, genişlik ve yüksekliğin önemli ölçüde farklı olduğu dikdörtgenler için iyidir. Neredeyse kare olan ve 45 dereceye yakın döndürülmüş dikdörtgenler ile biraz iffy olur, sadece test örneği 2 için% 7 hata engelini zorlukla temizler.

Örnek 2'deki bitmap aslında biraz tuhaf görünüyor. Sol köşe kuşkuyla donuk görünüyor. Sol köşeye bir piksel daha eklersem, ikisi de daha iyi görünür (bana göre) ve bu algoritma için çok daha iyi bir hassasiyet verir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.