Revision fa2cd768-66fd-49f4-a3f3-57d59e010e3e - Code Golf Stack Exchange

# [MATL](https://github.com/lmendo/MATL), <s>48</s> <s>44</s> <s>42</s> <s>37</s> 33 bytes

_Quite a few bytes saved thanks to [rahnnema's idea (Octave answer)](http://codegolf.stackexchange.com/a/104702/36398) of collapsing two convolutions into one_

 t5BQ4B&vX^Z+*ssGt3Y6Z+1=*&fdwdYy/

This takes the input as a binary matrix, with `;` as row separator. `1` corresponds to hash and `0` to space.

[Try it online!](https://tio.run/nexus/matl#@19i6hRo4qRWFhEXpa1VXOxeYhxpFqVtaKullpZSnhJZqf//f7SBAio0BEMYbahggA1ao@tBpQ2w68OhC68eBUMydBmSYZchhgtxmIzJszbEEgLo6gzRQ9QaFtr49eEKQ5xxgw3GAgA) Or [verify all test cases](https://tio.run/nexus/matl#zVa7DsIwDNz5ik4MdCAnHovFgtg6ITHwUBED4gdAIL6@SJWKaBrbaZpIKENVXRzH57Ody76oHov1dr4eP/fnYz6534vH7LA85lhNxrfr63p4T6vNrjqZrL1Qr@aLzLgW2Tbtr3HbMVaiTYYAKwT4QueGzMndP4KDAXsfbEapYVu24zhkc@Na5egknk59UWPFweIBKAJvBUFrps0zuTPkUkHHmjiWIUSEQJ6HxutVeclRRuP0WxuGRfkOJKNG7V5al8IAlIvXp7JNXL919UPqGCT3L8V7Dxwh@dKyHQnX9RSDHz1/snJ8qnA4rnUXnwmhzQgI8UPwP5Q/JNNvetxPX@n1Y3lh8y@/Ar57SH6/QMShnK/O7Oj67Tmd/w5PVz/x@l/3Ld0/v98d5Qc).

[Here's](https://tio.run/nexus/matl#tZVBDoMgEEX3nmKSn5R9t249QnetSe9/CRsQlRm@CJiaGM0bGD9/Bly@w/PzmKbhtSxvJ/EC4G/IcblRtjDiLTgNmyiKYRRnI02eTtofPgyYLwb9OKT5dxW3ytVqk4XNw@FLnObGEhFkJMosElxmhhACS7A6pvLAfj0jwOW66vRoArlP0sIFgrRWkahOpUSQEd3ALmuMM2L0sDFVmZM8ocv0jvPDwHWX0xMNxALiUwtiDtdKZVbkntLWqESkN@lWJXvVjtqL0qgeXRXqR9zofle3ucav/CQL0KJw5huUj6LnUnOFCifRn1BftRv6fv91XZizWjj/AA) a format converter that takes inputs as 2D char arrays (again, with `;` as separator) and produces string representations of the corresponding binary matrices.

###Explanation

This was fun! The code uses <s>three</s> two 2D-convolutions, each for a different purpose:

 1. To detect vertical and horizontal neighbours, which contribute a distance of `1`, the requires mask would be

 0 1 0
 1 0 1
 0 1 0

 But we only want each _pair_ of neighbours to be detected once. So we take half the mask (and the last row of zeros can be removed):

 0 1 0
 1 0 0

 To detect diagonal neighbours, which contribute a distance of `sqrt(2)`, the mask would be

 1 0 1
 0 0 0
 1 0 1

 but by the same reasoning as above it becomes

 1 0 1
 0 0 0

 If mask is multiplied by `sqrt(2)` and added to the first, the two convolutions can be replaced by one with the mask

 sqrt(2) 1 sqrt(2)
 1 0 0

 2. To detect start and end points. These are by definition the points with only one neighbour. Se we convolve with 

 1 1 1
 1 0 1
 1 1 1

 and see which points give `1` as result.

To generate mask 1 it's shorter to produce its square and then take the square root. Mask 2 is a predefined literal.

 t % Take input matrix implicitly. Duplicate
 5B % 5 in binary: [1 0 1]
 Q % Add 1; [2 1 2]
 4B % 4 in binary: [1 0 0]
 &v % Concatenate vertically
 X^ % Square root of each entry
 Z+ % 2D convolution, maintaining size
 * % Multiply, to only keep results corresponding to 1 in the input
 ss % Sum of all matrix entries. This gives total distance
 Gt % Push input again. Duplicate
 3Y6 % Predefined literal. This gives third mask
 Z+ % 2D convolution, maintaining size
 1= % Values different than 1 are set to 0
 * % Multiply, to only keep results corresponding to 1 in the input
 &f % Push array of row indices and array of column indices of nonzeros
 d % Difference. This is the horizontal difference between start and end
 wd % Swap, difference. This is the vertical difference between start and end 
 Yy % Hypothenuse. This gives total distance in straight line
 / % Divide. Display implicitly

AltStyle によって変換されたページ (->オリジナル) /