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\$
6
  • \$\begingroup\$ Can we assume that the input is padded to a rectangle with spaces? \$\endgroup\$ Feb 6, 2016 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, 2016 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\$ Feb 6, 2016 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\$ Feb 6, 2016 at 12:25
  • \$\begingroup\$ @CarpetPython no I mean whether we can assume that all lines of the input have the same length. \$\endgroup\$ Feb 6, 2016 at 12:54

5 Answers 5

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\$
0
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\$
2
  • \$\begingroup\$ How can that detect coastlines on the edge of the input? \$\endgroup\$
    – feersum
    Feb 6, 2016 at 0:06
  • \$\begingroup\$ I pad it first, I forgot to say that. \$\endgroup\$
    – Maltysen
    Feb 6, 2016 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\$
3
  • \$\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, 2016 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, 2016 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, 2016 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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