Tout d'abord, quelques définitions:
- Étant donné
n
etk
, considérons la liste triée de multisets , où pour chaque multiset nous choisissons desk
nombres{0, 1, ..., n-1}
avec des répétitions.
Par exemple, pour n=5
et k=3
, nous avons:
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 1), ( 0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 2), (0, 2, 3), (0, 2, 4), (0, 3, 3), (0, 3, 4), (0, 4, 4), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 3), (1, 3, 4), (1, 4, 4) , (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 3), (2, 3, 4), (2, 4, 4), ( 3, 3, 3), (3, 3, 4), (3, 4, 4), (4, 4, 4)]
- Une pièce est une liste de multisets avec la propriété que la taille de l'intersection de tous les multisets de la pièce est au moins
k-1
. C'est-à-dire que nous prenons tous les multisets et les croisons (en utilisant l'intersection multiset) en une seule fois. Par exemple,[(1, 2, 2), (1, 2, 3), (1, 2, 4)]
est une pièce car son intersection est de taille 2, mais[(1, 1, 3),(1, 2, 3),(1, 2, 4)]
ne l'est pas, car son intersection est de taille 1.
Tâche
Votre code doit prendre deux arguments n
et k
. Il doit ensuite parcourir goulûment ces multisets dans un ordre trié et sortir les parties de la liste. Pour le cas n=5, k=3
, le partitionnement correct est:
(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4)
(0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 1, 4)
(0, 2, 2), (0, 2, 3), (0, 2, 4)
(0, 3, 3), (0, 3, 4)
(0, 4, 4)
(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4)
(1, 2, 2), (1, 2, 3), (1, 2, 4)
(1, 3, 3), (1, 3, 4)
(1, 4, 4)
(2, 2, 2), (2, 2, 3), (2, 2, 4)
(2, 3, 3), (2, 3, 4)
(2, 4, 4)
(3, 3, 3), (3, 3, 4)
(3, 4, 4), (4, 4, 4)
Voici un autre exemple pour n = 4, k = 4
.
(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3)
(0, 0, 1, 1), (0, 0, 1, 2), (0, 0, 1, 3)
(0, 0, 2, 2), (0, 0, 2, 3)
(0, 0, 3, 3)
(0, 1, 1, 1), (0, 1, 1, 2), (0, 1, 1, 3)
(0, 1, 2, 2), (0, 1, 2, 3)
(0, 1, 3, 3)
(0, 2, 2, 2), (0, 2, 2, 3)
(0, 2, 3, 3), (0, 3, 3, 3)
(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3)
(1, 1, 2, 2), (1, 1, 2, 3)
(1, 1, 3, 3)
(1, 2, 2, 2), (1, 2, 2, 3)
(1, 2, 3, 3), (1, 3, 3, 3)
(2, 2, 2, 2), (2, 2, 2, 3)
(2, 2, 3, 3), (2, 3, 3, 3)
(3, 3, 3, 3)
Clarification de ce que signifie gourmand: Pour chaque multiset tour à tour nous cherchons à voir s'il peut être ajouté à la partie existante. Si c'est le cas, nous l'ajouterons. Si ce n'est pas possible, nous commençons une nouvelle partie. Nous regardons les multisets dans l'ordre trié comme dans l'exemple donné ci-dessus.
Production
Vous pouvez sortir le partitionnement dans n'importe quel format sensible que vous aimez. Cependant, les multisets doivent être écrits horizontalement sur une seule ligne. C'est-à-dire qu'un multiset individuel ne doit pas être écrit verticalement ou réparti sur plusieurs lignes. Vous pouvez choisir la façon dont vous séparez la représentation des pièces dans la sortie.
Hypothèses
Nous pouvons supposer cela n >= k > 0
.
la source
(0, 4, 4)
seul? Compte tenu de votre description, je pense que sa "partie" serait(0, 4, 4), (1, 4, 4), (2, 4, 4), (3, 4, 4), (4, 4, 4)
. De même pour(0, 0, 3, 3)
le deuxième cas de test.Réponses:
Gelée ,
2625 octetsProgramme complet qui imprime une représentation d'une liste de listes, chaque liste faisant partie, par exemple pour n = 5, k = 3:
Remarque: la représentation utilisée supprime les listes redondantes
[
et]
autour de longueur 1.Essayez-le en ligne! ou voir une jolie version imprimée (coût 3 octets)
Comment?
la source
MATLAB, 272 octets
Production:
Deux lignes vides entre différentes parties.
Non golfé:
Explication:
On trouve d'abord tous les multisets avec force brute:
repmat(0:n-1, 1, k)
répète le vecteur de valeurs de0
àn-1
k
fois.nchoosek(x, k)
renvoie une matrice contenant toutes les k-combinaisons du vecteur répété.sort(x, 2)
trie toutes les k-combinaisons, puisunique(x, 'rows')
supprime tous les doublons.p=zeros(0,k);
crée une matrice vide avec desk
colonnes. Nous allons l'utiliser comme une pile. A chaque itération de la outernmostfor
boucle, nous avons d' abord ajouter le multiset courant à ladite pile:p=[p;l(i,:)];
.Ensuite, nous vérifions si l'intersection de tous les multisets de la pile est au moins
k-1
longue avec le code suivant (nous ne pouvons pas utiliser laintersect
commande de MATLAB pour vérifier les intersections, car elle renvoie un ensemble, mais nous avons besoin d'un multiset):Maintenant, si l'intersection est suffisamment longue
a == 0
, sinona == 1
.Si l'intersection n'est pas assez longue, nous imprimons une nouvelle ligne et vider la pile:
Ensuite, nous imprimons simplement le multiset actuel:
la source
MATL , 34 octets
Les pièces sont séparées par une ligne contenant des espaces.
Essayez-le en ligne!
Explication
Avertissement: cette méthode semble fonctionner (et elle le fait dans les cas de test), mais je n'ai pas de preuve qu'elle fonctionne toujours
Les multisets sont triés, à la fois en interne (c'est-à-dire que chaque multiset a des entrées non décroissantes) et en externe (c'est à dire que le multiset M précède le multiset N si M précède N lexicographiquement).
Pour calculer l'intersection multisets, les multisets triés sont disposés sous forme de lignes d'une matrice et des différences consécutives sont calculées le long de chaque colonne. Si toutes les colonnes sauf au plus une ont toutes les différences égales à zéro, les multisets appartiennent à la même partie.
Ce test donne un faux résultat négatif pour multijeux comme
(1,2,3)
et(2,3,4)
: même si2
,3
sont entrées communes, ils ne seraient pas détectés comme tels parce qu'ils sont dans des colonnes qui ne correspondent pas .Cependant, cela ne semble pas être un problème, du moins dans les cas de test. Il semble qu'un test entre multisets comme
1,2,3
et2,3,4
jamais ne doive être fait, car certains multisets intermédiaires ont donné un résultat négatif et ils sont donc déjà dans des parties différentes. Si c'est effectivement le cas, la raison tient sans doute au fait que les multisets sont triés.Mais je n'en ai pas la preuve. Cela semble fonctionner.
la source
n=k=4
cas où nous avons un nouveau début de pièce(0, 0, 3, 3)
, la différence consécutive vectorisée de cela et le multi-ensemble précédent,(0, 0, 2, 3)
n'a qu'une seule différence, alors comment la "pièce jusqu'à présent" fait-elle fonctionner cela? (ou de manière équivalente quel était le résultat de l'étape précédente qui a été utilisé à la place(0, 0, 2, 3)
?)PHP, 245 octets
Essayez-le en ligne!
Étendu
Sortie sous forme de chaîne
n> 15 pour plus de précision
la source
0
pour(16**16-1)%16
et le long travail de la version uniquement avec la précision qui est nécessaire pourn>15
bcmod(bcsub(bcpow(16,16),1),16)
se15
php.net/manual/en/ref.bc.php