Partitionnez une liste!


10

Dans ce défi, vous devez partitionner une liste, où les partitions ont une taille maximale, une taille minimale et une taille préférée. Je vais utiliser la notation (min,pref,max) pour indiquer les tailles dans ce défi.

Pour ceux qui ne connaissent pas le partitionnement, la liste suivante a été partitionnée en parties de 3:
[0..9] -> [[0,1,2],[3,4,5],[6,7,8]]

Lorsque la liste ne sont pas divisibles, vous avez besoin des partitions d'être aussi proche de la taille préférée possible: [0..10], (2,4,5) -> [[0,1,2,3],[4,5,6],[7,8,9]]. Ce partitionnement est préférable à [[0,1,2,3],[4,5,6,7],[8,9]], même si ce dernier a plus de longueur préférée. Formellement, nous devons minimiser la somme de (partitionLength-preferredSize)^2pour chaque partition.

L'ordre des longueurs de partition n'a pas d'importance: pour [0..5], (2,3,3), soit [[0,1,2],[3,4]]ou [[0,1],[2,3,4]]fonctionne. Si aucune partition est possible, retourner un tableau vide: [0..7], (4,4,5) -> [].

Vous pouvez supposer cela 1<=min<=pref<=maxet que le tableau qui vous est transmis est un tableau d'entiers non vide. Le tableau sera toujours le premier argument. Vous pouvez accepter min, max et pref dans n'importe quel ordre et comme tuple ou comme arguments séparés.

Votre programme doit s'exécuter en quelques secondes. Fondamentalement, l'itération à travers toutes les tailles de partition possibles dans les limites n'est pas autorisée.

Cas de test:

[1], (1,3,4)         -> [[1]]
[100], (1,2,3)       -> [[100]]
[1,2], (1,1,2)       -> [[1],[2]]
[1,2], (1,2,2)       -> [[1,2]]
[1,2], (1,3,3)       -> [[1,2]]
[1,2,3], (1,2,3)     -> [[1,2],[3]] or [[1,2,3]]
[1,2,3,4], (1,3,4)   -> [[1,2,3,4]]
[1,2,3,4,5], (3,3,4) -> []
[1,2,3,4,5], (2,2,2) -> []
[1,2,3,4,5], (3,3,5) -> [[1,2,3,4,5]]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49], (2,6,6) -> [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24],[25,26,27,28,29],[30,31,32,33,34],[35,36,37,38,39],[40,41,42,43,44],[45,46,47,48,49]]

Il s'agit d'un , alors visez le moins d'octets possible dans votre langue préférée!


La notation que vous utilisez [a..b]inclut aet exclut b, n'est-ce pas?
Alex A.

A inclusif, B exclusif.
Nathan Merrill

Notez que votre interprétation de a n'est pas la même chose qu'une partition de la théorie des ensembles ...
agtoever

Mais il est en fait équivalent au partitionnement entier.
Nathan Merrill

Et s'il n'y a pas de solution?
feersum

Réponses:


2

Haskell, 152

_%0=[]
s%k|(a,b)<-splitAt(div(z s)k)s=a:b%(k-1)
z=length
f s n p x=snd$minimum$(z s*p^2,[]):[(sum[(z x-p)^2|x<-s%k],s%k)|k<-[-div(-z s)x..div(z s)n]]

Dans n'importe quelle partition, s'il existe deux listes dont les longueurs diffèrent de deux ou plus, il sera toujours avantageux de réduire la plus grande liste et d'agrandir la petite liste. par conséquent, nous devons seulement considérer les partitions avec seulement deux tailles de liste, ce qui simplifie le calcul.

le programme s'exécute alors sur toutes les quantités possibles de listes dans la partition. étant donné le nombre de listes dans la partition, le score est déterminé de manière unique. le programme calcule une partition appropriée et son score.

puis il trouve le minimum global et le renvoie.

Utilisation: entrée comme f [1,2,3,4,5] 1 3 4( fest la fonction qui résout le défi)

Bien qu'il soit possible de calculer la meilleure option complètement numériquement et de ne partitionner la liste qu'en conséquence, cela a pris trop d'octets. cependant, ma dernière version de cette approche est:

_%0=[]
s%k|(a,b)<-splitAt(div(length s)k)s=a:b%(k-1)
f s n p x|l<-length s=(s%)$snd$minimum$(l*p^2,0):[(k*j^2+mod l k*(1-2*j),k)|k<-[1..div l n],k*x>=l,j<-[p-div l k]]

1

CJam, 70

q~:S;_,[0L]a{_S2=e<),S0=>f{[__S1=-_*\]@@-j.+}[esL]a+:e<}j1={/(\e_}/;]p

Essayez-le en ligne

Le code trouve une séquence optimale de tailles de partition en fonction de la taille de la liste, en utilisant une programmation dynamique (via la récursion mémorisée), puis continue et partitionne la liste.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.