回転した長方形の寸法を決定する


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

スニペットによって生成された長方形のテキスト表現を取り、長方形のおよその幅と高さを、実際の幅と高さの±7%以内の両方で出力するプログラムを作成します。

プログラムは、スニペットで描画できるすべての可能な長方形に対して効果的に機能する必要があり、次の制約があります。

  • 長方形の幅と高さは少なくとも24です。
  • グリッドの幅と高さは少なくとも26です。
  • 四角形がグリッド境界に接触したり、グリッド境界から出たりすることはありません。

したがって、上記の3つの制約が満たされている限り、入力長方形は任意の回転、位置、および寸法を持ち、グリッドは任意の寸法を持つことができます。グリッドの寸法を除き、スニペットパラメータはフロートにすることができます。

詳細

  • 入力として生のテキストの長方形を使用するか、生のテキストの長方形を含むファイルのファイル名を使用します(stdinまたはコマンドライン経由)。テキストの長方形の末尾に改行があると仮定できます。
  • あなたは、テキスト矩形は任意の二つの異なるから作られていると仮定して印刷可能なASCII以外の文字X.希望の場合。(改行は改行のままにする必要があります。)
  • 測定された幅と高さを整数として出力するか、任意の順序で標準出力にフロートします(どちらが実際にどのパラメーターを使用したかを判断する方法がないため)。はっきりと2次元を示し、任意のフォーマットで結構です、例えばD1 D2D1,D2D1\nD2(D1, D2)、など
  • プログラムの代わりに、テキスト長方形を文字列またはファイル名として取り、結果を通常どおりに印刷するか、2つの要素を持つ文字列またはリスト/タプルとして返す関数を作成できます。
  • ことを覚えています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は、最も投票数の多い投稿です。


ソリューションは受け入れられる精度の要件を満たすべきではありませんか?特定の入力値については、受け入れたものは遠いです。
レトコラディ

回答:


6

Matlab、226バイト

アイデアは簡単です。まず、長方形がどれだけ回転したかを調べてから、長方形が直立するように画像を適切に回転させます。次に、行の列のすべてのピクセルを個別に「合計」し、幅と高さを決定するために平均を超える合計(単純なしきい値設定)を数えます。この簡単な方法は驚くほど確実に機能します。

角度を検出するにはどうすればよいですか?

各ステップ(各1度)を試し、列に沿って合計し、合計のベクトルを取得します。長方形が直立している場合、理想的には、この合計ベクトルで2つの突然の変化のみを取得する必要があります。正方形が先端にある場合、変更は非常に緩やかです。だから私は一次導関数を使用し、「ジャンプ」の数を最小限に抑えるようにします。ここで、最小化しようとしている基準のプロットを見ることができます。4つの可能な直立方向に対応する4つの最小値が表示されることに注意してください。

最小化基準

さらなる考え:徹底的な角度検索には多くのキャラクターが必要なため、どれだけゴルフできるかわかりませんが、組み込みの最適化手法でそれを達成できるかどうかはわかりません。私たちが探していないこと。あなたは簡単に角度のために小さなステップサイズを選択することによって(大きな写真用)の精度を向上させ、あなたが交換することができるようにのみ°〜360°の代わりに90を検索することができ0:3600:.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.組み合わせから必要なのは、2つの隣接する辺の3つの座標だけです。取得方法は次のとおりです。

First

長方形のどの方向でも.、入力全体の最初の角が角の1つになります。例えば..

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

ここでは、1 行.は2 行目の 8 列目にあります。

しかし、それだけではありません。調整を行い.、その行のランの幅を座標に追加して、右端の座標を取得する必要があります。

Second

上記の長方形(改行でピボットされる)を転置すると、左下隅が上記のステップの位置を占めます。ただし、ここでは.、とにかくエッジの左下座標を取得したかったので、ランレングスを補正しません(転置された形で最初に検出されます.

Rest two

残りの2つの座標については、長方形を水平に反転させ、上記の2つのステップを実行するだけです。ここのコーナーの1つは、最初の2つから共通しています。

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%です。私は同様のアプローチを試みました(あなたの意見を見る前に、それは私の最初のアイデアでした)。対角線に近い場合に最適です。これには、より多くのロジック(たとえば、対角線方向の極値の検索)またはまったく異なるアプローチが必要だと思います。
レトコラディ

@RetoKoradiああ。これは、すべての負の角度が.最初ではなく2番目の座標で幅調整を必要とするからです。修正します。短い修正する必要があります。
オプティマイザー

1
@RetoKoradiは修正されました。
オプティマイザー

角度0で40x24矩形を試してみてください
レトKoradi

@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に出力する関数を定義します。

Pyth、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以上の任意の文字)。

アルゴリズム

どちらも同じアルゴリズムを使用します。基本的には、長方形領域の重心を含む配列から始めます。次に、長方形内のすべてのポイントの配列に3つのポイントを追加し、常に配列内のポイントまでの距離の合計が最大のものを選択します。結果は、常に長方形の異なる角にある3点です。次に、これら3つのポイント間の3つの距離をすべて計算し、最短の2つの距離を取得します。


Pythソリューションはまったく機能しません。OPからの2つの例では、結果を与える[33.0, 59.0]代わりに [40, 24]、および[39.0, 54.0]代わりに[24.0, 24.5]
ジャクベ

@ジャクベ・ウィアード。家に着いたら調査します。残念ながら、6月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のアルゴリズムからインスピレーションを得ました。1つのコーナーを中心から最も遠いポイントとして決定するという考え方を取りますが、そことは異なります。

  • 2番目のコーナーを、中心から最初のコーナーへのベクトルとの最大の外積を持つポイントとして決定します。これにより、中心から最初のコーナーまでのラインからの距離が最大のポイントが得られます。
  • 3番目のコーナーは、中心に対する2番目のコーナーの鏡像にすぎないため、検索する必要はありません。

したがって、コードは次のシーケンスに従います。

  • 最初のループは、入力内の行に対して実行され、r長方形のポイントのリストを作成します。
  • 2番目のループは、すべての長方形ポイントの平均を計算し、長方形の中心を提供します。
  • 3番目のループは、中心から最も遠い点を見つけます。これが最初のコーナーです。同時に、リスト内のポイントから中心を減算するため、残りの計算ではポイント座標は中心を基準にします。
  • 4番目のループは、最初のコーナーへのベクトルとの最大の外積を持つポイントを見つけます。これは2番目のコーナーです。
  • 最初のコーナーと2番目のコーナー間の距離、および1番目のコーナーと2番目のコーナーの鏡像間の距離を印刷します。
  • 1.0元の距離計算ではピクセルインデックスが使用されるため、距離に追加されます。たとえば、5つのピクセルがある場合、最後のピクセルと最初のピクセルのインデックスの差は4のみであり、最終結果で補正が必要です。

精度はかなり良いです。2つの例の場合:

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

wbそしてhb画像から直接抽出することができます。ピクセルa数を数えることで、長方形の総面積をすばやく抽出することもでき..ます。長方形を扱っているため、これにより追加の方程式が得られます。

a = w * h

したがって、3つの未知数(whおよびp)を持つ3つの方程式があり、未知数を決定するのに十分です。唯一の問題は、方程式に三角関数が含まれていることです。少なくとも私の忍耐力と数学スキルでは、システムを分析的に簡単に解くことができません。

私が実装したのは、角度のブルートフォース検索ですp。一度p与えられると、上記の最初の2つの方程式は2つの線形方程式のシステムに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して、長方形の測定面積と比較できます。理想的には、2つの値はある時点で等しくなります。もちろん、これは浮動小数点演算では発生しません。

の値はw * h、角度が大きくなるにつれて減少します。したがって、角度0.0から開始し、最初の時間w * hが測定面積より小さくなるまで、角度を小さなステップで増分します。

コードには2つの主要なステップのみがあります。

  1. 入力から境界ボックスと長方形領域のサイズを抽出します。
  2. 終了基準に達するまで候補角度をループします。

出力の精度は、幅と高さが大幅に異なる長方形に適しています。ほぼ正方形で、45度近くに回転した長方形ではやや不明瞭になりますが、テスト例2の7%エラーのハードルはほとんどクリアされません。

例2のビットマップは実際には少し奇妙に見えます。左隅は疑わしく鈍いように見えます。左隅にもう1つピクセルを追加すると、両方がより良く見え(私にとって)、このアルゴリズムの精度が大幅に向上します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.