Un défi avec des règles simples mais des algorithmes non triviaux. :-)
Tâche
Prendre une entrée sous forme d’entiers séparés par des espaces:
N A B S
Où N est la longueur de côté d'une matrice carrée 2D remplie de nombres uniques (entiers) compris entre A et B inclus. Pour chaque ligne et colonne de cette matrice, la somme est toujours la même: S. (En d'autres termes, la matrice est un carré semi-magique).
Remarque:
Tous les chiffres sont positifs. L'exception est A, qui peut être 0.
Exemples
Pour
3 1 10000 2015
une solution valable serait
Pour
8 1 300 500
une solution valable serait
Sortie
Votre sortie devrait être une table ASCII. Exemple pour le premier exemple ci-dessus:
384 159 1472
1174 499 342
457 1357 201
Entiers alignés à droite remplis d'espaces. La largeur de chaque colonne est la largeur du plus grand entier de cette colonne.
Notation
C'est du code-golf , donc le code le plus court en octets gagne. Les failles standard s’appliquent (en particulier sur les solutions intégrées pour résoudre ce problème). Vous n'avez pas à vous soucier d'entrées fausses ou autrement impossibles (y compris des nombres négatifs). Veuillez fournir un exemple de sortie dans votre réponse (obligatoire) pour le deuxième exemple ci-dessus.
A
,B
etN
peut être négatif?Réponses:
CJam,
11991 octetsIl s’agit d’une approche parfaitement déterminante et non déterministe.
Sur mon bureau, le deuxième cas de test se termine généralement en moins de 10 minutes.
Le premier cas se termine instantanément. Essayez-le en ligne dans l' interprète CJam .
Échantillon échantillon
Idée
Sans limite de temps, nous pourrions simplement générer des carrés au hasard jusqu'à trouver un carré valide. Cette approche s'appuie sur cette idée en ajoutant deux optimisations:
Au lieu de générer de manière pseudo-aléatoire un carré de côtés N , nous générons des carrés de côtés N-1 , ajoutons une colonne pour former un rectangle N × (N-1) dont les lignes ont la somme S , puis une ligne pour former un carré de longueur latérale N dont les colonnes ont somme S .
Etant donné que la somme des éléments des colonnes sera NS et la somme des éléments du premier N-1 lignes est (N-1) S , la dernière ligne aura également somme S .
Toutefois, ce processus peut générer une matrice non valide, car rien ne garantit que tous les éléments de la dernière ligne et de la dernière colonne seront uniques ou tomberont dans la plage [A ... B] .
Choisir un carré d'entiers uniques dans [A ... B] et la longueur du côté N-1 uniformément au hasard prendrait beaucoup trop de temps. Nous devons en quelque sorte donner la priorité aux carrés qui ont plus de chances d’aboutir à un carré valide de longueur de côté N après avoir appliqué le processus détaillé dans le point précédent.
Étant donné que chaque ligne et colonne doit avoir une somme de S , ses éléments ont une moyenne de S / N . Ainsi, choisir plus d'éléments proches de cette moyenne devrait augmenter nos chances.
Pour chaque I dans [A ... B] , nous sélectionnons de manière pseudo-aléatoire un flottant compris entre 0 et (I - S / N) 2 + 1 et nous trions les éléments de [A ... B] en fonction des flottants sélectionnés. Nous conservons les premiers N 2 chiffres et les plaçons en ordre de lecture dans un carré.
En supposant une distribution parfaitement uniforme de tous les nombres réels entre 0 et (I - S / N) 2 + 1 à chaque étape, tous les carrés ont une probabilité non nulle d'être sélectionnés, ce qui signifie que le processus s'achèvera éventuellement.
Code
la source