Code-Golf: Quần đảo Count


31

Một cuộc thi đơn giản, lấy cảm hứng từ câu hỏi stackoverflow này :

Bạn được cung cấp một hình ảnh của một bề mặt được chụp bởi vệ tinh. Hình ảnh là một bitmap trong đó nước được đánh dấu bởi ' .' và đất được đánh dấu bởi ' *'. Các nhóm liền kề *tạo thành một hòn đảo. (Hai ' *' liền kề nếu chúng là hàng xóm ngang, dọc hoặc chéo). Nhiệm vụ của bạn là in số lượng đảo trong bitmap.

Một đơn *cũng được tính là một hòn đảo.

Đầu vào mẫu:

.........**
**......***
...........
...*.......
*........*.
*.........*

Đầu ra mẫu:

5

Người chiến thắng là mục có số byte nhỏ nhất trong mã.


Tôi không hiểu logic. Không có 5 sao ở góc trên bên phải được coi là một hòn đảo? Sau đó, ví dụ của bạn có 4 hòn đảo.
defhlt

Màn hình không bao bọc. một hòn đảo ở mỗi góc + *hòn đảo đơn độc
Claudiu

2
Nhưng theo định nghĩa của bạn, một hòn đảo là một nhóm các ký tự '*', ngụ ý nhiều hơn một.
acolyte

điểm công bằng *s độc lập cũng là đảo.
Claudiu

Câu trả lời:


30

Toán học 188 185 170 115 130 46 48 ký tự

Giải trình

Trong các phiên bản trước, tôi đã tạo một biểu đồ các vị trí có khoảng cách bàn cờ là 1 với nhau. GraphComponentssau đó tiết lộ số lượng đảo, mỗi đảo một thành phần.

Phiên bản hiện tại sử dụng MorphologicalComponentsđể tìm và đánh số cụm của các cụm trong mảng - các khu vực nơi 1tiếp giáp vật lý. Bởi vì đồ thị là không cần thiết, điều này dẫn đến một nền kinh tế mã lớn.


Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&

Thí dụ

Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}}]

5


Làm thế nào nó hoạt động

Dữ liệu được nhập vào dưới dạng một mảng; trong Mathematica, đây là danh sách các danh sách.

Trong mảng đầu vào, dữ liệu được chuyển đổi thành 1's và 0' bằng cách thay thế

/.{"."->0,"*"->1}

trong đó /.là một hình thức infix ReplaceAlltheo sau bởi các quy tắc thay thế. Điều này về cơ bản chuyển đổi các mảng thành một hình ảnh đen trắng. Tất cả chúng ta cần làm là áp dụng chức năng Image,.

Image[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}} /. {"." -> 0, "*" -> 1}]

đảo

Các ô vuông màu trắng tương ứng với các ô có giá trị, 1.

Hình dưới đây cho thấy một số bước tiếp cận sử dụng. Ma trận đầu vào chỉ chứa 1's và 0'. Ma trận đầu ra nhãn mỗi cụm hình thái với một số. (Tôi đã bọc cả ma trận đầu vào và đầu ra MatrixFormđể làm nổi bật cấu trúc hai chiều của chúng.)

MorphologicalComponentsthay thế 1s bằng một số nguyên tương ứng với số cụm của mỗi ô.

Chế biến

Max trả về số cụm lớn nhất.


Hiển thị quần đảo

Colorize sẽ tô màu mỗi hòn đảo độc đáo.

tô màu


Điều này không hoạt động như được viết trên v7 vì MorphologicalComponentsmuốn một Image, nhưng ngay cả trên v9 cũng không nên Max@MorphologicalComponents[d/.{"."->0,"*"->1}]? Đó là, sự thay thế được thực hiện đầu tiên? Maxsẽ biến mất trước khi thay thế được thực hiện, phải không?
Mr.Wizard

Tôi có V9, @ Mr.Wizard đúng. 46 ký tự là số đúng.
Murta

@ Mr.Wizard Việc thay thế được thực hiện trước khi áp dụng MorphologicalComponents. Phải là một điều ưu tiên.
DavidC

Xin chào @DavidCarraher, quan điểm của tôi không phải là về "->" mà là biểu thức Max@MorphologicalComponents@d/.{"."->0,"*"->1}không hoạt động, có ý nghĩa gì Max@MorphologicalComponents[d /. {"." -> 0, "*" -> 1}], vì vậy bạn có thêm một ký tự.
Murta

9

Ruby 1.9 (134 121 113 110)

Lấy bản đồ trên stdin hoặc tên tệp của bản đồ làm đối số dòng lệnh đầu tiên và in số lượng đảo thành thiết bị xuất chuẩn. Sử dụng một đệ quy lũ lụt cơ bản. Cải tiến luôn được chào đón!

c=0
gets$!
c+=1while(f=->i{9.times{|o|$_[i]=?.;f[o]if$_[o=i+(o/3-1)*(~/$/+1)+o%3-1]==?*&&o>0}if i})[~/\*/]
p c

Tương tự như Colorize của David, bạn cũng có thể lấy nó để hiển thị các hòn đảo khác nhau bằng cách thay đổi $_[i]=?.để $_[i]=c.to_sp cđể puts$_, mà sẽ cung cấp cho bạn một cái gì đó như thế này:

.........00
11......000
...........
...2.......
3........4.
3.........4

(ít nhất là cho đến khi bạn hết chữ số!)

Một số trường hợp thử nghiệm:

.........**
**......***
...........
...*.......
*........*.
*.........*

5

......*..**....*
**...*..***....*
....*..........*
...*.*.........*
*........***....
*.....*...***...
*.....*...*....*
****..........**
*.........*.....

9

*

1

****
****
....
****

2

**********
*........*
*.******.*
*.*....*.*
*.*.**.*.*
*.*.**.*.*
*.*....*.*
*.******.*
*........*
**********

3


8
Tôi thích bài kiểm tra cuối cùng. Suy nghĩ không khác biệt!
Ông Lister

1

C, 169 ký tự

Đọc bản đồ từ stdin. Không có may mắn cải thiện chức năng lấp lũ đệ quy r(j)mặc dù có vẻ như nó có thể.

c,g,x,w;char m[9999];r(j){if(m[j]==42)m[j]=c,r(j+1),r(j+w-1),r(j+w),r(j+w+1),c+=j==g;}main(){while((m[x++]=g=getchar())+1)w=g<11*!w?x:w;for(;g++<x;)r(g);printf("%i",c);}

1

Con trăn 2 223 203 byte

Cảm ơn Step HenArnold Palmer đã loại bỏ 20 ký tự khoảng trắng và dấu ngoặc đơn không cần thiết!

s=input()
c=[(s.index(l),i)for l in s for i,v in enumerate(l)if'*'==v]
n=[set([d for d in c if-2<d[0]-v[0]<2and-2<d[1]-v[1]<2])for v in c]
f=lambda x,p=0:p if x&n[p]else f(x,p+1)
print len(set(map(f,n)))

Tôi nghĩ rằng việc sử dụng khả năng hiểu danh sách có thể làm giảm số lượng byte, nhưng nó không mang lại sự cải thiện đáng kể nào.

Hãy thử nó ở đây.

Tôi tiếp tục cố gắng cắt nó quanh danh sách n (hàng xóm), nhưng tôi đã không thành công. Có lẽ ai đó sẽ có một số ý tưởng cho phần đó.


Chào mừng đến với PPCG! Đây là 217 byte bằng cách loại bỏ một số khoảng trắng. Trình phân tích cú pháp Python thực sự khoan dung: P
Stephen

Bạn có nhiều khoảng trắng hơn mức cần thiết. Hủy bỏ các khoảng trống giữa (s.index(l),i)for, enumerate(l)if, -v[0])<2and, p=0:p, và bool(x&n[p])else. Bạn cũng có nhiều dấu ngoặc đơn hơn mức cần thiết trong câu lệnh in của mình, vì bạn có 2 nhóm xung quanh set. Chỉnh sửa: Beat by StepHen vì làm mọi thứ trên thiết bị di động không lý tưởng.
Arnold Palmer

203 byte kết hợp các đề xuất của @ StepHen và của tôi, cộng với việc thay đổi các điều kiện một chút.
Arnold Palmer

Cảm ơn hai bạn vì sự giúp đỡ! Sự khoan hồng của Python làm tôi ngạc nhiên :)
Giải quyết

0

Perl 5 , 100 byte

98 byte mã + 2 byte cho -p0cờ.

/.*/;$@="@+"-1;$~="(.?.?.{$@})?";(s/X$~\*/X$1X/s||s/\*$~X/X$1X/s)&&redo;s/\*/X/&&++$\&&redo}{$\|=0

Hãy thử trực tuyến!

Một bản phóng tác (hay đúng hơn là đơn giản hóa) câu trả lời của tôi cho thử thách Bao nhiêu lỗ? . Bạn có thể tìm thấy giải thích về cách mã này hoạt động trên câu trả lời khác này (hơi lâu để giải thích, vì vậy tôi không muốn gõ lại toàn bộ giải thích).


0

Python 2, 233 byte

Quá dài, so với các câu trả lời khác. Cổng câu trả lời của tôi cho câu hỏi này .
Dùng thử trực tuyến

A=input()
c=0
X=len(A[0])-1
Y=len(A)-1
def C(T):
 x,y=T
 if A[y][x]<'.':A[y][x]='.';map(C,zip([x]*3+[min(x+1,X)]*3+[max(x-1,0)]*3,[y,min(y+1,Y),max(y-1,0)]*3))
while'*'in sum(A,[]):i=sum(A,[]).index('*');c+=1;C((i%-~X,i/-~X))
print c

0

JavaScript, 158 byte

function f(s){w=s.search('\n');t=s.replace(RegExp('([*@])([^]{'+w+','+(w+2)+'})?(?!\\1)[*@]'),'@$2@');return t!=s?f(t):/\*/.test(s)?f(s.replace('*','@'))+1:0}

Không trả lời câu trả lời ES6 (thách thức hoãn ngôn ngữ) cho 132 byte:

f=s=>s!=(s=s.replace(RegExp(`([*@])([^]{${w=s.search`
`},${w+2}})?(?!\\1)[*@]`),`@$2@`))?f(s):/\*/.test(s)?f(s.replace(`*`,`@`))+1:0

Cổng câu trả lời của tôi cho bao nhiêu lỗ? (vâng, tôi đang nhảy vào nhóm, bây giờ tôi đã thấy hai người khác chuyển câu trả lời của họ).


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.