Revision 9e9bdb28-6087-4561-a7db-0e6ac920c372 - Code Golf Stack Exchange

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

 tH4hBZ+*zGt5OhBZ+*z2X^*+Gt3Y6Z+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#@1/iYZLhFKWtVeVeYuoPYRlFxGlpu5cYR5pFaRvaaqmlpZSnRFbq//8fbaCACg3BEEYbKhhgg9boelBpA@z6cOjCq0fBkAxdhmTYZYjhQhwmY/KsDbGEALo6Q/QQtYaFNn59uMIQZ9xgg7EA) Or [verify all test cases](https://tio.run/nexus/matl#zVY9a8MwEN37Kzx1sIfq5aPL0aVkCHjIkiGJcekQSn@AITR/3oGEhFjS3cmyBEWDbJ5Op3v37qTvXd1368Xv56Eqz3W33Ny@Zruvsqq7@f79UOGjfP05no77v7d@te0bUwwHruM@ozC@QbbNcDZ@O8ZKtCkQYYUIX3BOyOzs/hE8DNjrYDNKd7ZlO45DNje@0b404u40FjVWHCwegSLyVBC0ZoY8kz9DPhU41sSxDCEiRPI8Nd6gysuOMhqn59owLMp3IBk1avfSuhQmoFy8IZVt0vq9Vj@kjkFy/1K8j8ARky8t24lwXU8p@NHzJysnpAqn41p3CbkhtDsCQvwQ/E/lD9n0mx8P01d@/Vhe2PzLr4DHGpLfLxBxKPurd3Zy/Y68nf8dnq9@0vU/9y09Pr@PFe0F).


[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 _three_ two-dimensional convolutions, each for a different purpose:

 1. To detect vertical and horizontal neighbours, which contribute a distance of `1`. The mask for that 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

 2. To detect diagonal neighbours, which contribute a distance of `sqrt(2)`. Again, each pair should contribute only once. So the mask

 1 0 1
 0 0 0
 1 0 1

 becomes

 1 0 1
 0 0 0

 3. 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.

The first two matrices are generated efficiently from binary expansions of a vector of two numbers. For example, expanding the vector `[2 4]` into binary produces the mask fo the first case (each number gives rise to a row). `[5 0]` produces the second. The third is a predefined literal.


 t % Take input matrix implicitly. Duplicate
 H4h % Push 2, then 4, concatenate: gives vector `[2 4]`
 B % Convert to binary. Gives first mask
 Z+ % 2D convolution, maintaining size
 * % Multiply, to only keep results corresponding to 1 in the input
 z % Number of nonzeros
 Gt % Push input again. Duplicate
 5Oh % Push 5, then 0, concatenate: gives vector `[5 0]`
 B % Convert to binary. Gives second mask
 Z+ % 2D convolution, maintaining size
 * % Multiply, to only keep results corresponding to 1 in the input
 z % Number of nonzeros
 2X^ % Push 2, take square root
 * % Multiply. Diagonal distances are sqrt(2), not 1
 + % Add. 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 によって変換されたページ (->オリジナル) /