Tâche
Vous recevrez un ensemble de cercles dans le plan avec leurs centres sur la ligne y = 0 . Il est garanti qu'aucune paire de cercles n'a plus d'un point commun.
Votre tâche consiste à déterminer le nombre de régions dans lesquelles les cercles divisent le plan. Une région est un ensemble de points contigus à inclusion maximale ne coupant aucun des cercles.
Vous devez écrire un programme qui calcule cette réponse lorsque vous recevez une description des cercles.
Voici un exemple:
Sur le côté gauche, vous voyez les cercles dessinés dans l'avion. Cependant, dans la moitié droite de l'image, les régions produites par les cercles sont colorées distinctement (une couleur par région). Il y a six régions dans cet exemple.
Contribution
La première ligne de l'entrée contient un nombre N
, le nombre de descriptions de cercle à suivre. Cette ligne est facultative, si votre solution fonctionne sans elle, c'est très bien.
Les N
lignes suivantes contiennent chacune deux entiers, x i et r i > 0 , représentant un cercle de centre (x i , 0) et de rayon r i .
Il est garanti qu'aucune paire de cercles n'a plus d'un point commun. Il est en outre garanti que x i et r i ne dépassent pas 10^9
en valeur absolue (ils s'intègrent donc confortablement dans un entier 32 bits).
L'entrée peut être:
lire de STDIN
lire à partir d'un fichier nommé
I
dans le répertoire courant
Alternativement, l'entrée pourrait être:
disponible sous forme de chaîne (y compris les sauts de ligne) dans une variable globale
sur la pile
Sortie
Il doit s'agir d'un seul entier, le nombre de régions produites. Cela doit être écrit dans STDOUT ou dans un fichier nommé O
dans le répertoire courant.
Règles
Le code le plus court en octets gagne
+200 octets de pénalité si votre code n'a pas de polynôme d'exécution + complexité spatiale dans
n
Bonus de -100 octets pour le pire cas d'exécution attendu + complexité de l'espace
O(n log n)
Bonus de -50 octets pour le pire cas d'exécution attendu + complexité de l'espace
O(n)
Bonus de -100 octets pour une exécution déterministe + complexité de l'espace
O(n)
Lors de l'évaluation de l'exécution:
Supposons que les tables de hachage aient un
O(1)
temps d'exécution prévu pour l'insertion, la suppression et la recherche, quelle que soit la séquence d'opérations et les données d'entrée. Cela peut être vrai ou non, selon que l'implémentation utilise la randomisation.Supposons que le tri intégré de votre langage de programmation prenne un
O(n log n)
temps déterministe , oùn
est la taille de la séquence d'entrée.Supposons que les opérations arithmétiques sur les nombres saisis ne prennent que du
O(1)
temps.Ne présumez pas que les nombres saisis sont liés par une constante, bien que, pour des raisons pratiques, ils le soient. Cela signifie que les algorithmes comme le tri par radix ou le tri par comptage ne sont pas du temps linéaire. En général, les très grands facteurs constants doivent être évités.
Exemples
Contribution:
2
1 3
5 1
Sortie: 3
Contribution:
3
2 2
1 1
3 1
Sortie: 5
4
7 5
-9 11
11 9
0 20
Contribution:
9
38 14
-60 40
73 19
0 100
98 2
-15 5
39 15
-38 62
94 2
Sortie: 11
Astuces
Nous pouvons utiliser l'idée suivante pour une solution très compacte. Permet d'intersecter l'ensemble des cercles avec l'axe X et d'interpréter les points d'intersection comme des nœuds dans un graphique plan:
Chaque cercle produit exactement 2 arêtes dans ce graphique et jusqu'à deux nœuds. Nous pouvons compter le nombre de nœuds en utilisant une table de hachage pour garder une trace du nombre total de bordures gauche ou droite distinctes.
Ensuite, nous pouvons utiliser la formule caractéristique d'Euler pour calculer le nombre de faces d'un dessin du graphique:
V - E + F - C = 1
F = E - V + C + 1
Pour calculer C
le nombre de composants connectés, nous pouvons utiliser une recherche en profondeur d'abord .
Remarque: Cette idée de problème est empruntée à un récent concours de programmation croate , mais ne trichez pas en regardant les contours de la solution. :)
n log n
bonus? De plus, j'ai une nouvelle solution conceptuellement nouvelle. Dois-je poster une nouvelle réponse ou remplacer l'ancienne? (Je préférerais l'ancien, au cas où ma nouvelle solution ne serait pas vraiment correcte)Réponses:
Mathematica,
125122 - 150 = -28 caractèresJe ne connais pas la complexité de la fonction intégrée
ConnectedComponents
.Usage:
la source
ConnectedComponents
complexité du pire des cas est linéaire, donc s'il y a des composants O (n), ce serait bien. Je ne comprends pas Mathematica, donc je ne peux pas dire si c'est globalement O (n) et si je me qualifie pour le bonus -150? Je pense que oui. Dois-je simplement l'exécuter avec une entrée dans STDIN?Rubis -
312306285273269259 caractèresCette réponse a été remplacée par mon autre approche qui utilise beaucoup moins de caractères et s'exécute
O(n log n)
.Okay allons-y. Pour commencer, je voulais juste une implémentation fonctionnelle, donc ce n'est pas encore optimisé algorithmiquement. Je trie les cercles du plus grand au plus petit et je construis un arbre (les cercles inclus dans les autres cercles sont les enfants de ces plus grands). Les deux opérations prennent
O(n^2)
au pire etO(n log n)
au mieux. Ensuite, je parcourt l'arbre pour compter les zones. Si les enfants d'un cercle remplissent tout son diamètre, il y a deux nouvelles zones, sinon il n'y en a qu'une. Cette itération prendO(n)
. J'ai donc une complexité globaleO(n^2)
et je n'ai droit ni à une récompense ni à une pénalité.Ce code attend que l'entrée sans le nombre de cercles soit stockée dans une variable
s
:Version non golfée (attend l'entrée en variable
string
):la source
11
. Pour celui dans votre commentaire9
.10
et8
avec ma version non golfée, mais11
et9
avec ma version golfée actuelle: DRuby,
203183173133 - 100 = 33 caractèresVoici donc une approche différente. Cette fois, je trie les cercles par leur point le plus à gauche. Les cercles se touchant à leur point le plus à gauche sont triés du plus grand au plus petit. Cela prend
O(n log n)
(enfin, Ruby utilise le tri rapide, donc en fait,O(n^2)
mais l'implémentation du tri par fusion / segment de mémoire dépasse probablement la portée de ce défi). Ensuite, j'itère cette liste en me souvenant de toutes les positions les plus à gauche et à droite des cercles que j'ai visités. Cela me permet de détecter si une série de cercles se connecte tout au long d'un cercle plus grand englobant. Dans ce cas, il existe deux sous-zones, sinon une seule. Cette itération ne prend queO(n)
donner une complexité totaleO(n log n)
qui se qualifie pour la récompense de 100 caractères.Cet extrait s'attend à ce que l'entrée soit fournie via un fichier dans les arguments de ligne de commande sans le nombre de cercles:
Version non golfée (attend l'entrée dans une variable
string
):la source
-1 1 1 1 0 2 4 2 0 6
. Je vais réfléchir à comment résoudre ce problème d'ici demain soir (j'espère).Julia - 260-100 (bonus?) = 160
MISE À JOUR: En réfléchissant un moment, j'ai compris que le problème avec ma méthode n'était que lorsque les cercles n'étaient pas connectés, alors j'ai eu une idée, pourquoi ne pas les connecter artificiellement? Le tout satisfera donc la formule d'Euler.
F = 2 + EV (V = 6, E = 9)
[Ne pas travailler avec des cercles imbriqués, donc ce n'est pas une réponse au problème pour les cas généraux]
Code :
la source
2 -10 1 10 1
.n=2
, les cercles sont(C=(-10,0), r=1)
et(C=(10,0), r=1)
4 0 2 1 1 10 2 11 1
mais je ne pense pas que je puisse vous donner beaucoup plus de cas de test, ce serait un peu injusteSpidermonkey JS,
308, 287, 273 - 100 = 173Je pense que si je réécrivais cela en Ruby ou Python, je pourrais enregistrer des caractères.
Code:
Algorithme:
Je ne suis pas terriblement doué pour la notation O, mais je pense que c'est O (n) car je boucle effectivement dans chaque cercle 3 fois (création, gauche, droite) et trie également les clés de la carte (et je trie pour O ( n log n) mais qui disparaît). Est-ce déterministe?
la source
r
boucle et lal
boucle en une seule instruction, je l'apprécierais.JavaScript (ES6) -
255254 Caractères -100250 Bonus =1554Suppose que la chaîne d'entrée se trouve dans la variable
S
et renvoie le nombre de régions à la console.La complexité temporelle est maintenant O (N).
Cas de test 1
Les sorties:
3
Cas de test 2
Les sorties:
5
Cas de test 3
Les sorties:
6
Cas de test 4
Les sorties:
11
Cas de test 5
Les sorties:
105
La version précédente
Avec commentaires:
La complexité temporelle totale est O (N) pour tout sauf le tri qui est O (N.log (N)) - cependant en le remplaçant par un tri par compartiment, cela réduira la complexité totale à O (N).
La mémoire requise est O (N).
Devinez ce qui est le prochain sur ma liste de tâches ... trier en moins de 150 caractères.Terminéla source
O(n)
(en faitO(n+k)
),O(n^2)
ouO(n log n)
pire, selon l'algorithme de tri utilisé dans les compartiments, vous devez donc le faire en 50 caractères.