กำหนดขนาดของสี่เหลี่ยมผืนผ้าที่หมุน


14

ตัวอย่างสแต็กนี้วาดสี่เหลี่ยมสีขาวที่มีนามแฝงบนพื้นหลังสีดำที่กำหนดพารามิเตอร์สำหรับขนาดตำแหน่งมุมและขนาดกริด:

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

การแสดงข้อความมีXXทุกที่ที่มีพิกเซลสีดำในภาพและ..ที่ใดก็ตามที่มีพิกเซลสีขาว (มันดูไม่ดีถ้าเป็นXและ.)

เขียนโปรแกรมที่ใช้การแทนข้อความของสี่เหลี่ยมที่สร้างโดย Snippet และส่งออกความกว้างและความสูงโดยประมาณของสี่เหลี่ยมทั้งสองถึงภายใน± 7% ของความกว้างและความสูงจริง

โปรแกรมของคุณควรทำงานอย่างมีประสิทธิภาพสำหรับสี่เหลี่ยมที่เป็นไปได้ทั้งหมดที่สามารถวาดโดยตัวอย่างด้วยข้อ จำกัด ที่:

  • ความกว้างและความสูงของรูปสี่เหลี่ยมผืนผ้าคือ 24 เป็นอย่างน้อย
  • ความกว้างและความสูงกริดคือ 26 ที่ต่ำสุด
  • สี่เหลี่ยมผืนผ้าไม่เคยสัมผัสและออกนอกขอบเขตกริด

ดังนั้นสี่เหลี่ยมอินพุทอาจมีการหมุนตำแหน่งและมิติและกริดอาจมีมิติใด ๆ ตราบใดที่ข้อ จำกัด ทั้งสามด้านบน โปรดทราบว่ายกเว้นขนาดกริดพารามิเตอร์ Snippet สามารถลอยได้

รายละเอียด

  • ใช้สี่เหลี่ยมผืนผ้าข้อความดิบเป็นอินพุตหรือใช้ชื่อไฟล์ของไฟล์ที่มีสี่เหลี่ยมผืนผ้าข้อความดิบ (ผ่าน stdin หรือบรรทัดคำสั่ง) คุณอาจจะถือว่าสี่เหลี่ยมผืนผ้าข้อความมีขึ้นบรรทัดใหม่
  • คุณอาจสมมติว่าสี่เหลี่ยมผืนผ้าข้อความนั้นทำจากอักขระ ASCII ที่สามารถพิมพ์ได้สองตัวนอกเหนือจากXและ.หากต้องการ (ขึ้นบรรทัดใหม่ต้องอยู่บรรทัดใหม่)
  • ส่งออกความกว้างและความสูงที่วัดได้เป็นจำนวนเต็มหรือลอยไปยัง stdout ในลำดับใด ๆ (เนื่องจากไม่มีวิธีการตรวจสอบว่าอันไหนที่ไปด้วยพารามิเตอร์ตัวใด) รูปแบบใด ๆ ที่แสดงให้เห็นชัดเจนทั้งสองมิติเป็นเรื่องปกติเช่นD1 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%)

เกณฑ์การให้คะแนน

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker เป็นโพสต์โหวตสูงสุด


โซลูชันไม่ควรตอบสนองความต้องการความแม่นยำที่จะยอมรับหรือไม่ สิ่งที่คุณยอมรับนั้นอยู่ไกลสำหรับค่าอินพุตบางค่า
Reto Koradi

คำตอบ:


6

Matlab, 226 ไบต์

ความคิดนั้นง่าย: ก่อนอื่นฉันพยายามหาว่าสี่เหลี่ยมหันไปเท่าไหร่จากนั้นหมุนภาพตามนั้นเพื่อให้สี่เหลี่ยมนั้นตั้งตรง จากนั้นฉันก็ 'ผลรวม' พิกเซลทั้งหมดในคอลัมน์แถวอย่างกระจัดกระจายและลองนับจำนวนผลรวมที่สูงกว่าค่าเฉลี่ย (การกำหนดค่าแบบง่าย) เพื่อกำหนดความกว้างและความสูง วิธีการง่ายๆนี้ทำงานได้อย่างน่าเชื่อถือ

ฉันจะตรวจจับมุมได้อย่างไร

ฉันลองแต่ละขั้นตอน (หนึ่งองศาแต่ละอัน) แล้วหาผลรวมตามแนวคอลัมน์แล้วรับผลบวกของเวกเตอร์ เมื่อรูปสี่เหลี่ยมผืนผ้าตั้งตรงฉันควรได้รับการเปลี่ยนแปลงอย่างฉับพลันเพียงสองครั้งในผลบวกของเวกเตอร์นี้ หากสี่เหลี่ยมอยู่บนปลายการเปลี่ยนแปลงจะค่อยเป็นค่อยไปมาก ดังนั้นฉันแค่ใช้อนุพันธ์อันดับแรกและพยายามลดจำนวน 'การข้าม' ที่นี่คุณสามารถเห็นพล็อตของเกณฑ์ที่เราพยายามย่อให้เล็กสุด โปรดสังเกตว่าคุณสามารถเห็นสี่ minima ซึ่งสอดคล้องกับทิศทางที่เป็นไปได้ทั้งสี่ที่เป็นไปได้

ลดเกณฑ์

ความคิดเพิ่มเติม: ฉันไม่แน่ใจว่าจะสามารถตีกอล์ฟได้มากเท่าไหร่เนื่องจากการค้นหามุม exhausive ใช้ตัวละครจำนวนมากและฉันสงสัยว่าคุณจะประสบความสำเร็จได้ด้วยวิธีการเพิ่มประสิทธิภาพที่สร้างขึ้นเพราะอย่างที่คุณเห็นว่ามีจำนวนท้องถิ่นน้อยที่สุด ที่เราไม่ต้องการ คุณสามารถปรับปรุงความแม่นยำได้อย่างง่ายดาย (สำหรับภาพใหญ่) โดยเลือกขนาดขั้นตอนที่เล็กลงสำหรับมุมและค้นหาเฉพาะ 90 °แทนที่จะเป็น 360 °เพื่อให้คุณสามารถแทนที่0:360ด้วย0:.1:90หรือเปลี่ยนบางอย่างเช่นนั้น แต่อย่างไรก็ตามสำหรับฉันความท้าทายคือการหาอัลกอริทึมที่มีประสิทธิภาพมากกว่าการเล่นกอล์ฟและฉันมั่นใจว่ารายการภาษาการเล่นกอล์ฟจะทำให้สิ่งที่ฉันส่งมีความผิดพลาด =)

PS: บางคนควรได้รับภาษากอล์ฟจาก Matlab / Octave

เอาท์พุท

ตัวอย่างที่ 1:

 25    39

ตัวอย่างที่ 2:

 25    24

รหัส

แข็งแรงเล่นกอล์ฟ:

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

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 ไบต์

นี่สามารถเล่นกอล์ฟได้มากกว่านี้ ..

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 TH คอลัมน์

แต่นั่นไม่ใช่เราต้องทำการปรับแต่งและเพิ่มความกว้างของการ.วิ่งบนเส้นนั้นไปยังพิกัดเพื่อให้ได้พิกัดที่ถูกต้อง

Second

หากเราเปลี่ยนตำแหน่งของสี่เหลี่ยมด้านบน (หมุนที่เส้นใหม่) มุมล่างซ้ายจะเข้าแทนที่ขั้นตอนข้างต้น แต่ที่นี่เราไม่ชดเชย.ความยาวในการวิ่งเนื่องจากเราต้องการให้พิกัดด้านล่างซ้ายของขอบยังไงก็ตาม(ซึ่งในรูปแบบ transposed จะยังคงเป็นครั้งแรกที่พบ.)

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% ฉันลองวิธีที่คล้ายกัน (มันเป็นความคิดเริ่มต้นของฉันก่อนที่จะเห็นของคุณ) และทำให้มันแม่นยำพอที่จะกลายเป็นเล่ห์เหลี่ยมกว่าที่คาดไว้โดยเฉพาะอย่างยิ่งถ้าด้านที่อยู่ใกล้แนวนอน / แนวตั้ง ใช้งานได้ดีถ้าพวกเขาอยู่ใกล้กับเส้นทแยงมุม ฉันคิดว่าสิ่งนี้ต้องใช้ตรรกะมากกว่า (เช่นค้นหาสุดขั้วในทิศทางทแยงมุม) หรือวิธีที่แตกต่างอย่างสิ้นเชิง
Reto Koradi

@RetoKoradi โอ้ นั่นเป็นเพราะมุมลบทั้งหมดต้องการการ.ปรับความกว้างในพิกัดที่สองแทนที่จะเป็นอันดับแรก จะแก้ไข ควรแก้ไขให้สั้น
เครื่องมือเพิ่มประสิทธิภาพ

1
@RetoKoradi ควรได้รับการแก้ไขแล้ว
เครื่องมือเพิ่มประสิทธิภาพ

ลองรูปสี่เหลี่ยมผืนผ้าขนาด 40x24 พร้อมมุม 0
Reto Koradi

@RetoKoradi คะแนนดี ไม่ยอมรับในตอนนี้
งานอดิเรกของ Calvin

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ระยะทางแบบยุคลิดรักของ Pyth รับอินพุตผ่าน STDIN และให้เอาต์พุตผ่าน STDOUT คาดหวังว่าอักขระที่ไม่ใช่รูปสี่เหลี่ยมผืนผ้าจะเป็นตัวพิมพ์เล็กx(อย่างใดก็ได้มีค่า ASCII 98 ขึ้นไป)

ขั้นตอนวิธี

ทั้งสองใช้อัลกอริทึมเดียวกัน ฉันเริ่มต้นด้วยอาร์เรย์ที่มีจุดศูนย์กลางมวลของพื้นที่สี่เหลี่ยม จากนั้นฉันจะเพิ่มสามจุดลงในอาร์เรย์ของทุกจุดในสี่เหลี่ยมผืนผ้าเลือกจุดที่มีค่าสูงสุดเสมอผลรวมระยะทางของจุดที่มีอยู่ในอาเรย์เสมอ ผลลัพธ์จะเป็นสามจุดในมุมต่าง ๆ ของสี่เหลี่ยมผืนผ้าเสมอ จากนั้นฉันจะคำนวณทั้งสามระยะทางระหว่างจุดสามจุดเหล่านั้นและหาจุดที่สั้นที่สุดสองอัน


โซลูชัน Pyth ใช้งานไม่ได้เลย ทั้งสองตัวอย่างจาก OP ให้ผล[33.0, 59.0]แทน [40, 24]และแทน[39.0, 54.0] [24.0, 24.5]
Jakube

@ Jakube แปลก ฉันจะตรวจสอบเมื่อฉันกลับถึงบ้าน น่าเสียดายที่ฉันเดินทางไปเรียนที่ Lapland จนถึงวันที่ 9 มิถุนายน
PurkkaKoodari

ฉันจะไม่เรียกการเดินทางไปที่ Lapland อย่างน่าเสียดาย ;-)
Jakube

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

วิธีนี้ไม่ได้ระบุมุมเลย มันขึ้นอยู่กับการสังเกตว่าขนาด (ความกว้างและความสูง) ของกล่อง bounding และพื้นที่ของสี่เหลี่ยมหมุนได้เพียงพอที่จะกำหนดความกว้างและความสูงของสี่เหลี่ยม

หากคุณดูภาพร่างมันเป็นเรื่องง่ายที่จะคำนวณความกว้าง ( 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 จริง ๆ แล้วดูแปลกเล็กน้อย มุมซ้ายดูหมองคล้ำอย่างน่าสงสัย ถ้าฉันเพิ่มหนึ่งพิกเซลที่มุมซ้ายทั้งคู่จะดูดีขึ้น (สำหรับฉัน) และให้ความแม่นยำมากขึ้นสำหรับอัลกอริทึมนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.