高尔夫守则:伯爵群岛


31

一个简单的比赛,受到这个stackoverflow问题的启发:

您将获得一张由卫星拍摄的表面图像,该图像是位图,其中水用'标记.,土地用'标记*。相邻的组*组成一个岛。(*如果两个' '是水平,垂直或对角线邻居,则它们是相邻的)。您的任务是打印位图中的岛数。

一个人*也算作一个小岛。

样本输入:

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

样本输出:

5

优胜者是代码中字节数最少的条目。


我不明白逻辑。右上角的5星不是被视为一个岛屿吗?那么您的示例有4个岛。
2012年

屏幕无法包裹。每个角落都有一个岛+ *孤岛
克劳迪乌(Claudiu)2012年

2
但是根据您的定义,孤岛是一组“ *”字符,表示多个。
acolyte 2012年

哦,很公平。独立服务器*也是孤岛。
克劳迪(Claudiu)2012年

Answers:


30

Mathematica 18818517011513046 48字符

说明

在早期版本中,我绘制了棋盘间距彼此为1的位置图。 GraphComponents然后显示岛屿的数量,每个组成部分一个。

当前版本用于MorphologicalComponents查找数组1中物理上连续的簇的簇并对其编号。由于不需要绘图,因此可以节省大量代码。


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

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

5


怎么运行的

数据作为数组输入;在Mathematica中,这是一个列表列表。

在输入数组中,通过替换将数据转换为10

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

其中/.是后缀ReplaceAll规则的后缀形式。这实际上将阵列转换为黑白图像。我们需要做的就是应用功能Image

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

岛屿

白色正方形对应于值为1的单元格。

下图显示了该方法使用的一些步骤。输入矩阵仅包含10。输出矩阵用数字标记每个形态簇。(我将输入和输出矩阵都包裹起来MatrixForm以突出显示它们的二维结构。)

MorphologicalComponents1s 替换为与每个单元的簇号相对应的整数。

处理中

Max 返回最大的群集号。


显示岛屿

Colorize 将为每个岛唯一上色。

着色


这不像在v7上写的那样工作,因为MorphologicalComponents想要一个Image,但是即使在v9上也不应该Max@MorphologicalComponents[d/.{"."->0,"*"->1}]吗?也就是说,更换先完成吗? Max在更换之前会消失,不是吗?
威兹德先生2013年

我有V9,@ Mr.Wizard正确。正确的数字是46个字符。
Murta,2013年

@ Mr.Wizard替换是在应用MorphologicalComponents之前进行的。必须是优先事项。
DavidC

@DavidCarraher,您好,我的意思不是关于“->”,而是该表达式Max@MorphologicalComponents@d/.{"."->0,"*"->1}不起作用,有意义的是Max@MorphologicalComponents[d /. {"." -> 0, "*" -> 1}],因此您还有一个字符。
Murta,2013年

9

Ruby 1.9(134 121 113 110)

将stdin上的地图或地图的文件名作为第一个命令行参数,并输出到stdout的孤岛数。使用基本的递归填充。一如既往的欢迎改进!

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

与David的colorize相似,您还可以通过更改$_[i]=?.$_[i]=c.to_sp c来显示不同的岛屿puts$_,这将为您提供以下信息:

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

(至少直到您用完数字!)

一些测试用例:

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

5

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

9

*

1个

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

2

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

3


8
我喜欢上一次测试。在盒子里思考!
李斯特先生,2012年

1

C,169个字符

从标准输入读取地图。r(j)尽管看起来确实可以改善递归洪水填充功能,但并没有运气。

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

Python 2 223 203字节

感谢Step HenArnold Palmer删除了20个字符的空格和不必要的括号!

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

我认为使用列表推导可能会减少字节数,但是并没有任何明显的改善。

在这里尝试。

我一直在尝试在n个(邻居)列表周围进行修剪,但没有成功。也许其他人会对该部分有一些想法。


欢迎来到PPCG!通过删除一些空格,这是217个字节。Python解析器真的很宽容:P
Stephen于2008年

您有多余的空白。间中的空格(s.index(l),i)forenumerate(l)if-v[0])<2andp=0:p,和bool(x&n[p])else。您的括号也超出了打印声明中所需的括号,因为您有2个分组set。编辑:被StepHen打败,因为在移动设备上做事情并不理想。
阿诺德·帕尔默

203个字节结合了@StepHen和我的建议,加上一些条件更改。
阿诺德·帕尔默

谢谢你们的帮助!Python的宽大处理让我感到惊讶:)
拯救(Salvation

0

Perl 5,100字节

98个字节的代码+ 2个字节的-p0标志。

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

在线尝试!

我对挑战“ 多少个洞?”的回答的改编(或简化)。您可以找到有关此代码如何在其他答案上工作的解释(解释时间有点长,所以我不希望重新输入整个解释)。


0

Python 2,233字节

与其他答案相比,时间太长。我对这个问题的回答的港口。
在线尝试

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个字节

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}

不竞争的ES6答案(语言发布日期挑战)为132个字节:

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

我对“ 多少个洞”的回答的港口 (是的,我现在正在追赶潮流,因为我已经看到另外两个人提出了他们的答案)。


0

Python 2,225个字节

g=map(list,input())
q,w,t,r=len(g),len(g[0]),0,range
def l(i,j):
 if 0<=i<q and 0<=j<w and g[i][j]=='1':g[i][j]=0;l(i+1,j);l(i-1,j);l(i,j+1);l(i,j-1)
 return 1
print sum(l(i,j)if g[i][j]=='1'else 0 for j in r(w)for i in r(q))

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.