Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Your task is to find the length of the coastline of a map of islands provided in an ASCII map. The input map will consist of 1 or more # characters that indicate land, and spaces which indicate water. The coastline is considered to be any edge between land and water, including inland lakes and islands.

Your solution should be a complete program that reads in a file, a string or an array of strings, and outputs a single integer to the screen or stdout. Each input line may have leading or trailing space, and zero or more hash characters. The borders of the map are assumed to be space (water).

Lines may be of different lengths.

Examples:

Input:
##
##
Output: 8

Input:
    ###    ###
  #####     #
   ##
Output: 26

Input:
  #####
  #   #
  # # #
  #   #
  #####
Output: 36

This is code golf, so the smallest byte count wins.

share|improve this question
    
Can we assume that the input is padded to a rectangle with spaces? – Martin Ender Feb 6 at 10:14
    
Why a complete program? Usually functions are also allowed, and I don't see a good reason for this challenge to be restrictive. – nimi Feb 6 at 11:22
    
@MartinBüttner, yes. I was hoping that the "The borders of the map are assumed to be space (water)" covered that. Let me know if I should make that clearer. – CarpetPython Feb 6 at 12:17
    
@nimi, I understand your concern, but as the challenge is 12 hours old, there are 4 answers, and other people may be working on it right now, I am reluctant to change it. – CarpetPython Feb 6 at 12:25
    
@CarpetPython no I mean whether we can assume that all lines of the input have the same length. – Martin Ender Feb 6 at 12:54

Snails, 8 bytes

A
\#o!\#

​​​​​The A option means to count all matching paths rather which starting points a match succeeds from. \# consumes a #, o turns in a cardinal direction, and !\# is a negative assertion which succeeds if there is not a # in front of us.

share|improve this answer
3  
+1, right tool. – lirtosiast Feb 6 at 0:33

Pyth - 25 23 bytes

First it pads the input to a rect. Then counts the occurrences of " #" over the 4 permutations of transpositions and reversals of the input+space.

/ssm_B++;j;d;CB.t.zd" #

Try it online here.

share|improve this answer
    
How can that detect coastlines on the edge of the input? – feersum Feb 6 at 0:06
    
I pad it first, I forgot to say that. – Maltysen Feb 6 at 0:06

ES6, 123 115 114 bytes

a=>a.map((s,i)=>s.replace(/#/g,(h,j)=>r+=(s[j-1]!=h)+(s[j+1]!=h)+((a[i-1]||'')[j]!=h)+((a[i+1]||'')[j]!=h)),r=0)|r

Edit: Saved 9 bytes thanks to @edc65.

share|improve this answer
    
I'm uncertain about this beeing a complete program that writes to stdout or on screen. Apart from this: you should use param of the replace function. a=>['',...a,''].map((s,i,a)=>s.replace(/#/g,(_,j)=>r+=(s[j-1]!=_)+(s[j+1]!=_)+(‌​a[i-1][j]!=_)+(a[i+1][j]!=_)),r=0)|r – edc65 Feb 6 at 10:15
    
And better a=>a.map((s,i)=>s.replace(/#/g,(_,j)=>r+=(s[j-1]!=_)+(s[j+1]!=_)+((a[i-1]||'')[‌​j]!=_)+((a[i+1]||'')[j]!=_)),r=0)|r – edc65 Feb 6 at 10:18
    
@edc65 Ah, of course, I lose two bytes by having to capture the inner array value. Also, nice catch on that replace parameter. – Neil Feb 6 at 11:00

MATL, 42 bytes

c2\FTFt!*Y+2*qFTFtl-4lhhbvv_2X53$Y+t0>)s2/

This accepts the input as a cell array of strings, of the form

{'#####', '#   #', '# # #', '#   #', '#####'}

It first converts the input to a 2D char array, padding with spaces, and then to a matrix of zeros and ones. 2D-convolution is then applied twice, with two different masks: first for expanding the matrix, second for detecting edges.

Try it online!

share|improve this answer

Japt, 22 19 bytes

4o £UzX è"#%s|#$} x

Assumes the input is padded with spaces to form a rectangle. Test it online!

How it works

          // Implicit: U = input string, S = a space
4o £    } // Create the array [0,1,2,3], and map each item X to:
UzX       //  Rotate U by 90 degrees X times.
è"#%s|#$  //  Count the number of "#"s followed by a space, newline, or end-of-string.
x         // Sum the resulting array.
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.