Défi
Étant donné l'entrée graphique d'une forme, déterminez le nombre de trous qu'il contient.
Pas de doublon
Cette question a été marquée comme un double possible des îles Count . Je crois que ce défi est différent du défi de Count Island parce que dans celui-ci, vous devez comprendre comment éliminer les blocs qui touchent la frontière.
Contribution
L'entrée sera donnée sous la forme d'une forme d'entrée 2D, soit une chaîne multiligne, un tableau de chaînes ou un tableau de tableaux de caractères. Cela représente la forme. La forme est garantie d'être en une seule pièce, reliée par le bord. Veuillez spécifier comment vous souhaitez que les données soient prises.
Production
La sortie est un entier unique indiquant le nombre de trous dans la forme. Une nouvelle ligne de fin est autorisée, mais aucun autre espace de début ou de fin. En d'autres termes, la sortie doit correspondre à l'expression régulière ^\d+\n?$
.
Qu'est-ce qu'un trou?
Ce sont des trous simples:
####
# #
# #
####
####
# #
# ##
###
#####
# # #
# #
#####
Ce ne sont pas des trous:
########
########
# ####
# ####
# ######
#
########
###
#
###
##########
#
# ########
# # #
# # #### #
# # ## #
# ###### #
# #
##########
À peu près, si l'écart rejoint le bord extérieur, ce n'est pas un trou.
Cas de test
#####
# # # -> 2
#####
#####
#
# ### -> 1
# # #
#####
####
## # -> 1 (things are connected by edges)
# ##
####
###
### -> 0 (You must handle shapes with no holes, but input will always contain at least one filled space)
###
Vous pouvez utiliser n'importe quel caractère à la place du «#» et à la place des espaces.
Critères de notation des objectifs
Le score est donné comme le nombre d'octets dans votre programme.
Gagnant
Le gagnant sera la soumission avec le score le plus bas, avant le 4 avril.
###|# #|##
comme cas de test? Cela devrait être0
, non?Réponses:
MATLAB / Octave, 18 octets
Essayez-le en ligne!
Il s'agit d'une fonction anonyme prenant une matrice logique en entrée. L'objet est formé par les
true
entrées (avec la connectivité spécifiée), l'espace vide sont lesfalse
entrées.bweuler
calcule ensuite le nombre d'Euler de l'image binaire représentée par cette matrice, c'est-à-dire le nombre d'objets moins le nombre de trous.la source
Mathematica,
5957 octetsIl y a une fonction intégrée pour cela. Prend l'entrée comme une matrice 2D de
1
s (murs) et0
s (trous). Pour plus de commodité, voici tous les cas de test dans ce format d'entrée:Solution alternative, 59 octets
C'était mon approche originale. Il est également basé sur les composants intégrés liés aux composants, mais ne compte pas directement les trous (à la place, il traite les trous eux-mêmes comme des composants).
Prend le même format d'entrée que ci-dessus, mais avec les rôles de
0
s et1
s échangés.La raison pour laquelle je dois convertir ceci en
Image
premier est que, sinon, Mathematica considérerait toutes les1
cellules comme faisant partie d'un seul composant (car il traite la matrice comme une matrice d'étiquette de composant). Par conséquent, le cas échéant1
cellule borde la marge, elle les supprimerait toutes. LorsqueDeleteBorderComponents
est utilisé à la place sur une image, il effectuera une vérification de connectivité implicite pour trouver les composants.Alternativement, je pourrais appeler d'
MorphologicalComponents
abord , ce qui transformerait l'entrée en une matrice d'étiquettes appropriée, mais si je le faisDeleteBorderComponents
ensuite, il n'est plus garanti que l'étiquette de composant maximale correspond au nombre de composants (car je pourrais supprimer un composant plus petit).la source
GenerateBuiltin
. Il génère un intégré pour tout défi qui n'a pas intégré. Aussi, je me sens mal pour la boîte de réception de Martin Ender, donc si vous voulez, continuons cette discussion iciPerl 5 , 154 octets
152 octets de code + 2 octets pour l'
-p0
indicateur.Essayez-le en ligne!
Je pense que le code est assez explicite.
Si vous avez besoin d'explications pour comprendre, voici quelques étapes des transformations effectuées par le programme sur une simple entrée (provenant de ici ), suivies de quelques explications ci-dessous:
Tout d'abord,
s/^ | $/A/gm;s/^.*\K | (?=.*$)/A/&&redo
remplacera les espaces dans la bordure (1er regex pour gauche / droite, 2e pour bas / haut) parA
(je choisis ce caractère assez arbitraire).Ensuite, nous obtenons la largeur de la forme avec
/.*/;$@="@+"-1;
.Maintenant, nous voulons remplacer chaque espace connecté à un
A
par unA
(car si un espace est connecté à unA
, cela signifie qu'il ne peut pas faire partie d'un trou. Cela se fait parfor$%(A,X){(s/$%(.?.?.{$@})? /$%$1$%/s||s/ (.?.?.{$@})?$%/$%$1$%/s)&&redo}
. (Vous remarquerez que cela se fait une fois pour leA
s et un pour lesX
s - les explications pour leX
sont ci-dessous). Il y a deux expressions rationnelles ici:s/$%(.?.?.{$@})? /$%$1$%/s
traite les espaces qui sont à droite ou en bas de aA
. Ets/ (.?.?.{$@})?$%/$%$1$%/s
avec les espaces en haut ou à gauche de aA
.À ce stade, les seuls espaces qui restent dans la chaîne font partie des trous.
Tant qu'il y a encore des espaces, nous répétons:
- Pour savoir combien il y a de trous, nous remplaçons un espace par un
X
(s/ /X/
) et incrémentons le compteur des trous ($\++
), et refaire tout le programme (en fait, nous voulons seulement refaire lafor
boucle , mais c'est moins d'octets pour refaire tout le programme).- Ensuite, la
for
boucle remplacera chaque espace connecté à unX
par unX
, car ils font partie du même trou.À la fin,
$\|=0
garantit que s'il n'y a pas de trous, un0
est imprimé au lieu d'une chaîne vide. Et$\
est implicitement imprimé grâce au-p
drapeau.la source
Python 2, 282 octets
+100 pour gérer les touches diagonales TT_TT (en avons-nous vraiment besoin?)
-119 grâce au guidage @Rod :)
Essayez-le en ligne . Prend un tableau de tableaux de caractères «#» et d'espaces en entrée.
Recherche le premier espace blanc et le marque comme non vide ('#'). Vérifiez récursivement tout ce qui l'entoure, tout en remplissant toutes les cellules vides. Si une cellule vide du "trou" actuel semble être sur le compteur de bordure, elle ne changera pas, sinon elle serait augmentée de 1. Répétez le processus jusqu'à ce qu'il n'y ait plus d'espaces blancs.
la source
sum(A,[])
pour aplatirNone
s, mais ce n'est pas pertinent)x=T[0];y=T[1]
->x,y=T
, vous n'avez (probablement) pas besoin de déclarerg=1
sur la 3ème ligne, et vous pouvez utiliser<
ou>
comparer des chaînes (cela prendra laord()
valeur de chaque caractère) vous permettant de remplacerA[y][x]!='#'
parA[y][x]<'#'
, depuis' '<'#'
.Python 2,
233225222 octetsmath_junkie : -8 octets
Prend un tableau 2D de booléens / entiers (0/1) en entrée
Essayez-le en ligne!
Version formatée:
la source
print sum(m(x,y)...
au lieu dea=
etprint a
C # 7, 364 octets
Moins que satisfait de cela ... peut-être que quelqu'un d'autre peut le régler ... Si j'ai l'énergie plus tard, j'inverserai la première boucle, et voir si cela peut aider à couper les limites.
Essayez-le en ligne
Programme complet, accepte l'entrée vers l'entrée standard, la sortie vers la sortie standard. Utilise des ensembles disjoints pour déterminer les trous provisoires et quand tue, touchez les bordures (avec un peu de dodgyness pour le bord supérieur).
Code formaté et commenté:
la source
Func<List<string>, int>
pour supprimer les trucs fluff et console. Cependant, j'ai vu que vous avez des fonctions locales, donc vous ne pourrez peut-être pas les avoir dans une fonction. Pourrait simplement compiler en une méthodeint h(string[] s) { }
.Escargots , 48 octets
Non golfé:
la source
JavaScript (ES6), 192 octets
Basé sur ma réponse à Détecter les châteaux défaillants . La chaîne est d'abord rembourrée avec des espaces pour créer une zone autour de la forme. Le RegExp recherche ensuite deux carrés adjacents, l'un contenant un
@
, l'autre contenant un espace, et les remplace tous les deux par un@
. S'il ne peut pas faire cela, il remplit un espace avec un@
et le compte comme un nouveau trou. Enfin, un est soustrait pour tenir compte de la zone environnante.la source