Cercles d'emballage

21

Jetez un oeil à cette image. Plus précisément, comment les trous sur les extrémités sont disposés.

entrez la description de l'image ici

( Source de l'image )

Remarquez comment les tuyaux de cette image sont placés dans un motif hexagonal. On sait qu'en 2D, un réseau hexagonal est le plus dense des cercles. Dans ce défi, nous nous concentrerons sur la minimisation du périmètre d'un emballage de cercles. Une façon utile de visualiser le périmètre est d'imaginer mettre un élastique autour de la collection de cercles.

La tâche

Étant donné un entier positif nen entrée, montrez une collection de ncercles aussi serrés que possible.

Règles et clarifications

  • Supposons que les cercles ont un diamètre de 1 unité.
  • La variable à minimiser est la longueur du périmètre, qui est définie comme étant la coque convexe des centres des cercles du groupe. Jetez un oeil à cette image:

entrez la description de l'image ici

Les trois cercles en ligne droite ont un périmètre de 4 (la coque convexe est un rectangle 2x0 et les 2 sont comptés deux fois), ceux disposés selon un angle de 120 degrés ont un périmètre d'environ 3,85 et le triangle a un périmètre de seulement 3 unités. Notez que j'ignore les unités pi supplémentaires que serait le périmètre réel parce que je ne regarde que les centres des cercles, pas leurs bords.

  • Il peut y avoir (et il y en aura presque certainement) de multiples solutions pour tout n. Vous pouvez produire n'importe lequel de ces éléments à votre discrétion. L'orientation n'a pas d'importance.
  • Les cercles doivent être sur un réseau hexagonal.
  • Les cercles doivent avoir au moins 10 pixels de diamètre et peuvent être remplis ou non.
  • Vous pouvez écrire soit un programme soit une fonction.
  • L'entrée peut être prise via STDIN, comme argument de fonction ou équivalent le plus proche.
  • La sortie peut être affichée ou sortie dans un fichier.

Exemples

Ci-dessous, j'ai des exemples de sorties valides et invalides pour n de 1 à 10 (exemples valides uniquement pour les cinq premiers). Les exemples valides sont à gauche; chaque exemple à droite a un périmètre plus grand que l'exemple valide correspondant.

entrez la description de l'image ici

Un grand merci à steveverrill pour son aide à la rédaction de ce défi. Bon emballage!

El'endia Starman
la source
3
En attendant Hexagony, je parie. ; D
Addison Crump
@VoteToClose: Je ne pense pas qu'Hexagony ait une sortie graphique, mais MAN, ce serait génial!
El'endia Starman
@ El'endiaStarman Eh bien, vous pourriez écrire un SVG sur stdout, mais je ne pense pas que je vais le faire ...: P
Martin Ender
1
Wow, personne ne m'a remercié en gras pour mes commentaires dans le bac à sable auparavant. Je rougis :-D Bien sûr, j'ai commenté parce que j'ai aimé le défi, même si je ne sais pas si je vais avoir le temps d'y répondre.
Level River St
D'après ma discussion avec Reto Koradi sur la réponse de user81655, je pense que le plus grand hexagone que nous verrons avec des coins pointus est la longueur latérale 7d (8 cercles.) C'est N = 169 cercles au total. Vous pourriez envisager de limiter le problème à ce nombre, ce qui donnerait plus de chances d'obtenir une réponse correcte (actuellement il n'y en a pas) et de pouvoir vérifier. D'un autre côté, il peut être plus intéressant de laisser le problème ouvert à un arbitraire N.
Level River St

Réponses:

4

Mathematica 295 950 octets

Remarque: Cette version encore à jouer résout les problèmes soulevés par Steve Merrill concernant mes tentatives précédentes.

Bien qu'il s'agisse d'une amélioration par rapport à la première version, il ne trouvera pas la configuration de poignée la plus dense où l'on chercherait une forme globale circulaire plutôt qu'hexagonale.

Il trouve des solutions en construisant un hexagone intérieur complet (pour n> = 6, puis examine toutes les configurations pour compléter la coque extérieure avec les cercles restants.

Fait intéressant, comme Steve Merrill l'a noté dans les commentaires, la solution pour les n+1cercles ne consiste pas toujours en la solution pour n cercles avec un autre cercle ajouté. Comparez la solution donnée pour 30 cercles à la solution donnée pour 31 cercles. (Remarque: il existe une solution unique pour 30 cercles.)

m[pts_]:={Show[ConvexHullMesh[pts],Graphics[{Point/@pts,Circle[#,1/2]&/@ pts}], 
ImageSize->Tiny,PlotLabel->qRow[{Length[pts],"  circles"}]],
RegionMeasure[RegionBoundary[ConvexHullMesh[pts]]]};
nPoints = ((#+1)^3-#^3)&;pointsAtLevelJ[0] = {{0,0}};
pointsAtLevelJ[j_]:=RotateLeft@DeleteDuplicates@Flatten[Subdivide[#1, #2, j] &@@@
Partition[Append[(w=Table[j{Cos[k Pi/3],Sin[k Pi/3]},{k,0,5}]), 
w[[1]]], 2, 1], 1];nPointsAtLevelJ[j_] := Length[pointsAtLevelJ[j]]
getNPoints[n_] := Module[{level = 0, pts = {}},While[nPoints[level]<=n, 
pts=Join[pointsAtLevelJ[level],pts];level++];Join[Take[pointsAtLevelJ[level],n-Length[pts]],
pts]];ns={1,7,19,37,61,91};getLevel[n_]:=Position[Union@Append[ns,n],n][[1, 1]]-1;
getBaseN[n_] := ns[[getLevel[n]]];pack[1]=Graphics[{Point[{0,0}], Circle[{0, 0}, 1/2]}, 
ImageSize->Tiny];pack[n_]:=Quiet@Module[{base = getNPoints[getBaseN[n]], 
outerRing = pointsAtLevelJ[getLevel[n]], ss},ss=Subsets[outerRing,{n-getBaseN[n]}];
SortBy[m[Join[base,#]]&/@ss,Last][[1]]]

Certaines vérifications ont entraîné des comparaisons de plus de cent mille cas pour une seule valeur de n (y compris les symétries). Il a fallu environ 5 minutes pour exécuter les 34 cas de test au total. Inutile de dire qu'avec une n'sapproche plus large, cette approche par force brute se révélerait bientôt impossible. Il est certain que des approches plus efficaces existent.

Les nombres à droite de chaque emballage sont les périmètres des coques convexes bleues respectives. Ci-dessous la sortie pour 3 < n < 35. Les cercles rouges sont ceux ajoutés autour d'un hexagone régulier.

disques


DavidC
la source
1
Comme je l'ai mentionné dans la réponse de l'utilisateur 81655, le cercle unique en saillie sur 22 (et 17, 25, 28, 31, 34) serait mieux placé au milieu de la rangée de cercles sur laquelle il se trouve.
Level River St
Je le pensais aussi, mais j'ai remarqué que 9, qui a également un cercle en saillie, était considéré comme correct. Quand j'aurai un peu de temps, je comparerai les mesures des coques convexes (des centres).
DavidC
en 9, le cercle en saillie est de 1/4 ou 3/4 le long de la rangée plate, donc cela ne fait aucune différence. en 17, 22, 25, 28, 31 le cercle en saillie est 1/6, 3/6 ou 5/6 le long, donc la position médiane est meilleure (pensez à tirer une corde sur le côté: il est plus facile de tirer du milieu parce que cela façon dont la corde a moins d'extension à faire. Dans 34 (et 35), nous avons 1/8, 3/8, 5/8 et 7/8 le long du côté plat. Donc pour ceux-ci, nous devrions choisir 3/8 et 5/8 avant le 1/8 et le 7/8
Level River St
Vous avez absolument raison et cela est confirmé par des mesures.
DavidC
C'est génial! La transition 30-> 31 montre que nous ne pouvons pas simplement prendre la forme précédente et ajouter un cercle à l'extérieur (cela aurait donné un périmètre de 16,464.) Il y a aussi au moins un cas où vous auriez pu juste ajouter un cercle à l'extérieur, mais a choisi un arrangement différent: 12-> 13
Level River St