Un labyrinthe est donné sous la forme d'une matrice de 0 (murs) et de 1 (espace accessible à pied) dans n'importe quel format pratique. Chaque cellule est considérée comme connectée à ses 4 voisins orthogonaux (ou moins). Un composant connecté est un ensemble de cellules accessibles à pied toutes connectées de manière transitoire les unes aux autres. Votre tâche consiste à identifier les points de coupure - des cellules praticables qui, si elles étaient transformées en murs, changeraient le nombre de composants connectés. Générez une matrice booléenne avec 1-s uniquement à ces emplacements. Le but est de le faire dans le moins d'octets de code.
La matrice d'entrée comprendra au moins 3 lignes et 3 colonnes. Au moins une de ses cellules sera un mur et au moins une sera accessible à pied. Votre fonction ou programme doit pouvoir traiter l'un des exemples ci-dessous en moins d'une minute sur TIO (ou sur votre propre ordinateur, si la langue n'est pas prise en charge par TIO).
in:
11101001
11011101
00000001
11101111
11110101
00011111
10110001
11111111
out:
01000000
00001001
00000001
00000101
00110000
00010000
00000000
11100000
in:
1111111111111111
1000000000000001
1111111111111101
0000000000000101
1111111111110101
1000000000010101
1011111111010101
1010000001010101
1010111101010101
1010101111010101
1010100000010101
1010111111110101
1010000000000101
1011111111111101
1000000000000001
1111111111111111
out:
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
in:
1011010001111010
1111111011101101
1110010101001011
1111001110010010
1111010000101001
0111101001000101
0011100111110010
1001110011111110
0101000011100011
1110110101001110
0010100111000110
1000110111011010
0100101000100101
0001010101100011
1001010000111101
1000111011000010
out:
0000000000111010
1011110001001000
0000000000000011
0000000100010000
0000010000101000
0000001000000100
0000000011000000
1001100000011110
0000000001000010
0110100001000110
0000100101000010
1000100000000000
0100001000000100
0000000100100001
0000010000111000
0000010000000010
Réponses:
Stax , 40 octets
Exécuter et déboguer des cas de test
Ce programme prend l'entrée comme une chaîne séparée par des espaces contenant des lignes. La sortie est au même format. Voici la représentation ascii non emballée.
L'opération fondamentale pour compter une île fonctionne comme ceci.
'1'
par un'2'
.'12|21'
par'22'
.'1'
dans la chaîne. Le nombre de répétitions est le nombre d'îles..
Programme bonus de 44 octets - cette version entre et sort en utilisant le format de grille.
la source
MATL , 26 octets
L'entrée est une matrice numérique, utilisant
;
comme séparateur de ligne.Essayez-le en ligne! Ou vérifiez tous les cas de test .
Explication
la source
Perl 5 ,
-p0
10510196939089 octetsUtilise
b
au lieu de1
dans l'entrée.Assurez-vous que la matrice sur STDIN se termine par une nouvelle ligne
Essayez-le en ligne!
Utilise 3 niveaux de substitution!
Cette version de 87 octets est à la fois au format d'entrée et de sortie plus facile à interpréter, mais n'est pas en concurrence car elle utilise 3 caractères différents dans la sortie:
Essayez-le en ligne!
Il est facile d'enregistrer un autre octet (l'expression rationnelle
s
modificateur d' régulière) dans les deux versions en utilisant un caractère différent (non alphanumérique) comme terminateur de ligne (au lieu de la nouvelle ligne), mais cela rend à nouveau l'entrée assez illisible.Comment ça fonctionne
Considérez la substitution
Cela trouvera deux lettres différentes et côte à côte horizontalement ou verticalement et les remplacera par
c
. Dans un labyrinthe dont les chemins sont entièrement constitués de la lettre,b
rien ne se passera car les lettres sont les mêmes, mais dès qu'une des lettres est remplacée par une autre (par exemplez
), cette lettre et un voisin seront remplacésc
et une application répétée est un inondation du composant connecté avecc
de la semencez
.Dans ce cas, je ne veux cependant pas un remplissage complet. Je veux remplir un seul des bras voisins
z
, donc après la première étape, je veux qu'ilsz
disparaissent. Cela fonctionne déjà avec lec$2c
remplacement, mais plus tard, je veux redémarrer un remplissage d'inondation le long d'un autre bras à partir du même point et je ne sais plus lequel desc
s était à l'originez
. Donc à la place j'utiliseb | a
estc
,b | c
estc
etz | a
est{
. Donc, dans un labyrinthe avec des chemins composésb
et une grainez
dans la première étapeb
sera remplacée parc
etz
sera remplacée par{
ce qui n'est pas une lettre et ne correspond pas\w
et ne provoquera donc pas de remplissages supplémentaires. Lec
cependant gardera un nouveau remplissage d'inondation aller et un bras voisin de la graine est rempli. Par exemple à partir deJe peux ensuite remplacer tous les c par des non-lettres (par exemple
-
) et les remplacer{
àz
nouveau pour redémarrer le remplissage:et répétez ce processus jusqu'à ce que tous les voisins de la graine aient été convertis. Si je remplace ensuite
{
parz
et remplit:Le
z
reste reste à la fin car il n'y a pas de voisin avec qui faire une transformation. Cela montre clairement ce qui se passe dans le fragment de code suivant:Trouvez la première nouvelle ligne. Le décalage de départ est maintenant
@-
L'expression régulière discutée ci-dessus avec
@{-}
comme nombre de colonnes (puisque plain@-
confond l'analyseur perl et ne le remplace pas correctement)Le
/\n/
réussit toujours et la substitution est vraie tant que nous pouvons encore remplir. Donc la partie après&&
est exécutée si le remplissage d'un bras est effectué. Sinon, le côté gauche correspond à une chaîne videRedémarrez le remplissage et retournez 1 si le remplissage précédent a fait quelque chose. Sinon, retourne la chaîne vide. Tout ce morceau de code est enveloppé à l'intérieur
Donc, si cela est exécuté sur une chaîne de départ
$_
avec unz
à la position de départ, le morceau de code à l'intérieur sera exécuté plusieurs fois, la plupart du temps, ne retournant rien, mais à1
chaque fois qu'un bras voisin est rempli. Effectivement$_
détruit et remplacé par autant de1
s qu'il y a de composants connectész
. Notez que la boucle doit être exécutée jusqu'à la somme des tailles des composants + nombre de fois d'armements mais c'est OK car il y aura "nombre de caractères y compris les sauts de ligne * 2 + 1" fois.Le labyrinthe se déconnecte s'il n'y en a pas
1
(chaîne vide, sommet isolé) ou s'il y a plus de 1 bras (plus de 21
s). Cela peut être vérifié en utilisant l'expression régulière/\B/
(cela donne0
au lieu de1
sur les anciennes versions de Perl. On peut dire laquelle est fausse). Malheureusement, s'il ne correspond pas, cela donnera une chaîne vide au lieu de0
. Cependant, le as:|.: code :seg
été conçu pour toujours renvoyer un nombre impair donc en faisant un&
avec/\B/
cela donnera0
ou1
.Il ne reste plus qu'à parcourir l'ensemble du réseau d'entrée et à chaque position de marche avec
z
et compter les bras connectés. Cela se fait facilement avec:Le seul problème est que dans les positions non accessibles à pied, l'ancienne valeur est conservée. Puisque nous avons besoin de
0
s, cela signifie que le tableau d'entrée d'origine doit avoir0
dans les positions non accessibles et0
correspond\w
dans la substitution d'origine et déclencherait des remplissages. C'est pourquoi j'utilise à la\pL
place (uniquement des lettres de correspondance).la source
Java 8,
503489459455 octets-18 octets grâce à @ceilingcat .
Explication:
Essayez-le en ligne.
la source
Python 2 , 290 octets
Essayez-le en ligne!
-11 octets grâce à Rod
-11 octets grâce à Lynn
la source
F(m,i,j)
pour chaque élément, économisant 11 octetsfor q in((i,j+1),(i,j-1),(i+1,j),(i-1,j)):
->for q in(i,j+1),(i,j-1),(i+1,j),(i-1,j):
- rmF
renvoie implicitementNone
, vous pouvez utiliser à laF(m,i,j)or c
place de[F(m,i,j)]and c
.and m[i][j]
peut être>0<m[i][j]
, et[q[:]for q in m]
peut êtreeval(`m`)
.Wolfram Language (Mathematica) , 118 octets
Essayez-le en ligne!
la source
Javascript 122 octets
Entrée / sortie sous forme de chaîne multiligne.
Pour chaque cellule accessible à pied, mettez un bloc et essayez de remplir les 4 cellules voisines. Si la cellule actuelle n'est pas un point de coupure, le démarrage à partir de n'importe quel voisin ouvert les remplira tous. Sinon, j'ai besoin de plus d'une opération de remplissage pour atteindre toutes les cellules voisines.
Moins golfé
Tester
la source