| Bytes | Lang | Time | Link |
|---|---|---|---|
| 133 | Python 3 | 240626T074210Z | Jitse |
| nan | Python 3 | 240627T195242Z | Keegan C |
| nan | Python 2 | 170809T015008Z | Solvatio |
| 225 | Python 2 | 170804T093730Z | Keerthan |
| 158 | JavaScript | 170408T204209Z | Neil |
| 233 | Python 2 | 170325T224658Z | Dead Pos |
| 100 | Perl 5 | 170325T193512Z | Dada |
| 048 | Mathematica | 120813T214432Z | DavidC |
| 169 | C | 120820T145004Z | schnaade |
| 110 | Ruby 1.9 134 121 113 | 120814T021917Z | Paul Pre |
Python 3, 133 bytes
I,*g=input(),
w=i=I.find(',')
for c in I:
q={k for k in g if{i-1,i,i+1,i+w}&{*k}};i+=1
if','>c:g={*g,sum(q,(i+w,))}-q
print(len(g))
Takes a comma-separated grid on a single line as input
Python 3, 257 185 165 144 bytes
EDIT Currently doesn't work with forked islands Thanks to Jitse for help I learned a bunch but this binary solution seems to have a fatal flaw.
I looked at this and thought I could solve it close to the optimal by looking at it as a binary addition problem and using bit shifting. Yikes I was wrong. The answer I paste can prob be minimized a bit more but no where near the current python 3 record of 136. Either way I figure someone would get a kick out of this mess.
EDIT - Big thanks to Noodle Person and Jitse for the push to look a bit deeper at this. With some tweaks I got it down to 185! Jitse for another update which trimmed this down even more!
import re
q=input().split(',')
q+='0'
t=0
for o,p in zip(q,q[1]):o=int(o,2);p=int(p,2);t+=len(re.findall('(1+)',bin(o&~(p|p>>1|p<<1))))
print(t)
Python 2, 223 203 Bytes
Thank you to Step Hen and Arnold Palmer for shaving off 20 characters of spaces and unnecessary parenthesis!
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)))
I thought that using list comprehensions might decrease the number of bytes, but it didn't provide any significant improvement.
I keep trying to trim it around the n (neighbors) list, but I haven't been successful. Maybe someone else will have some ideas for that section.
Python 2, 225 bytes
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))
JavaScript, 158 bytes
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}
Noncompeting ES6 answer (language postdates challenge) for 132 bytes:
f=s=>s!=(s=s.replace(RegExp(`([*@])([^]{${w=s.search`
`},${w+2}})?(?!\\1)[*@]`),`@$2@`))?f(s):/\*/.test(s)?f(s.replace(`*`,`@`))+1:0
Port of my answer to How Many Holes? (yes I'm jumping on the bandwagon, now that I've seen two other people port their answers).
Python 2, 233 bytes
Too long, compared to other answers. Port of my answer to this question.
Try it online
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
Perl 5, 100 bytes
98 bytes of code + 2 bytes for -p0 flags.
/.*/;$@="@+"-1;$~="(.?.?.{$@})?";(s/X$~\*/X$1X/s||s/\*$~X/X$1X/s)&&redo;s/\*/X/&&++$\&&redo}{$\|=0
An adaptation (or rather a simplification) of my answer to the challenge How Many Holes?. You can find explanations of how this code works on this other answer (it's a bit long to explain, so I prefer not to retype the entire explanations).
Mathematica 188 185 170 115 130 46 48 chars
Explanation
In earlier versions, I made a graph of positions having a chessboard distance of 1 from each other. GraphComponents then revealed the number of islands, one per component.
The present version uses MorphologicalComponents to find and number clusters of ones in the array--regions where 1's are physically contiguous. Because graphing is unnecessary, this results in a huge economy of code.
Code
Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&
Example
Max@MorphologicalComponents[#/.{"."->0,"*"->1}]&[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}}]
5
How it works
Data are input as an array; in Mathematica, this is a list of lists.
In the input array, data are converted to 1's and 0's by the replacement
/.{"."->0,"*"->1}
where /. is an infix form of ReplaceAll followed by replacement rules. This essentially converts the array into a black and white image. All we need to do is apply the function, Image.
Image[{{".", ".", ".", ".", ".", ".", ".", ".", ".", "*", "*"}, {"*", "*", ".", ".", ".", ".", ".", ".", "*", "*", "*"}, {".", ".", ".", ".", ".", ".", ".", ".", ".", ".", "."}, {".", ".", ".", "*", ".", ".", ".", ".", ".", ".", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", "*", "."}, {"*", ".", ".", ".", ".", ".", ".", ".", ".", ".", "*"}} /. {"." -> 0, "*" -> 1}]
The white squares correspond to the cells having the value, 1.
The picture below shows a some steps the approach uses. The input matrix contains only 1's and 0's. The output matrix labels each morphological cluster with a number. (I wrapped both the input and output matrices in MatrixForm to highlight their two dimensional structure.)
MorphologicalComponents replaces 1s with an integer corresponding to the cluster number of each cell.

Max returns the largest cluster number.
Displaying the Islands
Colorize will color each island uniquely.

C, 169 chars
Reads map from stdin. Had no luck improving the recursive flood-fill function r(j) although it looks like it could be.
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);}
Ruby 1.9 (134 121 113 110)
Takes the map on stdin or the file name of the map as the first command-line argument, and prints the number of islands to stdout. Using a basic recursive flood-fill. Improvements welcome as always!
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
Similar to David's colorize, you can also get it to display the different islands by changing $_[i]=?. to $_[i]=c.to_s and p c to puts$_, which would give you something like this:
.........00
11......000
...........
...2.......
3........4.
3.........4
(at least until you run out of digits!)
Some test cases:
.........**
**......***
...........
...*.......
*........*.
*.........*
5
......*..**....*
**...*..***....*
....*..........*
...*.*.........*
*........***....
*.....*...***...
*.....*...*....*
****..........**
*.........*.....
9
*
1
****
****
....
****
2
**********
*........*
*.******.*
*.*....*.*
*.*.**.*.*
*.*.**.*.*
*.*....*.*
*.******.*
*........*
**********
3
