# C# 7 - <s>414</s> <s>369</s> 327 bytes <!-- language: lang-c# --> ___Edit__: switched to 1D looping, computing `i` and `j` on the fly_ ___Edit__: changed input method, collapsed lookup table, and switched to well defined initial bounds ...and removed the pointless space in the last outer for-loop_ using C=System.Console;class P{static void Main(){var D=C.In.ReadToEnd().Replace("\r","");int W=D.IndexOf('\n')+1,H=D.Length,z=H,k,q,c;int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H;var B=new int[9];for(;z-->0;)for(k=9;k-->0&D[z]%7<1;)if(B[k]<=P())B[k]=P()+1;for(;++z<H;C.Write(q>9?'o':D[z]))for(q=k=9;k-->0;)q*=(c=P()-B[k])>0?0:c<0?1:2;}} [Try It Online](https://tio.run/nexus/cs-core#lZJdT4MwFIbv9ysIZNKOD0EvzFbKkjETTDQuarKLbRcEukmYRT6cyrLfPimD6TaIWm7enue87wltt2@JTxechR8/k5S8qFZIk3BJkLt0koQbrZPUSX2XW4W@x905PgVwvXJibogt9YaqD8TxnsJr6gGY69el4xLAT2Ne5nmIfJpyYzzM@zzycT8H4pSKUNJlO6/dErpIn@UM23IgR7JbNI8AxGbWHndA0L5UdChl50yfF9pGbO4AU/LO5c2T7gzNwxigTFFMDUGmA9xFAdueDSfZrH1l6Aj6czCYBDMD5@GQKSYkfeeVpMywkaWOYz8lIDK7fTEUe8wMi8AI7yMRjDoYuMytsBhoan2t5xpaX@9doM1mu1UbVutvQKgHAvuEkp@CEv4AQrkaQQFLINSDKvmAtFjnUfEb1NR3UTX1esf@z@uB0OQQGof/x7EDJ9PVynFMKlAd7eEVtk4v9ZfH8AU) Complete program, takes input to standard in, prints it to standard out, uses `#`, `.`, and `o`. For each cell, it computes a 'profile' (which is the distance over 8 directions (it appears to compute a ninth for convenience, but this is always `0`), and records a maximum of each of these. It then writes out the whole map again, and replaces any cell which is both on a boundary and not outside any with a 'o'. The commented code below explains how it all works. As per my answer to https://codegolf.stackexchange.com/questions/50829/save-the-geese-from-extinction, this produces the smallest octagon (valid circumnavigation with largest area) which bounds the island. ___Note__: that for once in my life I'm using something from the current decade, and this code requires C# 7 to compile. If you do not have C# 7, there is one line that will need to be replaced, which is clearly marked in the code._ Example usage and output: type t7.txt | IslandGolf1.exe .........ooooooooooo.... ........o....#......o... .......o...#.#.##...#o.. ......o....#.#.###.##.o. .....o....########.##..o ....o.....############.o ...o.#....############.o ..o#.###.##############o .o##.##################o o.####################.o o..##################..o o.##################...o o...################...o o###################...o o#####################.o o.##################..o. o####################o.. o#...##############.o... o##...#############o.... o#.....###....#...o..... .o.....#.........o...... ..ooooooooooooooo....... Formatted and commented code: <!-- language: lang-c# --> using C=System.Console; class P { static void Main() { // \n 10 // # 35 // . 46 // o 111 var D=C.In.ReadToEnd().Replace("\r",""); // map int W=D.IndexOf('\n')+1, // width H=D.Length, // length z=H, // position in map (decomposed into i and j by and for P) k, // bound index q, // bound distance, and later cell condition (0 -> outside, 8 -> inside, >8 -> on boudary) c; // (free), comparison store // 'indexes' into a profile for the point z at index k // effectively {i=z%W,j=z/W,-i,-j,i+j,j-i,-i-j,i-j,0}[k] (inside order is a bit different) (0 const is always treated as 'inside bounds') // each non-zero-const entry describes the distance in one of the 8 directions: we want to maximise these to find the 'outer bounds' // the non-zero-const bounds describe 8 lines, together an octogen int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // new C#7 local method syntax (if you don't have C#7, you can test this code with the line below instead) //k=0;System.Func<int>P=()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // old lambda syntax (must pre-assign k to make static checker happy) var B=new int[9]; // our current bounds, each is initially null (must only call P() when on a #) // B[k] starts off a 0, P() has a +H term, and W+(H/W)<H for W >= 3, so B[k] is assigned the first time we compare it (H-i-j always > 0) for(;z-->0;) // for each cell for(k=9;k-->0& // for each bound D[z]%7<1;) // if this cell is # if(B[k]<=P())B[k]=P()+1; // update bound if necessary (add one so that we define the bound _outside_ the hashes) // z=-1 for(;++z<H; // for each cell C.Write(q>9?'o':D[z])) // print the cell (if q > 9, then we are on the bounds, otherwise, spit out whatever we were before) // check we are not 'outside' any of the bounds, and that we are 'on' atleast one of them for(q=k=9;k-->0;) // for each bound q*=(c=P()-B[k])>0?0: // outside bound (q=0) (??0 is cheaper than (int) or .Value) c<0?1: // inside (preserve q) 2; // on bound (if q != 0, then q becomes > 9) } }