Đảo Golf số 1: Vòng quanh thế giới


43

Đây là lần đầu tiên trong một loạt các thử thách Island Golf. Thách thức tiếp theo

Đưa ra một hòn đảo trong nghệ thuật ASCII, đưa ra một con đường tối ưu để đi vòng quanh nó.

Đầu vào

Đầu vào của bạn sẽ là một lưới hình chữ nhật bao gồm hai ký tự, đại diện cho đất và nước. Trong các ví dụ dưới đây, đất #và nước là ., nhưng bạn có thể thay thế bất kỳ hai ký tự riêng biệt nào bạn muốn.

...........
...##......
..#####....
..#######..
.#########.
...#######.
...#####.#.
....####...
...........

Sẽ luôn có ít nhất một ngói đất. Tất cả các ô đất sẽ liền kề nhau (tức là chỉ có một hòn đảo). Các gạch nước cũng sẽ tiếp giáp nhau (tức là không có hồ). Đường viền bên ngoài của lưới sẽ là gạch nước. Gạch đất sẽ không được kết nối theo đường chéo: tức là, bạn sẽ không bao giờ thấy một cái gì đó như

....
.#..
..#.
....

Đầu ra

Mã của bạn phải xuất ra cùng một lưới, với một vòng tuần hoàn ngắn nhất được vẽ trên đó. Trong các ví dụ dưới đây, đường dẫn tuần hoàn được vẽ bằng o, nhưng bạn có thể thay thế bất kỳ ký tự nào miễn là nó khác với các ký tự đất và nước của bạn.

Một vòng tuần hoàn là một đường cong khép kín đơn giản, được vẽ hoàn toàn trên gạch nước, bao quanh hoàn toàn tất cả các ô đất trên lưới. Kết nối đường chéo được cho phép. Chẳng hạn, đây là một vòng quanh đảo trên (nhưng không phải là ngắn nhất):

.ooooo.....
o..##.oo...
o.#####.o..
o.#######o.
o#########o
ooo#######o
..o#####.#o
..oo####..o
....oooooo.

Độ dài của một vòng tuần hoàn được tính như sau: Đối với mỗi cặp gạch liền kề trên đường dẫn, nếu chúng được kết nối theo chiều ngang hoặc chiều dọc, hãy thêm 1; nếu chúng được kết nối theo đường chéo, thêm √2. Độ dài của đường dẫn trên là 22 + 7√2 (31.9).

Một vòng tuần hoàn ngắn nhất là một vòng tuần hoàn với chiều dài ngắn nhất có thể. Chương trình của bạn sẽ xuất ra bất kỳ một đường dẫn nào thỏa mãn điều kiện này. Đối với hầu hết các đảo, sẽ có nhiều giải pháp khả thi. Đây là một giải pháp cho hòn đảo trên, với chiều dài 10 + 13√2 (28,4):

...oo......
..o##oo....
.o#####oo..
.o#######o.
o#########o
.o.#######o
..o#####.#o
...o####.o.
....ooooo..

Chi tiết

Giải pháp của bạn có thể là một chương trình đầy đủ hoặc một chức năng . Bất kỳ phương thức nhập và xuất mặc định nào đều được chấp nhận.

Đầu vào và đầu ra của bạn có thể là một chuỗi nhiều dòng hoặc một danh sách các chuỗi. Nếu ngôn ngữ của bạn có loại ký tự khác với các chuỗi ký tự đơn, bạn có thể thay thế "danh sách các ký tự" cho "chuỗi" trong câu trước. Nếu ngôn ngữ của bạn cần nhập chiều cao và / hoặc chiều rộng của lưới, bạn có thể làm như vậy. Đầu ra của bạn có thể (tùy chọn) có một dòng mới duy nhất. Như đã đề cập ở trên, bạn có thể sử dụng bất kỳ ba ký tự riêng biệt nào thay thế #.o(vui lòng ghi rõ trong bài gửi của bạn những ký tự bạn đang sử dụng).

Các trường hợp thử nghiệm

A. Quần đảo có vòng tuần hoàn ngắn nhất:

...
.#.
...

.o.
o#o
.o.

......
.####.
......

.oooo.
o####o
.oooo.

......
......
..##..
...#..
......
......

......
..oo..
.o##o.
..o#o.
...o..
......

.......
.#####.
...#...
...#...
.#####.
.......

.ooooo.
o#####o
o..#..o
o..#..o
o#####o
.ooooo.

.......
...#...
...#...
.#####.
...#...
...#...
.......

...o...
..o#o..
.o.#.o.
o#####o
.o.#.o.
..o#o..
...o...

.......
.#####.
.##..#.
..#..#.
.......

.ooooo.
o#####o
o##..#o
.o#..#o
..oooo.

B. Ví dụ về một hòn đảo có nhiều giải pháp khả thi:

........
....##..
...####.
..###...
.#####..
.#####..
..##....
........

Đầu ra có thể:

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##.o..
..ooo...

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##.o..
..ooo...

C. Trường hợp thử nghiệm lớn như một ý chính


Đây là : mã ngắn nhất trong mỗi ngôn ngữ sẽ thắng.


1
Vòng tuần hoàn ngắn nhất cho trường hợp thử nghiệm thứ 3 là mô hình 'ổ bánh' trong Trò chơi cuộc sống của Conway!
Đồng chí SparklePony

Câu trả lời:


18

Mathicala (phiên bản 9), 165 byte

Hàm ngắn, đẹp ConvexHullMeshmà Greg Martin sử dụng chỉ được giới thiệu trong phiên bản Mathicala 10, vì vậy tôi nghĩ rằng tôi sẽ cố gắng mà không có nó, bằng cách sử dụng phiên bản Mathicala cổ đại của tôi 9. Tuy nhiên, tôi đã xoay sở để có được nó ngắn hơn một chút! Đó là một chức năng mà mất và trả về một danh sách các chuỗi (với ., #onhư những biểu tượng).

""<>#&/@("o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."})&[Characters@#/.{"."->0,"#"->1}]&

Giải trình:

  • Đầu tiên, Characters@# /. {"."->0, "#"->1}biến đầu vào thành một ma trận 0s và 1s.
  • "o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#sau đó sử dụng các khả năng xử lý hình ảnh mạnh mẽ (nhưng cực kỳ nặng byte) của Mathicala để lần đầu tiên điền vào thân lồi của hòn đảo (đó là hình dạng bạn sẽ có nếu bạn kéo căng một chuỗi xung quanh nó), sau đó lấy ranh giới của nó. Sau đó, chúng tôi nhân ma trận này với chuỗi "o"để có ma trận 0s và "o"s (nhờ khả năng thích ứng ấn tượng của Mathicala về các loại) và thêm "#"ma trận này vào lần ma trận của đảo.
  • Cuối cùng, ""<>#& /@ (... /. {0->"."})biến ma trận "o"s, "#"s và 0s này thành ma trận "o"s, "#"s và "."s và nối mỗi hàng thành một chuỗi.

Khi chúng tôi kiểm tra điều này trên ví dụ B , chúng tôi nhận được đầu ra

{"....oo..",
 "...o##o.",
 "..o####o",
 ".o###..o",
 "o#####o.",
 "o#####o.",
 ".o##oo..",
 "..oo...."}

[Chỉnh sửa, nhờ Greg Martin:] Nếu chúng tôi được phép sử dụng các mảng ký tự thay vì danh sách các chuỗi, chúng tôi có thể cắt giảm xuống còn 144 byte:

"o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."}&[#/.{"."->0,"#"->1}]&

1
Làm tốt lắm! Tôi chưa bao giờ biết về MorphologicalComponents[#, Method->"ConvexHull"] :) Bạn có thể lưu nhiều byte hơn bằng cách giả sử rằng đầu vào đã được chia thành các ký tự và bằng cách trả lại một mảng các ký tự 2D.
Greg Martin

@GregMartin, tôi không biết về việc sử dụng MorphologicalComponentsmột trong hai ngày hôm nay!
Không phải là cây

Người mới học toán ở đây: tôi nên gọi hàm này như thế nào? Tôi đã thử f[{"...",".#.","..."}]và có một số lỗi.
DLosc

@DLosc, Chức năng là toàn bộ, không chỉ f. (Chà, nói đúng ra đó là công cụ sau dấu chấm phẩy.) Để gọi hàm, hãy nhập toàn bộ vào cửa sổ Mathicala, theo sau là [đầu vào của bạn và ]do đó, nó sẽ trông giống như f@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}](được rút ngắn cho không gian).
Không phải là một cái cây vào

@DLosc Chà, đó là vì mã bị hỏng. Tôi nghĩ rằng tôi đã sửa nó ngay bây giờ! (Tôi không biết chuyện gì đã xảy ra ở đó; xin lỗi,)
Không phải là một cái cây vào

11

(Nhưng đi lên giải pháp của Notatree , tốt hơn!)

Toán học, 168 byte

(x_~n~y_:=Min[Norm[x-#]&/@y];i=#;p=i~Position~#&;t=p["#"|"."]~Select~#&;(i~Part~##="o")&@@@t[#~n~t[ConvexHullMesh[Join[s=p@"#",#+{.1,.1}&/@s]]~RegionMember~#&]==1&];i)&

Hàm thuần túy lấy một mảng 2D các ký tự làm đầu vào và trả về một mảng các ký tự 2D. Phiên bản dễ đọc hơn:

1  (x_~n~y_ := Min[Norm[x - #] & /@ y];
2  i = #; p = i~Position~# &; 
3  t = p["#" | "."]~Select~# &;
4  (i~Part~## = "o") & @@@ 
5    t[#~n~
6      t[ConvexHullMesh[
7        Join[s = p@"#", # + {.1, .1} & /@ s]]
8      ~RegionMember~# &] == 1 &];
9  i) &

Dòng 1 định nghĩa một hàm ntạo khoảng cách (nhỏ nhất) giữa một điểm xtrong mặt phẳng và một tập hợp ycác điểm khác. Dòng 2 khởi tạo biến icho đầu vào, cả hai để giải quyết sự mơ hồ về cà ri sau này và để có thể sửa đổi nó để tạo đầu ra cuối cùng; dòng 2 cũng định nghĩa một hàm ptrả về tọa độ của tất cả các lần xuất hiện của đầu vào của nó i.

Trên dòng 3, p["#" | "."]biểu thị mọi tọa độ đơn từ bản đồ đầu vào (vì tất cả các ký tự của nó là "#"hoặc "."), do đó, tmột hàm chỉ chọn các tọa độ thỏa mãn một thuộc tính chưa xác định. Trên dòng 4, i~Part~## = "o"sẽ thay đổi một loạt các mục nhập ivào nhân vật "o"; những ký tự đó sẽ được chọn từ tập hợp các tọa độ có thể theo các nội dung trên dòng 5-8. Và dòng 9 chỉ trả về câu trả lời khi nó được tính toán.

Được rồi, cơ sở hạ tầng đã hoàn thành, bây giờ đến tính toán thực tế. ConvexHullMeshlà tích hợp sẵn của Mathicala để tính toán vỏ lồi của một tập hợp các điểm (đa giác lồi nhỏ nhất chứa các điểm đó). Nói về mặt đạo đức, điều này sẽ "điền vào" các vịnh nhỏ và vịnh hẹp của hòn đảo (đó là s = p@"#"), để loại trừ chúng ra khỏi hệ thống kiểm duyệt của chúng tôi. Có một vấn đề nhỏ ConvexHullMeshkhi tập hợp các điểm đó nằm trong một dòng (cảm ơn bạn, trường hợp thử nghiệm số 2), chúng tôi giải quyết bằng cách nối thêm một phiên bản bù nhẹ của schính nó vào dòng 7. Đầu ra này là một đa giác, vì vậy các dòng 7 -9 (t[...~RegionMember~# &]) tạo ra một danh sách các điểm có tọa độ nguyên trong đa giác đó. Cuối cùng, dòng 5 và cuối dòng 9 tính toán tất cả các điểm ở khoảng cách chính xác 1 (do đó không phải là 0) từ tập hợp các điểm nguyên này; thiết lập đó trở thành con đường vòng quanh.

Dưới đây là đầu ra cho trường hợp thử nghiệm lớn tại liên kết của OP. Lưu ý ở phía trên bên trái, các lựa chọn bất thường khi đi về phía tây so với gợi ý về thực tế là nó che khuất một đường dốc vô hình -2/3 giữa hai bán đảo (đoạn đường cho biết là một phần của ranh giới vỏ lồi).

........................
.............o..........
...........oo#ooooooo...
..........o#.#.##...#o..
........oo.#.#.###.##o..
.......o..########.##o..
.....oo...############o.
...oo#....############o.
..o#.###.##############o
.o##.##################o
.o####################o.
.o.##################.o.
.o##################..o.
.o..################..o.
o###################..o.
o#####################o.
o.##################.o..
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#oooo.....
.oooooo#ooooooo.........
.......o................

Mathicala thường biểu diễn các chuỗi dưới dạng các mảng 1D của các ký tự? Nếu không, thay vào đó, bạn sẽ cần phải lấy / trả về một chuỗi các chuỗi 1D. (Ngoài ra, mong được giải thích! Tôi không nghĩ rằng tôi có thể chạy nó mà không cần
Mathicala

Mathematica có kiểu dữ liệu chuỗi, nhưng dường như một mảng các ký tự cũng hợp lệ cho các mục đích của trang web này (nghĩa là tôi đã học được điều này khi tôi bắt đầu trên PPCG, nhưng tôi quên mất tính hợp pháp của lý do tại sao). Vâng, thật không may, Mathicala không miễn phí và do đó không thể truy cập được đối với nhiều người :(
Greg Martin

1
@GregMartin Tôi luôn thử các giải pháp Mathicala
ovs

Đồng thuận hiện tại nói rằng danh sách các chuỗi ký tự đơn không thể được sử dụng thay cho chuỗi. Theo như tôi có thể nói, "các ký tự" trong Mathicala chỉ là các chuỗi ký tự đơn, giống như trong Python. Tình huống là khác nhau trong một ngôn ngữ như Java, có một charloại riêng biệt ; trong trường hợp đó, một charmảng có thể được sử dụng thay cho chuỗi.
DLosc

1
Đây là cách tôi đọc nó: Câu trả lời nâng cao chính đã được đăng vào năm 2014. Câu trả lời tôi liên kết đã được đăng vào năm 2016, như một nỗ lực để làm rõ sự mơ hồ trong câu trả lời trước đó. Vì vậy, tôi đã đọc điểm âm trên câu trả lời mới hơn khi mọi người nói, "Không, chúng tôi không muốn câu trả lời cũ hơn có nghĩa là danh sách các chuỗi ký tự đơn là ổn." Nhưng bất kể meta, tôi không đồng ý danh sách các chuỗi ký tự đơn trong câu hỏi này (và tôi đã làm rõ từ ngữ để phản ánh điều đó).
DLosc

10

Python 3, 779 byte (thụt lề bằng các tab)

Đây là toàn bộ chương trình. Nó đọc đầu vào từ stdin và in nó ra thiết bị xuất chuẩn. Stdin phải kết thúc bằng EOF. Ví dụ chạy với đầu vào lớn: https://ideone.com/X IfYY0

import itertools,sys
L=list
C=itertools.count
d=L(map(L,filter(None,sys.stdin.read().split('\n'))))
X=len(d[0])
Y=len(d)
R=range
def P(r):return all(d[y][x]=='.'for x,y in r)
def S(f):
    for n in C(0):
        if P(f(n)):l=n
        else:break
    for n in C(l+1):
        if P(f(n)):return l,n
def f(V,a,*b):return L(eval('lambda '+a+':('+i+')',V)for i in b)
V=locals()
def D(n):
    y=min(n,Y-1);x=n-y
    while y>=0and x<X:yield(x,y);x+=1;y-=1
def E(n):
    x=max(0,n-Y);y=x+Y-n
    while y<Y and x<X:yield(x,y);x+=1;y+=1
F=f(V,'p','(p,y)for y in R(0,Y)','(x,p)for x in R(0,X)')+[D,E]
r=f(V,'x,y','x','y','x+y','x-y+Y')
B=L(map(S,F))
for x in R(0,X):
    for y in R(0,Y):
        z=L(zip(r,B))
        if all(g(x,y)in R(a,b+1)for g,(a,b)in z)and any(g(x,y)in e for g,e in z):d[y][x]='o'
print('\n'.join(''.join(x)for x in d))

Ý tưởng rất đơn giản: nó tính các giới hạn hình bát giác nhỏ nhất và vẽ các ô nằm trong tất cả các giới hạn được tính toán và cắt nhau ít nhất một trong các cạnh.


1
Bạn không thực sự cần phải sử dụng sys.stdinlàm đầu vào. input(), nhận được multiline sẽ thực hiện công việc và tốn ít byte hơn
Dead Possum

2
Có thể thay thế R(0,x)bằngR(x)
trần mèo

+1 khi không sử dụng tích hợp.
Robert Fraser

1
Đẹp! Một số mẹo chơi gôn khác: tiết kiệm 5 byte mỗi bằng cách sử dụng lambdas để xác định Pf; L(generator expression)=> [generator expression]; F, rBdường như chỉ được sử dụng một lần mỗi lần và do đó có thể được nội tuyến.
DLosc

8

JavaScript (ES6), 369 343 byte

f=s=>(a=s.split`
`.map(s=>[...s]),m=Array(8),a.map((b,i)=>b.map((c,j)=>c>'#'||[i-j,i,j+i,j,j-i,-i,-i-j,-j].map((d,k)=>d>m[k]||(m[k]=d-1)))),[o,p,q,r,t,u,v,w]=m,g=(i,j,k,l,...p)=>i-k|j-l?a[i][j]=g(i+(k>i)-(k<i),j+(l>j)-(l<j),k,l,...p):1/p[0]?g(k,l,...p):'o',g(p,p-o,p,q-p,q-r,r,r-t,r,-u,t-u,-u,u-v,w-v,-w,o-w,-w,p,p-o),a.map(b=>b.join``).join`
`)

Giải thích: Chuỗi được chia thành một mảng ký tự (Tôi không rõ liệu đầu vào mảng ký tự có được chấp nhận hay không). Các mảng sau đó được lặp đi lặp lại và vị trí của tất cả các hình vuông đất được đặt. Các dòng bounding cho bởi phương trình x - y = o, x = p, x + y = q, y = r, y - x = t, -x = u, -x - y = v, -y = wđược xác định như vậy mà các tham số tối đa có thể được lựa chọn nơi mà tất cả những lời dối trá đất cõi bên kia đường. Điều này có tác dụng bao vây hòn đảo trong một hình bát giác. Các tọa độ của các góc của hình bát giác được tính toán dễ dàng từ các tham số và các ô trên cạnh của nó được điền vào. Mảng sau đó được nối lại thành một chuỗi. Lý do một hình bát giác đủ như sau:

   /o#     /o#     /o#
 |/o #   |/o #   |/ o#
 *o###   * o #   *  o#
/|o #   /|o #   /| o#
 |o#     |o#     |o#

Hãy xem xét một góc của hình bát giác. Tại một số điểm dọc theo hai cạnh, con đường sẽ bị giới hạn bởi đất bởi vì chúng tôi đã xây dựng hình bát giác để chạm đất càng gần càng tốt. Nếu không có đất ở góc, đường dẫn có thể đi theo các tuyến đường thay thế như hình bên phải, nhưng đó vẫn là cùng một số bước trực giao và đường chéo, do đó khoảng cách không thay đổi.


Không có gì ...
Robert Fraser

@RobertFraser Tên kỹ thuật là phá hủy mảng. Trong trường hợp này, tuy nhiên, nó chỉ hoạt động như một rest of argumentstham số.
Neil

@Neil Trên thực tế, tên kỹ thuật là tham số phần còn lại . Cú pháp tương tự được sử dụng cho toán tử trải . (Bạn sử dụng cả hai như ...pở những nơi khác nhau.) Phá hủy là một cái gì đó khác (mặc dù toán tử lây lan có thể được sử dụng trong phá hủy).
Brian McCutchon

@BrianMcCutchon Bạn nói đúng, ý tôi là toán tử trải rộng, nhưng phá hủy các công việc trong danh sách đối số.
Neil

6

Python 3.5, 224, 263, 234 218 byte

Đánh bại 16 byte khác bằng cách loại bỏ hàm lồng nhau và biến nó thành một lớp lót.

def h(s,k=0,i=0):w=s.find('\n')+1;x=s.find('X')-w;k=k or x;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2;u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]

Đánh bại 29 byte:

def f(s):
 w=s.find('\n')+1;x=s.find('X')-w;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2
 def h(s,k,i):u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]
 return h(s,x,0)

Đầu vào là một chuỗi đơn sử dụng '~' cho đại dương, 'X' cho đất liền và 'o' cho ranh giới. (Sử dụng 'X' sẽ tiết kiệm một byte cho '>' thay vì '==')

Phiên bản ít chơi gôn hơn với các bình luận:

def f(s):
    w=s.find('\n')+1                         # width of one row
    x=s.find('X')-w                          # starting point
    d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2        # delta to add to current index to move in 
                                             # the 8 directions: E, SE, S, SW, W, NW, 
                                             # N, NE. Make it long to avoid
                                             # lots of modulo operations in 
                                             #    the recursive calls

    def h(s,k,i):                            # s is the island string, k the current
                                             # position, i the direction index
        if s[k]>'X'and k==x:                 # if back at the begining,
            return s                         #   return the map

        elif 'X'>s[k] and i<8:               # if there is water here, and haven't
                                             #  looped around,
            u=s[:k]+'o'+s[k+1:]              #  make a new map with an 'o' in the 
                                             #  current spot

            r = h(u,k+d[i+2],i+2)            # try a 90 degree right turn
            if r: return r

            r = h(u,k+d[i+1],i+1)            # try a 45 degree turn
            if r: return r

            r= h(u,k+d[i],i)                 # try straight ahead
            if r: return r

        return ''                            # this path failed

    return h(s,x,0)

@DLosc đã sửa. (tôi có nên xóa câu trả lời cũ không?)
RootTwo 30/03/2017

Đẹp! (Có, bạn nên xóa câu trả lời cũ - nếu bất kỳ ai muốn xem nó, họ có thể xem lịch sử sửa đổi của bài đăng.)
DLosc

5

C # 7 - 414 369 327 byte

Chỉnh sửa : chuyển sang vòng lặp 1D, tính toán ijđang hoạt động

Chỉnh sửa : thay đổi phương thức nhập, bảng tra cứu được thu gọn và chuyển sang giới hạn ban đầu được xác định rõ ... và xóa khoảng trống vô nghĩa trong vòng lặp ngoài vòng lặp cuối cùng

using C=System.Console;class P{static void Main(){var D=C.In.ReadToEnd().Replace("\r","");int W=D.IndexOf('\n')+1,H=D.Length,z=H,k,q,c;int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H;var B=new int[9];for(;z-->0;)for(k=9;k-->0&D[z]%7<1;)if(B[k]<=P())B[k]=P()+1;for(;++z<H;C.Write(q>9?'o':D[z]))for(q=k=9;k-->0;)q*=(c=P()-B[k])>0?0:c<0?1:2;}}

Dùng thử trực tuyến

Toàn bộ chương trình, có đầu vào đến trong tiêu chuẩn, in nó ra tiêu chuẩn, sử dụng #, .o. Đối với mỗi ô, nó sẽ tính toán một 'hồ sơ' (là khoảng cách trên 8 hướng (có vẻ như tính toán một phần chín để thuận tiện, nhưng điều này luôn luôn 0) và ghi lại tối đa mỗi trong số đó. một lần nữa và thay thế bất kỳ ô nào nằm trên một ranh giới và không nằm ngoài bất kỳ ô nào bằng 'o'. Mã nhận xét bên dưới giải thích cách tất cả hoạt động.

Theo câu trả lời của tôi để cứu ngỗng khỏi sự tuyệt chủng , điều này tạo ra hình bát giác nhỏ nhất (tuần hoàn hợp lệ với diện tích lớn nhất) giới hạn trên đảo.

Lưu ý : rằng một lần trong đời tôi đang sử dụng thứ gì đó từ thập kỷ hiện tại và mã này yêu cầu C # 7 để biên dịch. Nếu bạn không có C # 7, có một dòng sẽ cần phải được thay thế, được đánh dấu rõ ràng trong mã.

Ví dụ sử dụng và đầu ra:

type t7.txt | IslandGolf1.exe

.........ooooooooooo....
........o....#......o...
.......o...#.#.##...#o..
......o....#.#.###.##.o.
.....o....########.##..o
....o.....############.o
...o.#....############.o
..o#.###.##############o
.o##.##################o
o.####################.o
o..##################..o
o.##################...o
o...################...o
o###################...o
o#####################.o
o.##################..o.
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#...o.....
.o.....#.........o......
..ooooooooooooooo.......

Mã định dạng và nhận xét:

using C=System.Console;

class P
{
    static void Main()
    {
        // \n 10
        // # 35
        // . 46
        // o 111


        var D=C.In.ReadToEnd().Replace("\r",""); // map

        int W=D.IndexOf('\n')+1, // width
            H=D.Length, // length
            z=H, // position in map (decomposed into i and j by and for P)
            k, // bound index
            q, // bound distance, and later cell condition (0 -> outside, 8 -> inside, >8 -> on boudary)
            c; // (free), comparison store

        // 'indexes' into a profile for the point z at index k
        // effectively {i=z%W,j=z/W,-i,-j,i+j,j-i,-i-j,i-j,0}[k] (inside order is a bit different) (0 const is always treated as 'inside bounds')
        // each non-zero-const entry describes the distance in one of the 8 directions: we want to maximise these to find the 'outer bounds'
        // the non-zero-const bounds describe 8 lines, together an octogen
        int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // new C#7 local method syntax (if you don't have C#7, you can test this code with the line below instead)
        //k=0;System.Func<int>P=()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // old lambda syntax (must pre-assign k to make static checker happy)

        var B=new int[9]; // our current bounds, each is initially null (must only call P() when on a #)
        // B[k] starts off a 0, P() has a +H term, and W+(H/W)<H for W >= 3, so B[k] is assigned the first time we compare it (H-i-j always > 0)

        for(;z-->0;) // for each cell
            for(k=9;k-->0& // for each bound
                D[z]%7<1;) // if this cell is #
                if(B[k]<=P())B[k]=P()+1; // update bound if necessary (add one so that we define the bound _outside_ the hashes)
        // z=-1
        for(;++z<H; // for each cell
                C.Write(q>9?'o':D[z])) // print the cell (if q > 9, then we are on the bounds, otherwise, spit out whatever we were before)
            // check we are not 'outside' any of the bounds, and that we are 'on' atleast one of them
            for(q=k=9;k-->0;) // for each bound
                q*=(c=P()-B[k])>0?0: // outside bound (q=0)    (??0 is cheaper than (int) or .Value)
                    c<0?1: // inside (preserve q)
                    2; // on bound (if q != 0, then q becomes > 9)
    }
}

hình bát giác lớn nhất? hay nhỏ nhất?
Sange Borsch

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