MATL , 54 51 49 octets
n:"G~1@(2Y6Z+leG45>1e*5M@)*]vtz:"otY*g]G48-X:*sX>
L'entrée est un tableau de caractères 2D au format MATL (AB), avec ;
comme séparateur de ligne. Les entrées dans l'exemple et dans les cas de test sont respectivement:
['11-011123';'111-010--';'0010---01';'111-01234']
['1']
['1-1-1-1';'-1-1-1-';'2-1-1-1';'-1-1-1-']
['12-45-';'4-65-9';'87-654';'12-487';'45----';'684764']
['111-12';'------';'21--10']
Essayez-le en ligne!
Explication
Cela fonctionne en construisant une matrice d'adjacence du graphe définie par la relation "étant connecté". Par exemple, considérons le champ 3 × 4
52-4
15-8
3-72
Les entrées dans un tableau 2D sont facilement décrites dans MATL en utilisant l'indexation linéaire (en colonne). Dans le cas 3 × 4, l'indice linéaire de chaque entrée est donné comme
1 4 7 10
2 5 8 11
3 6 9 12
La matrice d'adjacence est construite par étapes en utilisant la multiplication matricielle. Dans un premier temps, les voisins immédiats sont pris en compte. Par exemple, le point indexé 3 est voisin de lui-même et de celui d'index 2. Ce n'est pas un voisin de 6 car ce point ne contient pas de nombre selon le champ. Dans cet exemple, la matrice d'adjacence de la relation "voisin immédiat" est la matrice 12 × 12 L donnée comme
1 1 0 1 0 0 0 0 0 0 0 0
1 1 1 0 1 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0
1 0 0 1 1 0 0 0 0 0 0 0
0 1 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 1 0 1 1
(On peut voir que la colonne 3 a une valeur 1
aux lignes 2 et 3.) Cette matrice est toujours symétrique et sa diagonale a une valeur 1
pour les points qui ne contiennent pas -
.
L'étape suivante serait la matrice d'adjacence de la relation "connectée avec au plus un point entre les deux ". Pour l'obtenir, il suffit de multiplier L par lui-même et de définir des entrées non nulles sur 1
. En général, la matrice d'adjacence de la relation "connecté par un chemin", M , est obtenue en élevant L à un exposant (au sens de la matrice) qui représente la longueur de chemin maximale possible. Une limite supérieure de la longueur de trajet maximale est le nombre d'entrées non nulles dans L .
Le calcul direct de la puissance de la matrice peut provoquer un débordement, car de grands nombres se produisent rapidement. Il est donc préférable de multiplier progressivement par la même matrice, en convertissant les entrées non nulles en 1 après chaque étape pour éviter la formation de grands nombres.
La colonne i de M représente les points qui sont connectés (par n'importe quel chemin) au point i . Maintenant, le champ de niveau peut être réduit à un vecteur de colonne c dans un ordre linéaire, où chaque entrée contient le nombre correspondant ou une valeur indéfinie pour -
. Dans ce cas, c serait
5
1
3
2
5
-
-
-
7
4
8
2
La multiplication de chaque colonne de M par c élément par élément et le calcul de la somme de chaque colonne donne, pour chaque point i , le score total de la zone à laquelle appartient le point i . Une zone est définie par tous les points qui sont mutuellement connectés. Notez que de nombreuses colonnes donneront le même résultat; à savoir, les colonnes i et j donneront la même somme si les points i et j sont connectés (appartiennent à la même zone). Le résultat final est le maximum de ces sommes.
% Implicitly take input: 2D char array
n: % Range [1,...,N], where N is number of entries in the input
" % For loop. Each iteration builds a row of matrix L
G % Push input again
~ % Logical negate: transform into matrix of zeros
1 % Push 1, to be written into a matrix entry
@ % Iteration index. Ranges from 1 to N
( % Write that 1 into the N-th entry (linear order)
2Y6 % Push array [0 1 0; 1 1 1; 0 1 0]: mask of immediate neighbours
Z+ % Convolve and keep same-size result
le % Linearize into row array
G45> % Array of same size as the input that contains 1 for numbers, 0 for '-'
1e % Linearize into row array
* % Multiply element-wise
5M % Push last array again: 1 for numbers, 0 for '-'
@) % Get 0 or 1 value of that array corresponding to current iteration
* % Multiply. This is to give a row of zeros for non-numbers
] % End. We have all rows of L in the stack
v % Concatenate all rows into a matrix: L.
tz: % Duplicate. Range [1,...,K], where K is the number of nonzeros in L
" % For loop. Repear K times. This loop computes the 0/1 matrix power
o % Convert matrix entries to double
tY* % Duplicate and matrix-multiply
g % Convert to logical values, that is, nonzero values become 1
] % End. We have matrix M
G48- % Convert input chars to the corresponding numbers by subtractig 48
X: % Linearize into column array. This is vector c
* % Element-wise multiplication with broadcast (implicit repetition)
s % Sum of each column. Gives a row array
X> % Maximum of that row array
% Implicitly display