14
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Can we assume that the input is padded to a rectangle with spaces? \$\endgroup\$ – Martin Ender Feb 6 '16 at 10:14
  • \$\begingroup\$ Why a complete program? Usually functions are also allowed, and I don't see a good reason for this challenge to be restrictive. \$\endgroup\$ – nimi Feb 6 '16 at 11:22
  • \$\begingroup\$ @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. \$\endgroup\$ – Logic Knight Feb 6 '16 at 12:17
  • \$\begingroup\$ @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. \$\endgroup\$ – Logic Knight Feb 6 '16 at 12:25
  • \$\begingroup\$ @CarpetPython no I mean whether we can assume that all lines of the input have the same length. \$\endgroup\$ – Martin Ender Feb 6 '16 at 12:54
14
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ How can that detect coastlines on the edge of the input? \$\endgroup\$ – feersum Feb 6 '16 at 0:06
  • \$\begingroup\$ I pad it first, I forgot to say that. \$\endgroup\$ – Maltysen Feb 6 '16 at 0:06
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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 \$\endgroup\$ – edc65 Feb 6 '16 at 10:15
  • \$\begingroup\$ 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 \$\endgroup\$ – edc65 Feb 6 '16 at 10:18
  • \$\begingroup\$ @edc65 Ah, of course, I lose two bytes by having to capture the inner array value. Also, nice catch on that replace parameter. \$\endgroup\$ – Neil Feb 6 '16 at 11:00
2
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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