Pour plus d'informations, regardez cette vidéo et passez à A276523 pour une séquence connexe.
Le Mondrian Puzzle (pour un entier n
) est le suivant:
Ajustez des rectangles non congrus dans une n*n
grille carrée. Quelle est la plus petite différence possible entre le plus grand et le plus petit rectangle?
Pour 6
, la différence optimale pour M(6)
est 5
, et peut être démontrée comme suit:
___________
| |S|_______|
| | | L |
| |_|_______|
| | | |
| |_____|___|
|_|_________| (fig. I)
Le plus grand rectangle (L) a une aire de 2 * 4 = 8
et le plus petit rectangle (S) a une aire de 1 * 3 = 3
. Par conséquent, la différence est 8 - 3 = 5
.
Gardez à l'esprit qu'à l'heure actuelle, aucune solution optimale n > 44
n'a été trouvée.
Votre tâche consiste à créer un programme qui génère une grille Mondrian qui contient une solution (non optimale), étant donné un entier n
.
Vous serez testé sur les nombres de 100 à 150. Votre score pour chaque test sera la différence entre le plus grand et le plus petit rectangle. Votre score total est la somme de vos scores pour tous les tests de 100 à 150.
Vous devez présenter votre sortie comme suit:
{number}
{grid}
Où number
est le score (la différence entre le plus grand et le plus petit), et grid
est soit:
- Une chaîne à plusieurs lignes, ou
- Une liste en deux dimensions.
La grille DOIT clairement indiquer où commence et se termine un rectangle.
Règles:
- Votre programme doit correspondre à votre réponse.
- Votre programme doit générer une valeur pour tout nombre compris entre 100 et 150 en 1 heure sur un ordinateur portable moderne.
- Votre programme doit générer la même solution pour un entier à
n
chaque exécution du programme. - Vous devez fournir un lien vers les sorties des 51 solutions (en utilisant Pastebin, Github Gist ... n'importe quoi, vraiment).
- Vous devez avoir au moins deux rectangles sur la grille carrée pour votre solution.
la source
Réponses:
Piet, 9625
(Ça marche enfin!)
Les gens l'ont exigé, alors le voici. Il s'agit d'une solution extrêmement naïve (essentiellement la même que les limites supérieures lâches sur la page OEIS): elle divise chaque carré en seulement deux rectangles.
Cet essentiel contient les détails dans deux fichiers:
?
la sortie standard, c'est donc l' invite d'entrée, suivie immédiatement par le score de sortie, puis la grille.Explication
Ce programme prend un seul numéro
N
en entrée. Si le nombre est impair, le score est le nombre; s'il est pair, le score est le double du nombre.Après avoir sorti la partition, le reste du côté gauche du programme est consacré à remplir la pile avec cinq lots des informations suivantes:
N
)_
ou espace)|
)Le côté droit du programme prend chaque ensemble de quatre valeurs et imprime cette partie de la grille.
la source
C 6108
Cela utilise une version récursive (vraiment itérative) de la solution minimale. Au lieu de diviser le carré en deux rectangles dont l'un est un peu plus grand que la moitié de la surface, il le divise en N rectangles. Le premier rectangle est donc un peu plus grand que
1/N
la surface totale. Ensuite, en prenant le reste, le programme divise un rectangle un peu plus grand que1/(N-1)
le reste et ainsi de suite jusqu'à ce qu'il prenne le reste comme dernier rectangle. Les rectangles sont coupés du reste dans une spirale dans le sens horaire, donc d'abord en haut, puis à droite, etc.Comme il s'agit d'une méthode très directe au lieu d'une recherche sur un large espace, elle s'exécute rapidement - il faut environ 25 secondes (sur un Raspberry Pi) pour examiner 74 solutions chacune pour l'ensemble de problèmes donné.
Mon intention est d'utiliser ces résultats pour mieux informer un algorithme de recherche pour une approche plus sophistiquée.
La sortie donne le score et à la fois un dessin (ascii) et les coordonnées des sommets des rectangles. Les sommets sont dans le sens des aiguilles d'une montre, en partant du coin supérieur gauche du rectangle en question.
Développé à l'aide de gcc 4.9.2-10.
Résultats sur https://github.com/JaySpencerAnderson/mondrian
Code:
la source
C - 2982
Ce programme met en œuvre une recherche dans un large ensemble de résultats. L'important pour que cette recherche soit pratique était d'échouer tôt et / ou de ne pas emprunter de mauvaises voies.
Cela génère un ensemble de rectangles à considérer pour la solution. L'ensemble des rectangles générés évite ceux dont les dimensions ne seraient pas utiles. Par exemple, si le programme essaie de trouver la solution à un carré de 128x128, divisé en 8 rectangles, il générera un rectangle de 128x16. Il ne générera pas que l'on est 120x17 car il n'y a aucune perspective de génération d'un rectangle de 8 de large pour combler le vide à la fin de 120.
La stratégie initiale pour placer des rectangles est de les placer à l'intérieur du périmètre du carré (fonction buildedge). De cette façon, l'algorithme obtient un retour assez rapide à chaque coin pour savoir s'il y a un problème avec la séquence choisie. Tout en plaçant des rectangles, la logique continue de regarder pour voir si des lacunes d'espace se développent qui sont trop étroites pour un rectangle. Une fois le périmètre correctement rempli, la stratégie change pour essayer de faire correspondre l'espace restant avec les rectangles restants (fonction de correspondance).
Une autre chose qui pourrait être intéressante est que cela implémente des transactions avec restauration pour les piles de rectangles.
Ce programme n'essaie pas de trouver le meilleur ajustement possible. Il reçoit un budget (64) et se ferme lorsqu'il trouve la première solution. S'il ne trouve jamais de solution, nous augmentons le budget (par 16) et réessayons. Le temps requis (sur un ordinateur portable Dell avec un processeur I7) variait de bien moins d'une minute à 48 minutes pour 150 d'un côté (149 d'un côté a pris moins de 2 minutes). Les 51 solutions ont utilisé 11 rectangles. Les scores des 51 solutions variaient de 41 à 78. Les raisons pour lesquelles j'ai utilisé 11 rectangles étaient que le score était inférieur à celui de moins de rectangles et qu'il semblait que 12 rectangles prendraient beaucoup plus que l'heure allouée.
Les solutions et le code peuvent être trouvés sur https://github.com/JaySpencerAnderson/mondrian . Ce sont les deux fichiers my4 *.
BTW, si vous compilez ceci en "my4" et l'exécutez comme suit: "./my4 -h", cela vous donnera une utilisation. Si vous voulez le voir fonctionner en action, essayez quelque chose comme "./my4 -l 50 -n 8". Si vous changez celui "#if 0" en "#if 1" cela rendra l'espace restant sur l'écran. Si vous voulez changer cela pour rendre les rectangles, recherchez le seul endroit où le code exécute "graphique (espace, côté)" et remplacez-le par "graphique (pile d'appels, côté)" à la place. Je suggérerais également de changer le budget initial de 64 à 32 si vous voulez jouer avec des solutions pour des carrés d'environ 50 de large. La solution pour les petits carrés aura un meilleur score avec un budget plus petit.
Le programme ci-dessous est fonctionnel. Vérifiez github pour le code complet (avec utilisation, commentaires, etc.).
la source